1
The following changes since commit b52daaf2c868f2bab102eb5acbf55b2917f46aea:
1
The following changes since commit aa3a285b5bc56a4208b3b57d4a55291e9c260107:
2
2
3
Merge tag 'pull-block-2023-06-05' of https://gitlab.com/hreitz/qemu into staging (2023-06-05 10:27:31 -0700)
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-20230605
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20241224
8
8
9
for you to fetch changes up to a7f6911c127b1dd1b8764e03b0ebcf0a227a15e4:
9
for you to fetch changes up to e4a8e093dc74be049f4829831dce76e5edab0003:
10
10
11
tcg/tcg-op-vec: Remove left over _link_error() definitions (2023-06-05 12:20:16 -0700)
11
accel/tcg: Move gen_intermediate_code to TCGCPUOps.translate_core (2024-12-24 08:32:15 -0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Build tcg/ once for system and once for user.
14
tcg/optimize: Remove in-flight mask data from OptContext
15
Unmap perf_marker.
15
fpu: Add float*_muladd_scalbn
16
Remove left over _link_error() definitions.
16
fpu: Remove float_muladd_halve_result
17
fpu: Add float_round_nearest_even_max
18
fpu: Add float_muladd_suppress_add_product_zero
19
target/hexagon: Use float32_muladd
20
accel/tcg: Move gen_intermediate_code to TCGCPUOps.translate_core
17
21
18
----------------------------------------------------------------
22
----------------------------------------------------------------
19
Ilya Leoshkevich (1):
23
Ilya Leoshkevich (1):
20
accel/tcg: Unmap perf_marker
24
tests/tcg: Do not use inttypes.h in multiarch/system/memory.c
21
25
22
Philippe Mathieu-Daudé (2):
26
Pierrick Bouvier (1):
23
target/ppc: Inline gen_icount_io_start()
27
plugins: optimize cpu_index code generation
24
tcg/tcg-op-vec: Remove left over _link_error() definitions
25
28
26
Richard Henderson (49):
29
Richard Henderson (70):
27
tcg/ppc: Remove TARGET_LONG_BITS, TCG_TYPE_TL
30
tcg/optimize: Split out finish_bb, finish_ebb
28
tcg/riscv: Remove TARGET_LONG_BITS, TCG_TYPE_TL
31
tcg/optimize: Split out fold_affected_mask
29
tcg/s390x: Remove TARGET_LONG_BITS, TCG_TYPE_TL
32
tcg/optimize: Copy mask writeback to fold_masks
30
tcg/sparc64: Remove TARGET_LONG_BITS, TCG_TYPE_TL
33
tcg/optimize: Split out fold_masks_zs
31
tcg: Move TCG_TYPE_TL from tcg.h to tcg-op.h
34
tcg/optimize: Augment s_mask from z_mask in fold_masks_zs
32
tcg: Widen CPUTLBEntry comparators to 64-bits
35
tcg/optimize: Change representation of s_mask
33
tcg: Add tlb_fast_offset to TCGContext
36
tcg/optimize: Use finish_folding in fold_add, fold_add_vec, fold_addsub2
34
target/avr: Add missing includes of qemu/error-report.h
37
tcg/optimize: Introduce const value accessors for TempOptInfo
35
target/*: Add missing includes of tcg/debug-assert.h
38
tcg/optimize: Use fold_masks_zs in fold_and
36
*: Add missing includes of tcg/tcg.h
39
tcg/optimize: Use fold_masks_zs in fold_andc
37
tcg: Split out tcg-target-reg-bits.h
40
tcg/optimize: Use fold_masks_zs in fold_bswap
38
target/arm: Fix test of TCG_OVERSIZED_GUEST
41
tcg/optimize: Use fold_masks_zs in fold_count_zeros
39
tcg: Split out tcg/oversized-guest.h
42
tcg/optimize: Use fold_masks_z in fold_ctpop
40
tcg: Move TCGv, dup_const_tl definitions to tcg-op.h
43
tcg/optimize: Use fold_and and fold_masks_z in fold_deposit
41
tcg: Split tcg/tcg-op-common.h from tcg/tcg-op.h
44
tcg/optimize: Compute sign mask in fold_deposit
42
target/arm: Include helper-gen.h in translator.h
45
tcg/optimize: Use finish_folding in fold_divide
43
target/hexagon: Include helper-gen.h where needed
46
tcg/optimize: Use finish_folding in fold_dup, fold_dup2
44
tcg: Remove outdated comments in helper-head.h
47
tcg/optimize: Use fold_masks_s in fold_eqv
45
tcg: Move TCGHelperInfo and dependencies to tcg/helper-info.h
48
tcg/optimize: Use fold_masks_z in fold_extract
46
tcg: Pass TCGHelperInfo to tcg_gen_callN
49
tcg/optimize: Use finish_folding in fold_extract2
47
tcg: Move temp_idx and tcgv_i32_temp debug out of line
50
tcg/optimize: Use fold_masks_zs in fold_exts
48
tcg: Split tcg_gen_callN
51
tcg/optimize: Use fold_masks_z in fold_extu
49
tcg: Split helper-gen.h
52
tcg/optimize: Use fold_masks_zs in fold_movcond
50
tcg: Split helper-proto.h
53
tcg/optimize: Use finish_folding in fold_mul*
51
target/sh4: Emit insn_start for each insn in gUSA region
54
tcg/optimize: Use fold_masks_s in fold_nand
52
tcg: Add insn_start_words to TCGContext
55
tcg/optimize: Use fold_masks_z in fold_neg_no_const
53
tcg: Add guest_mo to TCGContext
56
tcg/optimize: Use fold_masks_s in fold_nor
54
tcg: Move TLB_FLAGS_MASK check out of get_alignment_bits
57
tcg/optimize: Use fold_masks_s in fold_not
55
tcg: Split tcg/tcg-op-gvec.h
58
tcg/optimize: Use fold_masks_zs in fold_or
56
tcg: Remove NO_CPU_IO_DEFS
59
tcg/optimize: Use fold_masks_zs in fold_orc
57
exec-all: Widen tb_page_addr_t for user-only
60
tcg/optimize: Use fold_masks_zs in fold_qemu_ld
58
exec-all: Widen TranslationBlock pc and cs_base to 64-bits
61
tcg/optimize: Return true from fold_qemu_st, fold_tcg_st
59
tcg: Spit out exec/translation-block.h
62
tcg/optimize: Use finish_folding in fold_remainder
60
include/exec: Remove CODE_GEN_AVG_BLOCK_SIZE
63
tcg/optimize: Distinguish simplification in fold_setcond_zmask
61
accel/tcg: Move most of gen-icount.h into translator.c
64
tcg/optimize: Use fold_masks_z in fold_setcond
62
accel/tcg: Introduce translator_io_start
65
tcg/optimize: Use fold_masks_s in fold_negsetcond
63
accel/tcg: Move translator_fake_ldb out of line
66
tcg/optimize: Use fold_masks_z in fold_setcond2
64
target/arm: Tidy helpers for translation
67
tcg/optimize: Use finish_folding in fold_cmp_vec
65
target/mips: Tidy helpers for translation
68
tcg/optimize: Use finish_folding in fold_cmpsel_vec
66
target/*: Add missing includes of exec/translation-block.h
69
tcg/optimize: Use fold_masks_zs in fold_sextract
67
target/arm: Add missing include of exec/exec-all.h
70
tcg/optimize: Use fold_masks_zs, fold_masks_s in fold_shift
68
accel/tcg: Tidy includes for translator.[ch]
71
tcg/optimize: Simplify sign bit test in fold_shift
69
tcg: Fix PAGE/PROT confusion
72
tcg/optimize: Use finish_folding in fold_sub, fold_sub_vec
70
tcg: Move env defines out of NEED_CPU_H in helper-head.h
73
tcg/optimize: Use fold_masks_zs in fold_tcg_ld
71
tcg: Remove target-specific headers from tcg.[ch]
74
tcg/optimize: Use finish_folding in fold_tcg_ld_memcopy
72
plugins: Move plugin_insn_append to translator.c
75
tcg/optimize: Use fold_masks_zs in fold_xor
73
plugins: Drop unused headers from exec/plugin-gen.h
76
tcg/optimize: Use finish_folding in fold_bitsel_vec
74
exec/poison: Do not poison CONFIG_SOFTMMU
77
tcg/optimize: Use finish_folding as default in tcg_optimize
75
tcg: Build once for system and once for user-only
78
tcg/optimize: Remove z_mask, s_mask from OptContext
79
tcg/optimize: Re-enable sign-mask optimizations
80
tcg/optimize: Move fold_bitsel_vec into alphabetic sort
81
tcg/optimize: Move fold_cmp_vec, fold_cmpsel_vec into alphabetic sort
82
softfloat: Add float{16,32,64}_muladd_scalbn
83
target/arm: Use float*_muladd_scalbn
84
target/sparc: Use float*_muladd_scalbn
85
softfloat: Remove float_muladd_halve_result
86
softfloat: Add float_round_nearest_even_max
87
softfloat: Add float_muladd_suppress_add_product_zero
88
target/hexagon: Use float32_mul in helper_sfmpy
89
target/hexagon: Use float32_muladd for helper_sffma
90
target/hexagon: Use float32_muladd for helper_sffms
91
target/hexagon: Use float32_muladd_scalbn for helper_sffma_sc
92
target/hexagon: Use float32_muladd for helper_sffm[as]_lib
93
target/hexagon: Remove internal_fmafx
94
target/hexagon: Expand GEN_XF_ROUND
95
target/hexagon: Remove Float
96
target/hexagon: Remove Double
97
target/hexagon: Use mulu64 for int128_mul_6464
98
target/hexagon: Simplify internal_mpyhh setup
99
accel/tcg: Move gen_intermediate_code to TCGCPUOps.translate_core
76
100
77
MAINTAINERS | 3 +-
101
include/exec/translator.h | 14 -
78
include/exec/cpu-all.h | 3 +
102
include/fpu/softfloat-types.h | 2 +
79
include/exec/cpu-defs.h | 50 +-
103
include/fpu/softfloat.h | 14 +-
80
include/exec/cpu_ldst.h | 22 +-
104
include/hw/core/tcg-cpu-ops.h | 13 +
81
include/exec/exec-all.h | 142 +--
105
target/alpha/cpu.h | 2 +
82
include/exec/gen-icount.h | 83 --
106
target/arm/internals.h | 2 +
83
include/exec/helper-gen-common.h | 18 +
107
target/avr/cpu.h | 2 +
84
include/exec/helper-gen.h | 97 +-
108
target/hexagon/cpu.h | 2 +
85
include/exec/helper-head.h | 24 +-
109
target/hexagon/fma_emu.h | 3 -
86
include/exec/helper-proto-common.h | 18 +
110
target/hppa/cpu.h | 2 +
87
include/exec/helper-proto.h | 73 +-
111
target/i386/tcg/helper-tcg.h | 2 +
88
include/exec/helper-tcg.h | 75 --
112
target/loongarch/internals.h | 2 +
89
include/exec/plugin-gen.h | 24 -
113
target/m68k/cpu.h | 2 +
90
include/exec/poison.h | 1 -
114
target/microblaze/cpu.h | 2 +
91
include/exec/tlb-common.h | 56 ++
115
target/mips/tcg/tcg-internal.h | 2 +
92
include/exec/translation-block.h | 149 +++
116
target/openrisc/cpu.h | 2 +
93
include/exec/translator.h | 24 +-
117
target/ppc/cpu.h | 2 +
94
include/qemu/typedefs.h | 1 +
118
target/riscv/cpu.h | 3 +
95
include/tcg/helper-info.h | 64 ++
119
target/rx/cpu.h | 2 +
96
include/tcg/insn-start-words.h | 17 +
120
target/s390x/s390x-internal.h | 2 +
97
include/tcg/oversized-guest.h | 23 +
121
target/sh4/cpu.h | 2 +
98
include/tcg/tcg-op-common.h | 996 +++++++++++++++++++
122
target/sparc/cpu.h | 2 +
99
include/tcg/tcg-op-gvec-common.h | 426 ++++++++
123
target/sparc/helper.h | 4 +-
100
include/tcg/tcg-op-gvec.h | 444 +--------
124
target/tricore/cpu.h | 2 +
101
include/tcg/tcg-op.h | 1033 +-------------------
125
target/xtensa/cpu.h | 2 +
102
include/tcg/tcg-opc.h | 6 +-
126
accel/tcg/cpu-exec.c | 8 +-
103
include/tcg/tcg.h | 107 +-
127
accel/tcg/plugin-gen.c | 9 +
104
target/arm/cpregs.h | 4 +-
128
accel/tcg/translate-all.c | 8 +-
105
target/arm/tcg/translate.h | 5 +
129
fpu/softfloat.c | 63 +--
106
target/mips/tcg/translate.h | 5 +-
130
target/alpha/cpu.c | 1 +
107
target/ppc/cpu.h | 2 -
131
target/alpha/translate.c | 4 +-
108
target/sparc/cpu.h | 2 -
132
target/arm/cpu.c | 1 +
109
tcg/aarch64/tcg-target-reg-bits.h | 12 +
133
target/arm/tcg/cpu-v7m.c | 1 +
110
tcg/arm/tcg-target-reg-bits.h | 12 +
134
target/arm/tcg/helper-a64.c | 6 +-
111
tcg/i386/tcg-target-reg-bits.h | 16 +
135
target/arm/tcg/translate.c | 5 +-
112
tcg/i386/tcg-target.h | 2 -
136
target/avr/cpu.c | 1 +
113
tcg/loongarch64/tcg-target-reg-bits.h | 21 +
137
target/avr/translate.c | 6 +-
114
tcg/loongarch64/tcg-target.h | 11 -
138
target/hexagon/cpu.c | 1 +
115
tcg/mips/tcg-target-reg-bits.h | 18 +
139
target/hexagon/fma_emu.c | 496 ++++++---------------
116
tcg/mips/tcg-target.h | 8 -
140
target/hexagon/op_helper.c | 125 ++----
117
tcg/ppc/tcg-target-reg-bits.h | 16 +
141
target/hexagon/translate.c | 4 +-
118
tcg/ppc/tcg-target.h | 5 -
142
target/hppa/cpu.c | 1 +
119
tcg/riscv/tcg-target-reg-bits.h | 19 +
143
target/hppa/translate.c | 4 +-
120
tcg/riscv/tcg-target.h | 9 -
144
target/i386/tcg/tcg-cpu.c | 1 +
121
tcg/s390x/tcg-target-reg-bits.h | 17 +
145
target/i386/tcg/translate.c | 5 +-
122
tcg/sparc64/tcg-target-reg-bits.h | 12 +
146
target/loongarch/cpu.c | 1 +
123
tcg/tcg-internal.h | 47 +-
147
target/loongarch/tcg/translate.c | 4 +-
124
tcg/tci/tcg-target-reg-bits.h | 18 +
148
target/m68k/cpu.c | 1 +
125
tcg/tci/tcg-target.h | 8 -
149
target/m68k/translate.c | 4 +-
126
include/exec/helper-gen.h.inc | 102 ++
150
target/microblaze/cpu.c | 1 +
127
include/exec/helper-proto.h.inc | 68 ++
151
target/microblaze/translate.c | 4 +-
128
accel/tcg/cpu-exec.c | 2 +-
152
target/mips/cpu.c | 1 +
129
accel/tcg/cputlb.c | 12 +-
153
target/mips/tcg/translate.c | 4 +-
130
accel/tcg/monitor.c | 1 +
154
target/openrisc/cpu.c | 1 +
131
accel/tcg/perf.c | 19 +-
155
target/openrisc/translate.c | 4 +-
132
accel/tcg/plugin-gen.c | 6 +
156
target/ppc/cpu_init.c | 1 +
133
accel/tcg/tcg-accel-ops-mttcg.c | 2 +-
157
target/ppc/translate.c | 4 +-
134
accel/tcg/tcg-accel-ops-rr.c | 2 +-
158
target/riscv/tcg/tcg-cpu.c | 1 +
135
accel/tcg/tcg-all.c | 1 +
159
target/riscv/translate.c | 4 +-
136
accel/tcg/tcg-runtime-gvec.c | 2 +-
160
target/rx/cpu.c | 1 +
137
accel/tcg/tcg-runtime.c | 6 +-
161
target/rx/translate.c | 4 +-
138
accel/tcg/translate-all.c | 30 +-
162
target/s390x/cpu.c | 1 +
139
accel/tcg/translator.c | 140 ++-
163
target/s390x/tcg/translate.c | 4 +-
140
target/alpha/translate.c | 18 +-
164
target/sh4/cpu.c | 1 +
141
target/arm/ptw.c | 8 +-
165
target/sh4/translate.c | 4 +-
142
target/arm/tcg/translate-a64.c | 42 +-
166
target/sparc/cpu.c | 1 +
143
target/arm/tcg/translate-m-nocp.c | 2 -
167
target/sparc/fop_helper.c | 8 +-
144
target/arm/tcg/translate-mve.c | 4 -
168
target/sparc/translate.c | 84 ++--
145
target/arm/tcg/translate-neon.c | 4 -
169
target/tricore/cpu.c | 1 +
146
target/arm/tcg/translate-sme.c | 7 -
170
target/tricore/translate.c | 5 +-
147
target/arm/tcg/translate-sve.c | 11 -
171
target/xtensa/cpu.c | 1 +
148
target/arm/tcg/translate-vfp.c | 7 +-
172
target/xtensa/translate.c | 4 +-
149
target/arm/tcg/translate.c | 41 +-
173
tcg/optimize.c | 857 +++++++++++++++++++-----------------
150
target/avr/cpu.c | 1 +
174
tests/tcg/multiarch/system/memory.c | 9 +-
151
target/avr/helper.c | 1 +
175
fpu/softfloat-parts.c.inc | 16 +-
152
target/avr/translate.c | 6 +-
176
75 files changed, 866 insertions(+), 1009 deletions(-)
153
target/cris/translate.c | 8 +-
154
target/hexagon/genptr.c | 1 +
155
target/hexagon/translate.c | 7 +
156
target/hppa/translate.c | 10 +-
157
target/i386/helper.c | 3 +
158
target/i386/tcg/translate.c | 57 +-
159
target/loongarch/translate.c | 7 +-
160
target/m68k/translate.c | 5 +-
161
target/microblaze/translate.c | 6 +-
162
target/mips/tcg/msa_translate.c | 3 -
163
target/mips/tcg/mxu_translate.c | 2 -
164
target/mips/tcg/octeon_translate.c | 4 +-
165
target/mips/tcg/rel6_translate.c | 2 -
166
target/mips/tcg/translate.c | 53 +-
167
target/mips/tcg/translate_addr_const.c | 1 -
168
target/mips/tcg/tx79_translate.c | 4 +-
169
target/mips/tcg/vr54xx_translate.c | 3 -
170
target/nios2/translate.c | 6 +-
171
target/openrisc/sys_helper.c | 1 +
172
target/openrisc/translate.c | 14 +-
173
target/ppc/translate.c | 78 +-
174
target/riscv/cpu_helper.c | 1 +
175
target/riscv/translate.c | 6 +-
176
target/rx/cpu.c | 1 +
177
target/rx/op_helper.c | 1 +
178
target/rx/translate.c | 7 +-
179
target/s390x/tcg/translate.c | 10 +-
180
target/sh4/translate.c | 21 +-
181
target/sparc/translate.c | 78 +-
182
target/tricore/cpu.c | 1 +
183
target/tricore/translate.c | 7 +-
184
target/xtensa/translate.c | 31 +-
185
tcg/optimize.c | 2 +-
186
tcg/region.c | 20 +-
187
tcg/tcg-op-gvec.c | 4 +-
188
tcg/tcg-op-ldst.c | 26 +-
189
tcg/tcg-op-vec.c | 13 +-
190
tcg/tcg-op.c | 4 +-
191
tcg/tcg.c | 218 +++--
192
tcg/tci.c | 3 +-
193
include/exec/helper-info.c.inc | 96 ++
194
target/loongarch/insn_trans/trans_extra.c.inc | 4 +-
195
target/loongarch/insn_trans/trans_privileged.c.inc | 4 +-
196
target/ppc/power8-pmu-regs.c.inc | 10 +-
197
target/ppc/translate/branch-impl.c.inc | 2 +-
198
target/riscv/insn_trans/trans_privileged.c.inc | 8 +-
199
target/riscv/insn_trans/trans_rvi.c.inc | 24 +-
200
tcg/aarch64/tcg-target.c.inc | 8 +-
201
tcg/arm/tcg-target.c.inc | 8 +-
202
tcg/i386/tcg-target.c.inc | 9 +-
203
tcg/loongarch64/tcg-target.c.inc | 8 +-
204
tcg/mips/tcg-target.c.inc | 20 +-
205
tcg/ppc/tcg-target.c.inc | 46 +-
206
tcg/riscv/tcg-target.c.inc | 21 +-
207
tcg/s390x/tcg-target.c.inc | 22 +-
208
tcg/sparc64/tcg-target.c.inc | 20 +-
209
scripts/make-config-poison.sh | 5 +-
210
target/hexagon/idef-parser/idef-parser.y | 3 +-
211
tcg/meson.build | 30 +-
212
135 files changed, 3088 insertions(+), 2782 deletions(-)
213
delete mode 100644 include/exec/gen-icount.h
214
create mode 100644 include/exec/helper-gen-common.h
215
create mode 100644 include/exec/helper-proto-common.h
216
delete mode 100644 include/exec/helper-tcg.h
217
create mode 100644 include/exec/tlb-common.h
218
create mode 100644 include/exec/translation-block.h
219
create mode 100644 include/tcg/helper-info.h
220
create mode 100644 include/tcg/insn-start-words.h
221
create mode 100644 include/tcg/oversized-guest.h
222
create mode 100644 include/tcg/tcg-op-common.h
223
create mode 100644 include/tcg/tcg-op-gvec-common.h
224
create mode 100644 tcg/aarch64/tcg-target-reg-bits.h
225
create mode 100644 tcg/arm/tcg-target-reg-bits.h
226
create mode 100644 tcg/i386/tcg-target-reg-bits.h
227
create mode 100644 tcg/loongarch64/tcg-target-reg-bits.h
228
create mode 100644 tcg/mips/tcg-target-reg-bits.h
229
create mode 100644 tcg/ppc/tcg-target-reg-bits.h
230
create mode 100644 tcg/riscv/tcg-target-reg-bits.h
231
create mode 100644 tcg/s390x/tcg-target-reg-bits.h
232
create mode 100644 tcg/sparc64/tcg-target-reg-bits.h
233
create mode 100644 tcg/tci/tcg-target-reg-bits.h
234
create mode 100644 include/exec/helper-gen.h.inc
235
create mode 100644 include/exec/helper-proto.h.inc
236
create mode 100644 include/exec/helper-info.c.inc
237
diff view generated by jsdifflib
New patch
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
2
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>
23
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
24
---
25
tests/tcg/multiarch/system/memory.c | 9 ++++-----
26
1 file changed, 4 insertions(+), 5 deletions(-)
27
28
diff --git a/tests/tcg/multiarch/system/memory.c b/tests/tcg/multiarch/system/memory.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/tests/tcg/multiarch/system/memory.c
31
+++ b/tests/tcg/multiarch/system/memory.c
32
@@ -XXX,XX +XXX,XX @@
33
34
#include <stdint.h>
35
#include <stdbool.h>
36
-#include <inttypes.h>
37
#include <minilib.h>
38
39
#ifndef CHECK_UNALIGNED
40
@@ -XXX,XX +XXX,XX @@ int main(void)
41
int i;
42
bool ok = true;
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);
53
}
54
55
- ml_printf("Test data read: %"PRId32"\n", test_read_count);
56
- ml_printf("Test data write: %"PRId32"\n", test_write_count);
57
+ ml_printf("Test data read: %lu\n", (unsigned long)test_read_count);
58
+ ml_printf("Test data write: %lu\n", (unsigned long)test_write_count);
59
ml_printf("Test complete: %s\n", ok ? "PASSED" : "FAILED");
60
return ok ? 0 : -1;
61
}
62
--
63
2.43.0
diff view generated by jsdifflib
1
This finally paves the way for tcg/ to be built once per mode.
1
From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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>
4
Signed-off-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>
5
---
13
---
6
include/tcg/tcg.h | 1 -
14
accel/tcg/plugin-gen.c | 9 +++++++++
7
accel/tcg/plugin-gen.c | 1 +
15
1 file changed, 9 insertions(+)
8
tcg/region.c | 2 +-
9
tcg/tcg-op.c | 2 +-
10
tcg/tcg.c | 2 +-
11
5 files changed, 4 insertions(+), 4 deletions(-)
12
16
13
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/tcg/tcg.h
16
+++ b/include/tcg/tcg.h
17
@@ -XXX,XX +XXX,XX @@
18
#ifndef TCG_H
19
#define TCG_H
20
21
-#include "cpu.h"
22
#include "exec/memop.h"
23
#include "exec/memopidx.h"
24
#include "qemu/bitops.h"
25
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
17
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
26
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
27
--- a/accel/tcg/plugin-gen.c
19
--- a/accel/tcg/plugin-gen.c
28
+++ b/accel/tcg/plugin-gen.c
20
+++ b/accel/tcg/plugin-gen.c
29
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void gen_disable_mem_helper(void)
30
* CPU's index into a TCG temp, since the first callback did it already.
22
31
*/
23
static TCGv_i32 gen_cpu_index(void)
32
#include "qemu/osdep.h"
24
{
33
+#include "cpu.h"
25
+ /*
34
#include "tcg/tcg.h"
26
+ * Optimize when we run with a single vcpu. All values using cpu_index,
35
#include "tcg/tcg-temp-internal.h"
27
+ * including scoreboard index, will be optimized out.
36
#include "tcg/tcg-op.h"
28
+ * User-mode calls tb_flush when setting this flag. In system-mode, all
37
diff --git a/tcg/region.c b/tcg/region.c
29
+ * vcpus are created before generating code.
38
index XXXXXXX..XXXXXXX 100644
30
+ */
39
--- a/tcg/region.c
31
+ if (!tcg_cflags_has(current_cpu, CF_PARALLEL)) {
40
+++ b/tcg/region.c
32
+ return tcg_constant_i32(current_cpu->cpu_index);
41
@@ -XXX,XX +XXX,XX @@
33
+ }
42
#include "qemu/cacheinfo.h"
34
TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
43
#include "qemu/qtree.h"
35
tcg_gen_ld_i32(cpu_index, tcg_env,
44
#include "qapi/error.h"
36
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
45
-#include "exec/exec-all.h"
46
#include "tcg/tcg.h"
47
+#include "exec/translation-block.h"
48
#include "tcg-internal.h"
49
50
51
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tcg/tcg-op.c
54
+++ b/tcg/tcg-op.c
55
@@ -XXX,XX +XXX,XX @@
56
*/
57
58
#include "qemu/osdep.h"
59
-#include "exec/exec-all.h"
60
#include "tcg/tcg.h"
61
#include "tcg/tcg-temp-internal.h"
62
#include "tcg/tcg-op-common.h"
63
+#include "exec/translation-block.h"
64
#include "exec/plugin-gen.h"
65
#include "tcg-internal.h"
66
67
diff --git a/tcg/tcg.c b/tcg/tcg.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/tcg/tcg.c
70
+++ b/tcg/tcg.c
71
@@ -XXX,XX +XXX,XX @@
72
#include "qemu/cacheflush.h"
73
#include "qemu/cacheinfo.h"
74
#include "qemu/timer.h"
75
-#include "exec/exec-all.h"
76
+#include "exec/translation-block.h"
77
#include "exec/tlb-common.h"
78
#include "tcg/tcg-op-common.h"
79
80
--
37
--
81
2.34.1
38
2.43.0
82
83
diff view generated by jsdifflib
New patch
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.
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 | 47 +++++++++++++++++++++++++++++++----------------
9
1 file changed, 31 insertions(+), 16 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 void copy_propagate(OptContext *ctx, TCGOp *op,
16
}
17
}
18
19
+static void finish_bb(OptContext *ctx)
20
+{
21
+ /* We only optimize memory barriers across basic blocks. */
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)
34
{
35
const TCGOpDef *def = &tcg_op_defs[op->opc];
36
int i, nb_oargs;
37
38
- /*
39
- * We only optimize extended basic blocks. If the opcode ends a BB
40
- * and is not a conditional branch, reset all temp data.
41
- */
42
- if (def->flags & TCG_OPF_BB_END) {
43
- ctx->prev_mb = NULL;
44
- if (!(def->flags & TCG_OPF_COND_BRANCH)) {
45
- memset(&ctx->temps_used, 0, sizeof(ctx->temps_used));
46
- remove_mem_copy_all(ctx);
47
- }
48
- return;
49
- }
50
-
51
nb_oargs = def->nb_oargs;
52
for (i = 0; i < nb_oargs; i++) {
53
TCGTemp *ts = arg_temp(op->args[i]);
54
@@ -XXX,XX +XXX,XX @@ static bool fold_brcond(OptContext *ctx, TCGOp *op)
55
if (i > 0) {
56
op->opc = INDEX_op_br;
57
op->args[0] = op->args[3];
58
+ finish_ebb(ctx);
59
+ } else {
60
+ finish_bb(ctx);
61
}
62
- return false;
63
+ return true;
64
}
65
66
static bool fold_brcond2(OptContext *ctx, TCGOp *op)
67
@@ -XXX,XX +XXX,XX @@ static bool fold_brcond2(OptContext *ctx, TCGOp *op)
68
}
69
op->opc = INDEX_op_br;
70
op->args[0] = label;
71
- break;
72
+ finish_ebb(ctx);
73
+ return true;
74
}
75
- return false;
76
+
77
+ finish_bb(ctx);
78
+ return true;
79
}
80
81
static bool fold_bswap(OptContext *ctx, TCGOp *op)
82
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
83
CASE_OP_32_64_VEC(xor):
84
done = fold_xor(&ctx, op);
85
break;
86
+ case INDEX_op_set_label:
87
+ case INDEX_op_br:
88
+ case INDEX_op_exit_tb:
89
+ case INDEX_op_goto_tb:
90
+ case INDEX_op_goto_ptr:
91
+ finish_ebb(&ctx);
92
+ done = true;
93
+ break;
94
default:
95
break;
96
}
97
--
98
2.43.0
diff view generated by jsdifflib
1
Create helper-proto-common.h without the target specific portion.
1
There are only a few logical operations which can compute
2
Use that in tcg-op-common.h. Include helper-proto.h in target/arm
2
an "affected" mask. Split out handling of this optimization
3
and target/hexagon before helper-info.c.inc; all other targets are
3
to a separate function, only to be called when applicable.
4
already correct in this regard.
5
4
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
10
---
9
include/exec/helper-proto-common.h | 18 ++++++++
11
tcg/optimize.c | 42 +++++++++++++++++++++++++++---------------
10
include/exec/helper-proto.h | 73 ++++--------------------------
12
1 file changed, 27 insertions(+), 15 deletions(-)
11
include/tcg/tcg-op-common.h | 2 +-
12
include/exec/helper-proto.h.inc | 68 ++++++++++++++++++++++++++++
13
accel/tcg/cputlb.c | 3 +-
14
accel/tcg/plugin-gen.c | 2 +-
15
accel/tcg/tcg-runtime-gvec.c | 2 +-
16
accel/tcg/tcg-runtime.c | 2 +-
17
target/arm/tcg/translate.c | 1 +
18
target/hexagon/translate.c | 1 +
19
10 files changed, 102 insertions(+), 70 deletions(-)
20
create mode 100644 include/exec/helper-proto-common.h
21
create mode 100644 include/exec/helper-proto.h.inc
22
13
23
diff --git a/include/exec/helper-proto-common.h b/include/exec/helper-proto-common.h
14
diff --git a/tcg/optimize.c b/tcg/optimize.c
24
new file mode 100644
25
index XXXXXXX..XXXXXXX
26
--- /dev/null
27
+++ b/include/exec/helper-proto-common.h
28
@@ -XXX,XX +XXX,XX @@
29
+/* SPDX-License-Identifier: GPL-2.0-or-later */
30
+/*
31
+ * Helper file for declaring TCG helper functions.
32
+ * This one expands prototypes for the helper functions.
33
+ */
34
+
35
+#ifndef HELPER_PROTO_COMMON_H
36
+#define HELPER_PROTO_COMMON_H
37
+
38
+#define HELPER_H "accel/tcg/tcg-runtime.h"
39
+#include "exec/helper-proto.h.inc"
40
+#undef HELPER_H
41
+
42
+#define HELPER_H "accel/tcg/plugin-helpers.h"
43
+#include "exec/helper-proto.h.inc"
44
+#undef HELPER_H
45
+
46
+#endif /* HELPER_PROTO_COMMON_H */
47
diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h
48
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
49
--- a/include/exec/helper-proto.h
16
--- a/tcg/optimize.c
50
+++ b/include/exec/helper-proto.h
17
+++ b/tcg/optimize.c
51
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ typedef struct OptContext {
52
-/* Helper file for declaring TCG helper functions.
19
QSIMPLEQ_HEAD(, MemCopyInfo) mem_free;
53
- This one expands prototypes for the helper functions. */
20
54
+/* SPDX-License-Identifier: GPL-2.0-or-later */
21
/* In flight values from optimization. */
55
+/*
22
- uint64_t a_mask; /* mask bit is 0 iff value identical to first input */
56
+ * Helper file for declaring TCG helper functions.
23
uint64_t z_mask; /* mask bit is 0 iff value bit is 0 */
57
+ * This one expands prototypes for the helper functions.
24
uint64_t s_mask; /* mask of clrsb(value) bits */
58
+ */
25
TCGType type;
59
26
@@ -XXX,XX +XXX,XX @@ static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
60
#ifndef HELPER_PROTO_H
27
61
#define HELPER_PROTO_H
28
static bool fold_masks(OptContext *ctx, TCGOp *op)
62
29
{
63
-#include "exec/helper-head.h"
30
- uint64_t a_mask = ctx->a_mask;
64
+#include "exec/helper-proto-common.h"
31
uint64_t z_mask = ctx->z_mask;
65
32
uint64_t s_mask = ctx->s_mask;
66
-/*
33
67
- * Work around an issue with --enable-lto, in which GCC's ipa-split pass
34
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
68
- * decides to split out the noreturn code paths that raise an exception,
35
* type changing opcodes.
69
- * taking the __builtin_return_address() along into the new function,
36
*/
70
- * where it no longer computes a value that returns to TCG generated code.
37
if (ctx->type == TCG_TYPE_I32) {
71
- * Despite the name, the noinline attribute affects splitter, so this
38
- a_mask = (int32_t)a_mask;
72
- * prevents the optimization in question. Given that helpers should not
39
z_mask = (int32_t)z_mask;
73
- * otherwise be called directly, this should have any other visible effect.
40
s_mask |= MAKE_64BIT_MASK(32, 32);
74
- *
41
ctx->z_mask = z_mask;
75
- * See https://gitlab.com/qemu-project/qemu/-/issues/1454
42
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
76
- */
43
if (z_mask == 0) {
77
-#define DEF_HELPER_ATTR __attribute__((noinline))
44
return tcg_opt_gen_movi(ctx, op, op->args[0], 0);
78
-
45
}
79
-#define DEF_HELPER_FLAGS_0(name, flags, ret) \
46
+ return false;
80
-dh_ctype(ret) HELPER(name) (void) DEF_HELPER_ATTR;
47
+}
81
-
82
-#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
83
-dh_ctype(ret) HELPER(name) (dh_ctype(t1)) DEF_HELPER_ATTR;
84
-
85
-#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
86
-dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)) DEF_HELPER_ATTR;
87
-
88
-#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
89
-dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), \
90
- dh_ctype(t3)) DEF_HELPER_ATTR;
91
-
92
-#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
93
-dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
94
- dh_ctype(t4)) DEF_HELPER_ATTR;
95
-
96
-#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
97
-dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
98
- dh_ctype(t4), dh_ctype(t5)) DEF_HELPER_ATTR;
99
-
100
-#define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \
101
-dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
102
- dh_ctype(t4), dh_ctype(t5), \
103
- dh_ctype(t6)) DEF_HELPER_ATTR;
104
-
105
-#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7) \
106
-dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
107
- dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \
108
- dh_ctype(t7)) DEF_HELPER_ATTR;
109
-
110
-#define IN_HELPER_PROTO
111
-
112
-#include "helper.h"
113
-#include "accel/tcg/tcg-runtime.h"
114
-#include "accel/tcg/plugin-helpers.h"
115
-
116
-#undef IN_HELPER_PROTO
117
-
118
-#undef DEF_HELPER_FLAGS_0
119
-#undef DEF_HELPER_FLAGS_1
120
-#undef DEF_HELPER_FLAGS_2
121
-#undef DEF_HELPER_FLAGS_3
122
-#undef DEF_HELPER_FLAGS_4
123
-#undef DEF_HELPER_FLAGS_5
124
-#undef DEF_HELPER_FLAGS_6
125
-#undef DEF_HELPER_FLAGS_7
126
-#undef DEF_HELPER_ATTR
127
+#define HELPER_H "helper.h"
128
+#include "exec/helper-proto.h.inc"
129
+#undef HELPER_H
130
131
#endif /* HELPER_PROTO_H */
132
diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
133
index XXXXXXX..XXXXXXX 100644
134
--- a/include/tcg/tcg-op-common.h
135
+++ b/include/tcg/tcg-op-common.h
136
@@ -XXX,XX +XXX,XX @@
137
#define TCG_TCG_OP_COMMON_H
138
139
#include "tcg/tcg.h"
140
-#include "exec/helper-proto.h"
141
+#include "exec/helper-proto-common.h"
142
#include "exec/helper-gen-common.h"
143
144
/* Basic output routines. Not for general consumption. */
145
diff --git a/include/exec/helper-proto.h.inc b/include/exec/helper-proto.h.inc
146
new file mode 100644
147
index XXXXXXX..XXXXXXX
148
--- /dev/null
149
+++ b/include/exec/helper-proto.h.inc
150
@@ -XXX,XX +XXX,XX @@
151
+/* SPDX-License-Identifier: GPL-2.0-or-later */
152
+/*
153
+ * Helper file for declaring TCG helper functions.
154
+ * This one expands prototypes for the helper functions.
155
+ * Define HELPER_H for the header file to be expanded.
156
+ */
157
+
158
+#include "exec/helper-head.h"
159
+
48
+
160
+/*
49
+/*
161
+ * Work around an issue with --enable-lto, in which GCC's ipa-split pass
50
+ * An "affected" mask bit is 0 if and only if the result is identical
162
+ * decides to split out the noreturn code paths that raise an exception,
51
+ * to the first input. Thus if the entire mask is 0, the operation
163
+ * taking the __builtin_return_address() along into the new function,
52
+ * is equivalent to a copy.
164
+ * where it no longer computes a value that returns to TCG generated code.
165
+ * Despite the name, the noinline attribute affects splitter, so this
166
+ * prevents the optimization in question. Given that helpers should not
167
+ * otherwise be called directly, this should not have any other visible effect.
168
+ *
169
+ * See https://gitlab.com/qemu-project/qemu/-/issues/1454
170
+ */
53
+ */
171
+#define DEF_HELPER_ATTR __attribute__((noinline))
54
+static bool fold_affected_mask(OptContext *ctx, TCGOp *op, uint64_t a_mask)
172
+
55
+{
173
+#define DEF_HELPER_FLAGS_0(name, flags, ret) \
56
+ if (ctx->type == TCG_TYPE_I32) {
174
+dh_ctype(ret) HELPER(name) (void) DEF_HELPER_ATTR;
57
+ a_mask = (uint32_t)a_mask;
175
+
58
+ }
176
+#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
59
if (a_mask == 0) {
177
+dh_ctype(ret) HELPER(name) (dh_ctype(t1)) DEF_HELPER_ATTR;
60
return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]);
178
+
61
}
179
+#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
62
@@ -XXX,XX +XXX,XX @@ static bool fold_and(OptContext *ctx, TCGOp *op)
180
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)) DEF_HELPER_ATTR;
63
* Known-zeros does not imply known-ones. Therefore unless
181
+
64
* arg2 is constant, we can't infer affected bits from it.
182
+#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
65
*/
183
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), \
66
- if (arg_is_const(op->args[2])) {
184
+ dh_ctype(t3)) DEF_HELPER_ATTR;
67
- ctx->a_mask = z1 & ~z2;
185
+
68
+ if (arg_is_const(op->args[2]) &&
186
+#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
69
+ fold_affected_mask(ctx, op, z1 & ~z2)) {
187
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
70
+ return true;
188
+ dh_ctype(t4)) DEF_HELPER_ATTR;
71
}
189
+
72
190
+#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
73
return fold_masks(ctx, op);
191
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
74
@@ -XXX,XX +XXX,XX @@ static bool fold_andc(OptContext *ctx, TCGOp *op)
192
+ dh_ctype(t4), dh_ctype(t5)) DEF_HELPER_ATTR;
75
*/
193
+
76
if (arg_is_const(op->args[2])) {
194
+#define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \
77
uint64_t z2 = ~arg_info(op->args[2])->z_mask;
195
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
78
- ctx->a_mask = z1 & ~z2;
196
+ dh_ctype(t4), dh_ctype(t5), \
79
+ if (fold_affected_mask(ctx, op, z1 & ~z2)) {
197
+ dh_ctype(t6)) DEF_HELPER_ATTR;
80
+ return true;
198
+
81
+ }
199
+#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7) \
82
z1 &= z2;
200
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
83
}
201
+ dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \
84
ctx->z_mask = z1;
202
+ dh_ctype(t7)) DEF_HELPER_ATTR;
85
@@ -XXX,XX +XXX,XX @@ static bool fold_extract(OptContext *ctx, TCGOp *op)
203
+
86
204
+#define IN_HELPER_PROTO
87
z_mask_old = arg_info(op->args[1])->z_mask;
205
+
88
z_mask = extract64(z_mask_old, pos, len);
206
+#include HELPER_H
89
- if (pos == 0) {
207
+
90
- ctx->a_mask = z_mask_old ^ z_mask;
208
+#undef IN_HELPER_PROTO
91
+ if (pos == 0 && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
209
+
92
+ return true;
210
+#undef DEF_HELPER_FLAGS_0
93
}
211
+#undef DEF_HELPER_FLAGS_1
94
ctx->z_mask = z_mask;
212
+#undef DEF_HELPER_FLAGS_2
95
ctx->s_mask = smask_from_zmask(z_mask);
213
+#undef DEF_HELPER_FLAGS_3
96
@@ -XXX,XX +XXX,XX @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
214
+#undef DEF_HELPER_FLAGS_4
97
215
+#undef DEF_HELPER_FLAGS_5
98
ctx->z_mask = z_mask;
216
+#undef DEF_HELPER_FLAGS_6
99
ctx->s_mask = s_mask;
217
+#undef DEF_HELPER_FLAGS_7
100
- if (!type_change) {
218
+#undef DEF_HELPER_ATTR
101
- ctx->a_mask = s_mask & ~s_mask_old;
219
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
102
+ if (!type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
220
index XXXXXXX..XXXXXXX 100644
103
+ return true;
221
--- a/accel/tcg/cputlb.c
104
}
222
+++ b/accel/tcg/cputlb.c
105
223
@@ -XXX,XX +XXX,XX @@
106
return fold_masks(ctx, op);
224
#include "tcg/tcg.h"
107
@@ -XXX,XX +XXX,XX @@ static bool fold_extu(OptContext *ctx, TCGOp *op)
225
#include "qemu/error-report.h"
108
226
#include "exec/log.h"
109
ctx->z_mask = z_mask;
227
-#include "exec/helper-proto.h"
110
ctx->s_mask = smask_from_zmask(z_mask);
228
+#include "exec/helper-proto-common.h"
111
- if (!type_change) {
229
#include "qemu/atomic.h"
112
- ctx->a_mask = z_mask_old ^ z_mask;
230
#include "qemu/atomic128.h"
113
+ if (!type_change && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
231
#include "exec/translate-all.h"
114
+ return true;
232
@@ -XXX,XX +XXX,XX @@
115
}
233
#endif
116
return fold_masks(ctx, op);
234
#include "tcg/tcg-ldst.h"
117
}
235
#include "tcg/oversized-guest.h"
118
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
236
-#include "exec/helper-proto.h"
119
s_mask |= MAKE_64BIT_MASK(len, 64 - len);
237
120
ctx->s_mask = s_mask;
238
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
121
239
/* #define DEBUG_TLB */
122
- if (pos == 0) {
240
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
123
- ctx->a_mask = s_mask & ~s_mask_old;
241
index XXXXXXX..XXXXXXX 100644
124
+ if (pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
242
--- a/accel/tcg/plugin-gen.c
125
+ return true;
243
+++ b/accel/tcg/plugin-gen.c
126
}
244
@@ -XXX,XX +XXX,XX @@
127
245
#include "exec/exec-all.h"
128
return fold_masks(ctx, op);
246
#include "exec/plugin-gen.h"
129
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
247
#include "exec/translator.h"
130
}
248
-#include "exec/helper-proto.h"
131
249
+#include "exec/helper-proto-common.h"
132
/* Assume all bits affected, no bits known zero, no sign reps. */
250
133
- ctx.a_mask = -1;
251
#define HELPER_H "accel/tcg/plugin-helpers.h"
134
ctx.z_mask = -1;
252
#include "exec/helper-info.c.inc"
135
ctx.s_mask = 0;
253
diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
136
254
index XXXXXXX..XXXXXXX 100644
255
--- a/accel/tcg/tcg-runtime-gvec.c
256
+++ b/accel/tcg/tcg-runtime-gvec.c
257
@@ -XXX,XX +XXX,XX @@
258
#include "qemu/osdep.h"
259
#include "qemu/host-utils.h"
260
#include "cpu.h"
261
-#include "exec/helper-proto.h"
262
+#include "exec/helper-proto-common.h"
263
#include "tcg/tcg-gvec-desc.h"
264
265
266
diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c
267
index XXXXXXX..XXXXXXX 100644
268
--- a/accel/tcg/tcg-runtime.c
269
+++ b/accel/tcg/tcg-runtime.c
270
@@ -XXX,XX +XXX,XX @@
271
#include "qemu/osdep.h"
272
#include "qemu/host-utils.h"
273
#include "cpu.h"
274
-#include "exec/helper-proto.h"
275
+#include "exec/helper-proto-common.h"
276
#include "exec/cpu_ldst.h"
277
#include "exec/exec-all.h"
278
#include "disas/disas.h"
279
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
280
index XXXXXXX..XXXXXXX 100644
281
--- a/target/arm/tcg/translate.c
282
+++ b/target/arm/tcg/translate.c
283
@@ -XXX,XX +XXX,XX @@
284
#include "translate.h"
285
#include "translate-a32.h"
286
#include "exec/gen-icount.h"
287
+#include "exec/helper-proto.h"
288
289
#define HELPER_H "helper.h"
290
#include "exec/helper-info.c.inc"
291
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
292
index XXXXXXX..XXXXXXX 100644
293
--- a/target/hexagon/translate.c
294
+++ b/target/hexagon/translate.c
295
@@ -XXX,XX +XXX,XX @@
296
#include "tcg/tcg-op.h"
297
#include "tcg/tcg-op-gvec.h"
298
#include "exec/helper-gen.h"
299
+#include "exec/helper-proto.h"
300
#include "exec/cpu_ldst.h"
301
#include "exec/log.h"
302
#include "internal.h"
303
--
137
--
304
2.34.1
138
2.43.0
305
306
diff view generated by jsdifflib
1
Move most includes from *translate*.c to translate.h, ensuring
1
Use of fold_masks should be restricted to those opcodes that
2
that we get the ordering correct. Ensure cpu.h is first.
2
can reliably make use of it -- those with a single output,
3
Use disas/disas.h instead of exec/log.h.
3
and from higher-level folders that set up the masks.
4
Drop otherwise unused includes.
4
Prepare for conversion of each folder in turn.
5
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
8
---
9
target/mips/tcg/translate.h | 6 ++++--
9
tcg/optimize.c | 17 ++++++++++++++---
10
target/mips/tcg/msa_translate.c | 3 ---
10
1 file changed, 14 insertions(+), 3 deletions(-)
11
target/mips/tcg/mxu_translate.c | 2 --
12
target/mips/tcg/octeon_translate.c | 4 +---
13
target/mips/tcg/rel6_translate.c | 2 --
14
target/mips/tcg/translate.c | 18 ++++++------------
15
target/mips/tcg/translate_addr_const.c | 1 -
16
target/mips/tcg/tx79_translate.c | 4 +---
17
target/mips/tcg/vr54xx_translate.c | 3 ---
18
9 files changed, 12 insertions(+), 31 deletions(-)
19
11
20
diff --git a/target/mips/tcg/translate.h b/target/mips/tcg/translate.h
12
diff --git a/tcg/optimize.c b/tcg/optimize.c
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/target/mips/tcg/translate.h
14
--- a/tcg/optimize.c
23
+++ b/target/mips/tcg/translate.h
15
+++ b/tcg/optimize.c
24
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
25
#ifndef TARGET_MIPS_TRANSLATE_H
17
{
26
#define TARGET_MIPS_TRANSLATE_H
18
uint64_t z_mask = ctx->z_mask;
27
19
uint64_t s_mask = ctx->s_mask;
28
-#include "qemu/log.h"
20
+ const TCGOpDef *def = &tcg_op_defs[op->opc];
29
-#include "exec/translator.h"
21
+ TCGTemp *ts;
30
+#include "cpu.h"
22
+ TempOptInfo *ti;
31
#include "tcg/tcg-op.h"
23
+
32
+#include "exec/translator.h"
24
+ /* Only single-output opcodes are supported here. */
33
+#include "exec/helper-gen.h"
25
+ tcg_debug_assert(def->nb_oargs == 1);
34
+#include "qemu/log.h"
26
35
27
/*
36
#define MIPS_DEBUG_DISAS 0
28
* 32-bit ops generate 32-bit results, which for the purpose of
37
29
@@ -XXX,XX +XXX,XX @@ static bool fold_masks(OptContext *ctx, TCGOp *op)
38
diff --git a/target/mips/tcg/msa_translate.c b/target/mips/tcg/msa_translate.c
30
if (ctx->type == TCG_TYPE_I32) {
39
index XXXXXXX..XXXXXXX 100644
31
z_mask = (int32_t)z_mask;
40
--- a/target/mips/tcg/msa_translate.c
32
s_mask |= MAKE_64BIT_MASK(32, 32);
41
+++ b/target/mips/tcg/msa_translate.c
33
- ctx->z_mask = z_mask;
42
@@ -XXX,XX +XXX,XX @@
34
- ctx->s_mask = s_mask;
43
* SPDX-License-Identifier: LGPL-2.1-or-later
35
}
44
*/
36
45
#include "qemu/osdep.h"
37
if (z_mask == 0) {
46
-#include "tcg/tcg-op.h"
38
return tcg_opt_gen_movi(ctx, op, op->args[0], 0);
47
-#include "exec/helper-gen.h"
39
}
48
#include "translate.h"
40
- return false;
49
#include "fpu_helper.h"
41
+
50
-#include "internal.h"
42
+ ts = arg_temp(op->args[0]);
51
43
+ reset_ts(ctx, ts);
52
static int elm_n(DisasContext *ctx, int x);
44
+
53
static int elm_df(DisasContext *ctx, int x);
45
+ ti = ts_info(ts);
54
diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c
46
+ ti->z_mask = z_mask;
55
index XXXXXXX..XXXXXXX 100644
47
+ ti->s_mask = s_mask;
56
--- a/target/mips/tcg/mxu_translate.c
48
+ return true;
57
+++ b/target/mips/tcg/mxu_translate.c
49
}
58
@@ -XXX,XX +XXX,XX @@
59
*/
60
61
#include "qemu/osdep.h"
62
-#include "tcg/tcg-op.h"
63
-#include "exec/helper-gen.h"
64
#include "translate.h"
65
50
66
/*
51
/*
67
diff --git a/target/mips/tcg/octeon_translate.c b/target/mips/tcg/octeon_translate.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/mips/tcg/octeon_translate.c
70
+++ b/target/mips/tcg/octeon_translate.c
71
@@ -XXX,XX +XXX,XX @@
72
*/
73
74
#include "qemu/osdep.h"
75
-#include "tcg/tcg-op.h"
76
-#include "tcg/tcg-op-gvec.h"
77
-#include "exec/helper-gen.h"
78
#include "translate.h"
79
+#include "tcg/tcg-op-gvec.h"
80
81
/* Include the auto-generated decoder. */
82
#include "decode-octeon.c.inc"
83
diff --git a/target/mips/tcg/rel6_translate.c b/target/mips/tcg/rel6_translate.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/mips/tcg/rel6_translate.c
86
+++ b/target/mips/tcg/rel6_translate.c
87
@@ -XXX,XX +XXX,XX @@
88
*/
89
90
#include "qemu/osdep.h"
91
-#include "tcg/tcg-op.h"
92
-#include "exec/helper-gen.h"
93
#include "translate.h"
94
95
/* Include the auto-generated decoders. */
96
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/mips/tcg/translate.c
99
+++ b/target/mips/tcg/translate.c
100
@@ -XXX,XX +XXX,XX @@
101
*/
102
103
#include "qemu/osdep.h"
104
-#include "cpu.h"
105
-#include "internal.h"
106
-#include "tcg/tcg-op.h"
107
-#include "exec/translator.h"
108
-#include "exec/helper-proto.h"
109
-#include "exec/helper-gen.h"
110
-#include "semihosting/semihost.h"
111
-
112
-#include "trace.h"
113
-#include "exec/log.h"
114
-#include "qemu/qemu-print.h"
115
-#include "fpu_helper.h"
116
#include "translate.h"
117
+#include "internal.h"
118
+#include "exec/helper-proto.h"
119
+#include "semihosting/semihost.h"
120
+#include "trace.h"
121
+#include "disas/disas.h"
122
+#include "fpu_helper.h"
123
124
#define HELPER_H "helper.h"
125
#include "exec/helper-info.c.inc"
126
diff --git a/target/mips/tcg/translate_addr_const.c b/target/mips/tcg/translate_addr_const.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/target/mips/tcg/translate_addr_const.c
129
+++ b/target/mips/tcg/translate_addr_const.c
130
@@ -XXX,XX +XXX,XX @@
131
* SPDX-License-Identifier: LGPL-2.1-or-later
132
*/
133
#include "qemu/osdep.h"
134
-#include "tcg/tcg-op.h"
135
#include "translate.h"
136
137
bool gen_lsa(DisasContext *ctx, int rd, int rt, int rs, int sa)
138
diff --git a/target/mips/tcg/tx79_translate.c b/target/mips/tcg/tx79_translate.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/target/mips/tcg/tx79_translate.c
141
+++ b/target/mips/tcg/tx79_translate.c
142
@@ -XXX,XX +XXX,XX @@
143
*/
144
145
#include "qemu/osdep.h"
146
-#include "tcg/tcg-op.h"
147
-#include "tcg/tcg-op-gvec.h"
148
-#include "exec/helper-gen.h"
149
#include "translate.h"
150
+#include "tcg/tcg-op-gvec.h"
151
152
/* Include the auto-generated decoder. */
153
#include "decode-tx79.c.inc"
154
diff --git a/target/mips/tcg/vr54xx_translate.c b/target/mips/tcg/vr54xx_translate.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/target/mips/tcg/vr54xx_translate.c
157
+++ b/target/mips/tcg/vr54xx_translate.c
158
@@ -XXX,XX +XXX,XX @@
159
*/
160
161
#include "qemu/osdep.h"
162
-#include "tcg/tcg-op.h"
163
-#include "exec/helper-gen.h"
164
#include "translate.h"
165
-#include "internal.h"
166
167
/* Include the auto-generated decoder. */
168
#include "decode-vr54xx.c.inc"
169
--
52
--
170
2.34.1
53
2.43.0
171
172
diff view generated by jsdifflib
1
Fixes an assert in tcg_gen_code that we don't accidentally
1
Add a routine to which masks can be passed directly, rather than
2
eliminate an insn_start during optimization.
2
storing them into OptContext. To be used in upcoming patches.
3
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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
target/sh4/translate.c | 15 ++++++++++++---
7
tcg/optimize.c | 15 ++++++++++++---
8
1 file changed, 12 insertions(+), 3 deletions(-)
8
1 file changed, 12 insertions(+), 3 deletions(-)
9
9
10
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/sh4/translate.c
12
--- a/tcg/optimize.c
13
+++ b/target/sh4/translate.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
14
@@ -XXX,XX +XXX,XX @@ static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
15
15
return fold_const2(ctx, op);
16
/* The entire region has been translated. */
16
}
17
ctx->envflags &= ~TB_FLAG_GUSA_MASK;
17
18
- ctx->base.pc_next = pc_end;
18
-static bool fold_masks(OptContext *ctx, TCGOp *op)
19
- ctx->base.num_insns += max_insns - 1;
19
+/*
20
- return;
20
+ * Record "zero" and "sign" masks for the single output of @op.
21
+ goto done;
21
+ * See TempOptInfo definition of z_mask and s_mask.
22
22
+ * If z_mask allows, fold the output to constant zero.
23
fail:
23
+ */
24
qemu_log_mask(LOG_UNIMP, "Unrecognized gUSA sequence %08x-%08x\n",
24
+static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
25
@@ -XXX,XX +XXX,XX @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
25
+ uint64_t z_mask, uint64_t s_mask)
26
purposes of accounting within the TB. We might as well report the
26
{
27
entire region consumed via ctx->base.pc_next so that it's immediately
27
- uint64_t z_mask = ctx->z_mask;
28
available in the disassembly dump. */
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
+}
29
+
40
+
30
+ done:
41
/*
31
ctx->base.pc_next = pc_end;
42
* An "affected" mask bit is 0 if and only if the result is identical
32
ctx->base.num_insns += max_insns - 1;
43
* to the first input. Thus if the entire mask is 0, the operation
33
+
34
+ /*
35
+ * Emit insn_start to cover each of the insns in the region.
36
+ * This matches an assert in tcg.c making sure that we have
37
+ * tb->icount * insn_start.
38
+ */
39
+ for (i = 1; i < max_insns; ++i) {
40
+ tcg_gen_insn_start(pc + i * 2, ctx->envflags);
41
+ }
42
}
43
#endif
44
45
--
44
--
46
2.34.1
45
2.43.0
47
48
diff view generated by jsdifflib
1
Disconnect the layout of ArchCPU from TCG compilation.
1
Consider the passed s_mask to be a minimum deduced from
2
Pass the relative offset of 'env' and 'neg.tlb.f' as a parameter.
2
either existing s_mask or from a sign-extension operation.
3
We may be able to deduce more from the set of known zeros.
4
Remove identical logic from several opcode folders.
3
5
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
8
---
7
include/exec/cpu-defs.h | 39 +---------------------
9
tcg/optimize.c | 21 ++++++---------------
8
include/exec/tlb-common.h | 56 ++++++++++++++++++++++++++++++++
10
1 file changed, 6 insertions(+), 15 deletions(-)
9
include/tcg/tcg.h | 1 +
10
accel/tcg/translate-all.c | 2 ++
11
tcg/tcg.c | 13 ++++++++
12
tcg/aarch64/tcg-target.c.inc | 7 ++--
13
tcg/arm/tcg-target.c.inc | 7 ++--
14
tcg/i386/tcg-target.c.inc | 9 ++---
15
tcg/loongarch64/tcg-target.c.inc | 7 ++--
16
tcg/mips/tcg-target.c.inc | 7 ++--
17
tcg/ppc/tcg-target.c.inc | 7 ++--
18
tcg/riscv/tcg-target.c.inc | 7 ++--
19
tcg/s390x/tcg-target.c.inc | 7 ++--
20
tcg/sparc64/tcg-target.c.inc | 7 ++--
21
14 files changed, 110 insertions(+), 66 deletions(-)
22
create mode 100644 include/exec/tlb-common.h
23
11
24
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
12
diff --git a/tcg/optimize.c b/tcg/optimize.c
25
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
26
--- a/include/exec/cpu-defs.h
14
--- a/tcg/optimize.c
27
+++ b/include/exec/cpu-defs.h
15
+++ b/tcg/optimize.c
28
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
29
#define NB_MMU_MODES 16
17
* Record "zero" and "sign" masks for the single output of @op.
30
18
* See TempOptInfo definition of z_mask and s_mask.
31
#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
19
* If z_mask allows, fold the output to constant zero.
32
+#include "exec/tlb-common.h"
20
+ * The passed s_mask may be augmented by z_mask.
33
34
/* use a fully associative victim tlb of 8 entries */
35
#define CPU_VTLB_SIZE 8
36
37
-#define CPU_TLB_ENTRY_BITS 5
38
-
39
#define CPU_TLB_DYN_MIN_BITS 6
40
#define CPU_TLB_DYN_DEFAULT_BITS 8
41
42
@@ -XXX,XX +XXX,XX @@
43
# endif
44
# endif
45
46
-/* Minimalized TLB entry for use by TCG fast path. */
47
-typedef union CPUTLBEntry {
48
- struct {
49
- uint64_t addr_read;
50
- uint64_t addr_write;
51
- uint64_t addr_code;
52
- /*
53
- * Addend to virtual address to get host address. IO accesses
54
- * use the corresponding iotlb value.
55
- */
56
- uintptr_t addend;
57
- };
58
- /*
59
- * Padding to get a power of two size, as well as index
60
- * access to addr_{read,write,code}.
61
- */
62
- uint64_t addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(uint64_t)];
63
-} CPUTLBEntry;
64
-
65
-QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
66
-
67
#endif /* !CONFIG_USER_ONLY && CONFIG_TCG */
68
69
#if !defined(CONFIG_USER_ONLY)
70
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBDesc {
71
CPUTLBEntryFull *fulltlb;
72
} CPUTLBDesc;
73
74
-/*
75
- * Data elements that are per MMU mode, accessed by the fast path.
76
- * The structure is aligned to aid loading the pair with one insn.
77
- */
78
-typedef struct CPUTLBDescFast {
79
- /* Contains (n_entries - 1) << CPU_TLB_ENTRY_BITS */
80
- uintptr_t mask;
81
- /* The array of tlb entries itself. */
82
- CPUTLBEntry *table;
83
-} CPUTLBDescFast QEMU_ALIGNED(2 * sizeof(void *));
84
-
85
/*
86
* Data elements that are shared between all MMU modes.
87
*/
21
*/
88
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLB {
22
static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
89
CPUTLBDescFast f[NB_MMU_MODES];
23
uint64_t z_mask, uint64_t s_mask)
90
} CPUTLB;
24
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
91
25
92
-/* This will be used by TCG backends to compute offsets. */
26
ti = ts_info(ts);
93
-#define TLB_MASK_TABLE_OFS(IDX) \
27
ti->z_mask = z_mask;
94
- ((int)offsetof(ArchCPU, neg.tlb.f[IDX]) - (int)offsetof(ArchCPU, env))
28
- ti->s_mask = s_mask;
95
-
29
+ ti->s_mask = s_mask | smask_from_zmask(z_mask);
96
#else
97
98
typedef struct CPUTLB { } CPUTLB;
99
diff --git a/include/exec/tlb-common.h b/include/exec/tlb-common.h
100
new file mode 100644
101
index XXXXXXX..XXXXXXX
102
--- /dev/null
103
+++ b/include/exec/tlb-common.h
104
@@ -XXX,XX +XXX,XX @@
105
+/*
106
+ * Common definitions for the softmmu tlb
107
+ *
108
+ * Copyright (c) 2003 Fabrice Bellard
109
+ *
110
+ * This library is free software; you can redistribute it and/or
111
+ * modify it under the terms of the GNU Lesser General Public
112
+ * License as published by the Free Software Foundation; either
113
+ * version 2.1 of the License, or (at your option) any later version.
114
+ *
115
+ * This library is distributed in the hope that it will be useful,
116
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
117
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
118
+ * Lesser General Public License for more details.
119
+ *
120
+ * You should have received a copy of the GNU Lesser General Public
121
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
122
+ */
123
+#ifndef EXEC_TLB_COMMON_H
124
+#define EXEC_TLB_COMMON_H 1
125
+
126
+#define CPU_TLB_ENTRY_BITS 5
127
+
128
+/* Minimalized TLB entry for use by TCG fast path. */
129
+typedef union CPUTLBEntry {
130
+ struct {
131
+ uint64_t addr_read;
132
+ uint64_t addr_write;
133
+ uint64_t addr_code;
134
+ /*
135
+ * Addend to virtual address to get host address. IO accesses
136
+ * use the corresponding iotlb value.
137
+ */
138
+ uintptr_t addend;
139
+ };
140
+ /*
141
+ * Padding to get a power of two size, as well as index
142
+ * access to addr_{read,write,code}.
143
+ */
144
+ uint64_t addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(uint64_t)];
145
+} CPUTLBEntry;
146
+
147
+QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
148
+
149
+/*
150
+ * Data elements that are per MMU mode, accessed by the fast path.
151
+ * The structure is aligned to aid loading the pair with one insn.
152
+ */
153
+typedef struct CPUTLBDescFast {
154
+ /* Contains (n_entries - 1) << CPU_TLB_ENTRY_BITS */
155
+ uintptr_t mask;
156
+ /* The array of tlb entries itself. */
157
+ CPUTLBEntry *table;
158
+} CPUTLBDescFast QEMU_ALIGNED(2 * sizeof(void *));
159
+
160
+#endif /* EXEC_TLB_COMMON_H */
161
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
162
index XXXXXXX..XXXXXXX 100644
163
--- a/include/tcg/tcg.h
164
+++ b/include/tcg/tcg.h
165
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
166
TCGType addr_type; /* TCG_TYPE_I32 or TCG_TYPE_I64 */
167
168
#ifdef CONFIG_SOFTMMU
169
+ int tlb_fast_offset;
170
int page_mask;
171
uint8_t page_bits;
172
uint8_t tlb_dyn_max_bits;
173
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
174
index XXXXXXX..XXXXXXX 100644
175
--- a/accel/tcg/translate-all.c
176
+++ b/accel/tcg/translate-all.c
177
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
178
tcg_ctx->page_bits = TARGET_PAGE_BITS;
179
tcg_ctx->page_mask = TARGET_PAGE_MASK;
180
tcg_ctx->tlb_dyn_max_bits = CPU_TLB_DYN_MAX_BITS;
181
+ tcg_ctx->tlb_fast_offset =
182
+ (int)offsetof(ArchCPU, neg.tlb.f) - (int)offsetof(ArchCPU, env);
183
#endif
184
185
tb_overflow:
186
diff --git a/tcg/tcg.c b/tcg/tcg.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/tcg/tcg.c
189
+++ b/tcg/tcg.c
190
@@ -XXX,XX +XXX,XX @@
191
#define NO_CPU_IO_DEFS
192
193
#include "exec/exec-all.h"
194
+#include "exec/tlb-common.h"
195
#include "tcg/tcg-op.h"
196
197
#if UINTPTR_MAX == UINT32_MAX
198
@@ -XXX,XX +XXX,XX @@ static uintptr_t G_GNUC_UNUSED get_jmp_target_addr(TCGContext *s, int which)
199
return (uintptr_t)tcg_splitwx_to_rx(&s->gen_tb->jmp_target_addr[which]);
200
}
201
202
+#if defined(CONFIG_SOFTMMU) && !defined(CONFIG_TCG_INTERPRETER)
203
+static int tlb_mask_table_ofs(TCGContext *s, int which)
204
+{
205
+ return s->tlb_fast_offset + which * sizeof(CPUTLBDescFast);
206
+}
207
+#endif
208
+
209
/* Signal overflow, starting over with fewer guest insns. */
210
static G_NORETURN
211
void tcg_raise_tb_overflow(TCGContext *s)
212
@@ -XXX,XX +XXX,XX @@ void tcg_func_start(TCGContext *s)
213
214
tcg_debug_assert(s->addr_type == TCG_TYPE_I32 ||
215
s->addr_type == TCG_TYPE_I64);
216
+
217
+#if defined(CONFIG_SOFTMMU) && !defined(CONFIG_TCG_INTERPRETER)
218
+ tcg_debug_assert(s->tlb_fast_offset < 0);
219
+ tcg_debug_assert(s->tlb_fast_offset >= MIN_TLB_MASK_TABLE_OFS);
220
+#endif
221
}
222
223
static TCGTemp *tcg_temp_alloc(TCGContext *s)
224
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
225
index XXXXXXX..XXXXXXX 100644
226
--- a/tcg/aarch64/tcg-target.c.inc
227
+++ b/tcg/aarch64/tcg-target.c.inc
228
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
229
return true;
30
return true;
230
}
31
}
231
32
232
+/* We expect to use a 7-bit scaled negative offset from ENV. */
33
@@ -XXX,XX +XXX,XX @@ static bool fold_bswap(OptContext *ctx, TCGOp *op)
233
+#define MIN_TLB_MASK_TABLE_OFS -512
34
default:
234
+
35
g_assert_not_reached();
235
/*
36
}
236
* For softmmu, perform the TLB load and compare.
37
- s_mask = smask_from_zmask(z_mask);
237
* For useronly, perform any required alignment tests.
38
238
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
39
+ s_mask = 0;
239
? TCG_TYPE_I64 : TCG_TYPE_I32);
40
switch (op->args[2] & (TCG_BSWAP_OZ | TCG_BSWAP_OS)) {
240
41
case TCG_BSWAP_OZ:
241
/* Load env_tlb(env)->f[mmu_idx].{mask,table} into {tmp0,tmp1}. */
42
break;
242
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
43
@@ -XXX,XX +XXX,XX @@ static bool fold_bswap(OptContext *ctx, TCGOp *op)
243
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -512);
44
default:
244
QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, mask) != 0);
45
/* The high bits are undefined: force all bits above the sign to 1. */
245
QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, table) != 8);
46
z_mask |= sign << 1;
246
tcg_out_insn(s, 3314, LDP, TCG_REG_TMP0, TCG_REG_TMP1, TCG_AREG0,
47
- s_mask = 0;
247
- TLB_MASK_TABLE_OFS(mem_index), 1, 0);
48
break;
248
+ tlb_mask_table_ofs(s, mem_index), 1, 0);
49
}
249
50
ctx->z_mask = z_mask;
250
/* Extract the TLB index from the address into X0. */
51
@@ -XXX,XX +XXX,XX @@ static bool fold_count_zeros(OptContext *ctx, TCGOp *op)
251
tcg_out_insn(s, 3502S, AND_LSR, mask_type == TCG_TYPE_I64,
52
g_assert_not_reached();
252
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
53
}
253
index XXXXXXX..XXXXXXX 100644
54
ctx->z_mask = arg_info(op->args[2])->z_mask | z_mask;
254
--- a/tcg/arm/tcg-target.c.inc
55
- ctx->s_mask = smask_from_zmask(ctx->z_mask);
255
+++ b/tcg/arm/tcg-target.c.inc
256
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
257
return true;
258
}
259
260
+/* We expect to use an 9-bit sign-magnitude negative offset from ENV. */
261
+#define MIN_TLB_MASK_TABLE_OFS -256
262
+
263
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
264
TCGReg addrlo, TCGReg addrhi,
265
MemOpIdx oi, bool is_ld)
266
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
267
int mem_index = get_mmuidx(oi);
268
int cmp_off = is_ld ? offsetof(CPUTLBEntry, addr_read)
269
: offsetof(CPUTLBEntry, addr_write);
270
- int fast_off = TLB_MASK_TABLE_OFS(mem_index);
271
+ int fast_off = tlb_mask_table_ofs(s, mem_index);
272
unsigned s_mask = (1 << (opc & MO_SIZE)) - 1;
273
TCGReg t_addr;
274
275
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
276
ldst->addrhi_reg = addrhi;
277
278
/* Load env_tlb(env)->f[mmu_idx].{mask,table} into {r0,r1}. */
279
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
280
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -256);
281
QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, mask) != 0);
282
QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, table) != 4);
283
tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_AREG0, fast_off);
284
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
285
index XXXXXXX..XXXXXXX 100644
286
--- a/tcg/i386/tcg-target.c.inc
287
+++ b/tcg/i386/tcg-target.c.inc
288
@@ -XXX,XX +XXX,XX @@ static inline int setup_guest_base_seg(void)
289
#endif /* setup_guest_base_seg */
290
#endif /* !SOFTMMU */
291
292
+#define MIN_TLB_MASK_TABLE_OFS INT_MIN
293
+
294
/*
295
* For softmmu, perform the TLB load and compare.
296
* For useronly, perform any required alignment tests.
297
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
298
int trexw = 0, hrexw = 0, tlbrexw = 0;
299
unsigned mem_index = get_mmuidx(oi);
300
unsigned s_mask = (1 << s_bits) - 1;
301
+ int fast_ofs = tlb_mask_table_ofs(s, mem_index);
302
int tlb_mask;
303
304
ldst = new_ldst_label(s);
305
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
306
s->page_bits - CPU_TLB_ENTRY_BITS);
307
308
tcg_out_modrm_offset(s, OPC_AND_GvEv + trexw, TCG_REG_L0, TCG_AREG0,
309
- TLB_MASK_TABLE_OFS(mem_index) +
310
- offsetof(CPUTLBDescFast, mask));
311
+ fast_ofs + offsetof(CPUTLBDescFast, mask));
312
313
tcg_out_modrm_offset(s, OPC_ADD_GvEv + hrexw, TCG_REG_L0, TCG_AREG0,
314
- TLB_MASK_TABLE_OFS(mem_index) +
315
- offsetof(CPUTLBDescFast, table));
316
+ fast_ofs + offsetof(CPUTLBDescFast, table));
317
318
/*
319
* If the required alignment is at least as large as the access, simply
320
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
321
index XXXXXXX..XXXXXXX 100644
322
--- a/tcg/loongarch64/tcg-target.c.inc
323
+++ b/tcg/loongarch64/tcg-target.c.inc
324
@@ -XXX,XX +XXX,XX @@ bool tcg_target_has_memory_bswap(MemOp memop)
325
return false;
56
return false;
326
}
57
}
327
58
328
+/* We expect to use a 12-bit negative offset from ENV. */
59
@@ -XXX,XX +XXX,XX @@ static bool fold_ctpop(OptContext *ctx, TCGOp *op)
329
+#define MIN_TLB_MASK_TABLE_OFS -(1 << 11)
60
default:
330
+
61
g_assert_not_reached();
331
/*
62
}
332
* For softmmu, perform the TLB load and compare.
63
- ctx->s_mask = smask_from_zmask(ctx->z_mask);
333
* For useronly, perform any required alignment tests.
334
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
335
#ifdef CONFIG_SOFTMMU
336
unsigned s_bits = opc & MO_SIZE;
337
int mem_index = get_mmuidx(oi);
338
- int fast_ofs = TLB_MASK_TABLE_OFS(mem_index);
339
+ int fast_ofs = tlb_mask_table_ofs(s, mem_index);
340
int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask);
341
int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table);
342
343
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
344
ldst->oi = oi;
345
ldst->addrlo_reg = addr_reg;
346
347
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
348
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11));
349
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs);
350
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs);
351
352
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
353
index XXXXXXX..XXXXXXX 100644
354
--- a/tcg/mips/tcg-target.c.inc
355
+++ b/tcg/mips/tcg-target.c.inc
356
@@ -XXX,XX +XXX,XX @@ bool tcg_target_has_memory_bswap(MemOp memop)
357
return false;
64
return false;
358
}
65
}
359
66
360
+/* We expect to use a 16-bit negative offset from ENV. */
67
@@ -XXX,XX +XXX,XX @@ static bool fold_extract(OptContext *ctx, TCGOp *op)
361
+#define MIN_TLB_MASK_TABLE_OFS -32768
68
return true;
362
+
69
}
363
/*
70
ctx->z_mask = z_mask;
364
* For softmmu, perform the TLB load and compare.
71
- ctx->s_mask = smask_from_zmask(z_mask);
365
* For useronly, perform any required alignment tests.
72
366
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
73
return fold_masks(ctx, op);
367
#ifdef CONFIG_SOFTMMU
368
unsigned s_mask = (1 << s_bits) - 1;
369
int mem_index = get_mmuidx(oi);
370
- int fast_off = TLB_MASK_TABLE_OFS(mem_index);
371
+ int fast_off = tlb_mask_table_ofs(s, mem_index);
372
int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
373
int table_off = fast_off + offsetof(CPUTLBDescFast, table);
374
int add_off = offsetof(CPUTLBEntry, addend);
375
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
376
ldst->addrhi_reg = addrhi;
377
378
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
379
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
380
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -32768);
381
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_AREG0, mask_off);
382
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP1, TCG_AREG0, table_off);
383
384
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
385
index XXXXXXX..XXXXXXX 100644
386
--- a/tcg/ppc/tcg-target.c.inc
387
+++ b/tcg/ppc/tcg-target.c.inc
388
@@ -XXX,XX +XXX,XX @@ bool tcg_target_has_memory_bswap(MemOp memop)
389
return aa.atom <= MO_64;
390
}
74
}
391
75
@@ -XXX,XX +XXX,XX @@ static bool fold_extu(OptContext *ctx, TCGOp *op)
392
+/* We expect to use a 16-bit negative offset from ENV. */
76
}
393
+#define MIN_TLB_MASK_TABLE_OFS -32768
77
394
+
78
ctx->z_mask = z_mask;
395
/*
79
- ctx->s_mask = smask_from_zmask(z_mask);
396
* For softmmu, perform the TLB load and compare.
80
if (!type_change && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
397
* For useronly, perform any required alignment tests.
81
return true;
398
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
82
}
399
int mem_index = get_mmuidx(oi);
83
@@ -XXX,XX +XXX,XX @@ static bool fold_qemu_ld(OptContext *ctx, TCGOp *op)
400
int cmp_off = is_ld ? offsetof(CPUTLBEntry, addr_read)
84
int width = 8 * memop_size(mop);
401
: offsetof(CPUTLBEntry, addr_write);
85
402
- int fast_off = TLB_MASK_TABLE_OFS(mem_index);
86
if (width < 64) {
403
+ int fast_off = tlb_mask_table_ofs(s, mem_index);
87
- ctx->s_mask = MAKE_64BIT_MASK(width, 64 - width);
404
int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
88
- if (!(mop & MO_SIGN)) {
405
int table_off = fast_off + offsetof(CPUTLBDescFast, table);
89
+ if (mop & MO_SIGN) {
406
90
+ ctx->s_mask = MAKE_64BIT_MASK(width, 64 - width);
407
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
91
+ } else {
408
ldst->addrhi_reg = addrhi;
92
ctx->z_mask = MAKE_64BIT_MASK(0, width);
409
93
- ctx->s_mask <<= 1;
410
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
94
}
411
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
95
}
412
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -32768);
96
413
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, mask_off);
97
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
414
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_AREG0, table_off);
98
fold_setcond_tst_pow2(ctx, op, false);
415
99
416
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
100
ctx->z_mask = 1;
417
index XXXXXXX..XXXXXXX 100644
101
- ctx->s_mask = smask_from_zmask(1);
418
--- a/tcg/riscv/tcg-target.c.inc
102
return false;
419
+++ b/tcg/riscv/tcg-target.c.inc
420
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
421
return true;
422
}
103
}
423
104
424
+/* We expect to use a 12-bit negative offset from ENV. */
105
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
425
+#define MIN_TLB_MASK_TABLE_OFS -(1 << 11)
106
}
426
+
107
427
/*
108
ctx->z_mask = 1;
428
* For softmmu, perform the TLB load and compare.
109
- ctx->s_mask = smask_from_zmask(1);
429
* For useronly, perform any required alignment tests.
110
return false;
430
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
111
431
unsigned s_bits = opc & MO_SIZE;
112
do_setcond_const:
432
unsigned s_mask = (1u << s_bits) - 1;
113
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_ld(OptContext *ctx, TCGOp *op)
433
int mem_index = get_mmuidx(oi);
114
break;
434
- int fast_ofs = TLB_MASK_TABLE_OFS(mem_index);
115
CASE_OP_32_64(ld8u):
435
+ int fast_ofs = tlb_mask_table_ofs(s, mem_index);
116
ctx->z_mask = MAKE_64BIT_MASK(0, 8);
436
int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask);
117
- ctx->s_mask = MAKE_64BIT_MASK(9, 55);
437
int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table);
118
break;
438
int compare_mask;
119
CASE_OP_32_64(ld16s):
439
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
120
ctx->s_mask = MAKE_64BIT_MASK(16, 48);
440
ldst->oi = oi;
121
break;
441
ldst->addrlo_reg = addr_reg;
122
CASE_OP_32_64(ld16u):
442
123
ctx->z_mask = MAKE_64BIT_MASK(0, 16);
443
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
124
- ctx->s_mask = MAKE_64BIT_MASK(17, 47);
444
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11));
125
break;
445
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs);
126
case INDEX_op_ld32s_i64:
446
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs);
127
ctx->s_mask = MAKE_64BIT_MASK(32, 32);
447
128
break;
448
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
129
case INDEX_op_ld32u_i64:
449
index XXXXXXX..XXXXXXX 100644
130
ctx->z_mask = MAKE_64BIT_MASK(0, 32);
450
--- a/tcg/s390x/tcg-target.c.inc
131
- ctx->s_mask = MAKE_64BIT_MASK(33, 31);
451
+++ b/tcg/s390x/tcg-target.c.inc
132
break;
452
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
133
default:
453
return true;
134
g_assert_not_reached();
454
}
455
456
+/* We're expecting to use a 20-bit negative offset on the tlb memory ops. */
457
+#define MIN_TLB_MASK_TABLE_OFS -(1 << 19)
458
+
459
/*
460
* For softmmu, perform the TLB load and compare.
461
* For useronly, perform any required alignment tests.
462
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
463
#ifdef CONFIG_SOFTMMU
464
unsigned s_mask = (1 << s_bits) - 1;
465
int mem_index = get_mmuidx(oi);
466
- int fast_off = TLB_MASK_TABLE_OFS(mem_index);
467
+ int fast_off = tlb_mask_table_ofs(s, mem_index);
468
int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
469
int table_off = fast_off + offsetof(CPUTLBDescFast, table);
470
int ofs, a_off;
471
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
472
tcg_out_sh64(s, RSY_SRLG, TCG_TMP0, addr_reg, TCG_REG_NONE,
473
s->page_bits - CPU_TLB_ENTRY_BITS);
474
475
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
476
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 19));
477
tcg_out_insn(s, RXY, NG, TCG_TMP0, TCG_AREG0, TCG_REG_NONE, mask_off);
478
tcg_out_insn(s, RXY, AG, TCG_TMP0, TCG_AREG0, TCG_REG_NONE, table_off);
479
480
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
481
index XXXXXXX..XXXXXXX 100644
482
--- a/tcg/sparc64/tcg-target.c.inc
483
+++ b/tcg/sparc64/tcg-target.c.inc
484
@@ -XXX,XX +XXX,XX @@ bool tcg_target_has_memory_bswap(MemOp memop)
485
return true;
486
}
487
488
+/* We expect to use a 13-bit negative offset from ENV. */
489
+#define MIN_TLB_MASK_TABLE_OFS -(1 << 12)
490
+
491
/*
492
* For softmmu, perform the TLB load and compare.
493
* For useronly, perform any required alignment tests.
494
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
495
496
#ifdef CONFIG_SOFTMMU
497
int mem_index = get_mmuidx(oi);
498
- int fast_off = TLB_MASK_TABLE_OFS(mem_index);
499
+ int fast_off = tlb_mask_table_ofs(s, mem_index);
500
int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
501
int table_off = fast_off + offsetof(CPUTLBDescFast, table);
502
int cmp_off = is_ld ? offsetof(CPUTLBEntry, addr_read)
503
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
504
int cc;
505
506
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
507
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
508
- QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 12));
509
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_T2, TCG_AREG0, mask_off);
510
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_T3, TCG_AREG0, table_off);
511
512
--
135
--
513
2.34.1
136
2.43.0
514
515
diff view generated by jsdifflib
1
Create tcg/tcg-op-gvec-common.h, moving everything that does not
1
Change the representation from sign bit repetitions to all bits equal
2
concern TARGET_LONG_BITS. Adjust tcg-op-gvec.c to use the new header.
2
to the sign bit, including the sign bit itself.
3
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
23
---
7
include/tcg/tcg-op-gvec-common.h | 426 +++++++++++++++++++++++++++++
24
tcg/optimize.c | 64 ++++++++++++--------------------------------------
8
include/tcg/tcg-op-gvec.h | 444 +------------------------------
25
1 file changed, 15 insertions(+), 49 deletions(-)
9
tcg/tcg-op-gvec.c | 2 +-
10
3 files changed, 437 insertions(+), 435 deletions(-)
11
create mode 100644 include/tcg/tcg-op-gvec-common.h
12
26
13
diff --git a/include/tcg/tcg-op-gvec-common.h b/include/tcg/tcg-op-gvec-common.h
27
diff --git a/tcg/optimize.c b/tcg/optimize.c
14
new file mode 100644
15
index XXXXXXX..XXXXXXX
16
--- /dev/null
17
+++ b/include/tcg/tcg-op-gvec-common.h
18
@@ -XXX,XX +XXX,XX @@
19
+/* SPDX-License-Identifier: GPL-2.0-or-later */
20
+/*
21
+ * Target independent generic vector operation expansion
22
+ *
23
+ * Copyright (c) 2018 Linaro
24
+ */
25
+
26
+#ifndef TCG_TCG_OP_GVEC_COMMON_H
27
+#define TCG_TCG_OP_GVEC_COMMON_H
28
+
29
+/*
30
+ * "Generic" vectors. All operands are given as offsets from ENV,
31
+ * and therefore cannot also be allocated via tcg_global_mem_new_*.
32
+ * OPRSZ is the byte size of the vector upon which the operation is performed.
33
+ * MAXSZ is the byte size of the full vector; bytes beyond OPSZ are cleared.
34
+ *
35
+ * All sizes must be 8 or any multiple of 16.
36
+ * When OPRSZ is 8, the alignment may be 8, otherwise must be 16.
37
+ * Operands may completely, but not partially, overlap.
38
+ */
39
+
40
+/* Expand a call to a gvec-style helper, with pointers to two vector
41
+ operands, and a descriptor (see tcg-gvec-desc.h). */
42
+typedef void gen_helper_gvec_2(TCGv_ptr, TCGv_ptr, TCGv_i32);
43
+void tcg_gen_gvec_2_ool(uint32_t dofs, uint32_t aofs,
44
+ uint32_t oprsz, uint32_t maxsz, int32_t data,
45
+ gen_helper_gvec_2 *fn);
46
+
47
+/* Similarly, passing an extra data value. */
48
+typedef void gen_helper_gvec_2i(TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i32);
49
+void tcg_gen_gvec_2i_ool(uint32_t dofs, uint32_t aofs, TCGv_i64 c,
50
+ uint32_t oprsz, uint32_t maxsz, int32_t data,
51
+ gen_helper_gvec_2i *fn);
52
+
53
+/* Similarly, passing an extra pointer (e.g. env or float_status). */
54
+typedef void gen_helper_gvec_2_ptr(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
55
+void tcg_gen_gvec_2_ptr(uint32_t dofs, uint32_t aofs,
56
+ TCGv_ptr ptr, uint32_t oprsz, uint32_t maxsz,
57
+ int32_t data, gen_helper_gvec_2_ptr *fn);
58
+
59
+/* Similarly, with three vector operands. */
60
+typedef void gen_helper_gvec_3(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
61
+void tcg_gen_gvec_3_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
62
+ uint32_t oprsz, uint32_t maxsz, int32_t data,
63
+ gen_helper_gvec_3 *fn);
64
+
65
+/* Similarly, with four vector operands. */
66
+typedef void gen_helper_gvec_4(TCGv_ptr, TCGv_ptr, TCGv_ptr,
67
+ TCGv_ptr, TCGv_i32);
68
+void tcg_gen_gvec_4_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
69
+ uint32_t cofs, uint32_t oprsz, uint32_t maxsz,
70
+ int32_t data, gen_helper_gvec_4 *fn);
71
+
72
+/* Similarly, with five vector operands. */
73
+typedef void gen_helper_gvec_5(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr,
74
+ TCGv_ptr, TCGv_i32);
75
+void tcg_gen_gvec_5_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
76
+ uint32_t cofs, uint32_t xofs, uint32_t oprsz,
77
+ uint32_t maxsz, int32_t data, gen_helper_gvec_5 *fn);
78
+
79
+typedef void gen_helper_gvec_3_ptr(TCGv_ptr, TCGv_ptr, TCGv_ptr,
80
+ TCGv_ptr, TCGv_i32);
81
+void tcg_gen_gvec_3_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
82
+ TCGv_ptr ptr, uint32_t oprsz, uint32_t maxsz,
83
+ int32_t data, gen_helper_gvec_3_ptr *fn);
84
+
85
+typedef void gen_helper_gvec_4_ptr(TCGv_ptr, TCGv_ptr, TCGv_ptr,
86
+ TCGv_ptr, TCGv_ptr, TCGv_i32);
87
+void tcg_gen_gvec_4_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
88
+ uint32_t cofs, TCGv_ptr ptr, uint32_t oprsz,
89
+ uint32_t maxsz, int32_t data,
90
+ gen_helper_gvec_4_ptr *fn);
91
+
92
+typedef void gen_helper_gvec_5_ptr(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr,
93
+ TCGv_ptr, TCGv_ptr, TCGv_i32);
94
+void tcg_gen_gvec_5_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
95
+ uint32_t cofs, uint32_t eofs, TCGv_ptr ptr,
96
+ uint32_t oprsz, uint32_t maxsz, int32_t data,
97
+ gen_helper_gvec_5_ptr *fn);
98
+
99
+/* Expand a gvec operation. Either inline or out-of-line depending on
100
+ the actual vector size and the operations supported by the host. */
101
+typedef struct {
102
+ /* Expand inline as a 64-bit or 32-bit integer.
103
+ Only one of these will be non-NULL. */
104
+ void (*fni8)(TCGv_i64, TCGv_i64);
105
+ void (*fni4)(TCGv_i32, TCGv_i32);
106
+ /* Expand inline with a host vector type. */
107
+ void (*fniv)(unsigned, TCGv_vec, TCGv_vec);
108
+ /* Expand out-of-line helper w/descriptor. */
109
+ gen_helper_gvec_2 *fno;
110
+ /* The optional opcodes, if any, utilized by .fniv. */
111
+ const TCGOpcode *opt_opc;
112
+ /* The data argument to the out-of-line helper. */
113
+ int32_t data;
114
+ /* The vector element size, if applicable. */
115
+ uint8_t vece;
116
+ /* Prefer i64 to v64. */
117
+ bool prefer_i64;
118
+ /* Load dest as a 2nd source operand. */
119
+ bool load_dest;
120
+} GVecGen2;
121
+
122
+typedef struct {
123
+ /* Expand inline as a 64-bit or 32-bit integer.
124
+ Only one of these will be non-NULL. */
125
+ void (*fni8)(TCGv_i64, TCGv_i64, int64_t);
126
+ void (*fni4)(TCGv_i32, TCGv_i32, int32_t);
127
+ /* Expand inline with a host vector type. */
128
+ void (*fniv)(unsigned, TCGv_vec, TCGv_vec, int64_t);
129
+ /* Expand out-of-line helper w/descriptor, data in descriptor. */
130
+ gen_helper_gvec_2 *fno;
131
+ /* Expand out-of-line helper w/descriptor, data as argument. */
132
+ gen_helper_gvec_2i *fnoi;
133
+ /* The optional opcodes, if any, utilized by .fniv. */
134
+ const TCGOpcode *opt_opc;
135
+ /* The vector element size, if applicable. */
136
+ uint8_t vece;
137
+ /* Prefer i64 to v64. */
138
+ bool prefer_i64;
139
+ /* Load dest as a 3rd source operand. */
140
+ bool load_dest;
141
+} GVecGen2i;
142
+
143
+typedef struct {
144
+ /* Expand inline as a 64-bit or 32-bit integer.
145
+ Only one of these will be non-NULL. */
146
+ void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64);
147
+ void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32);
148
+ /* Expand inline with a host vector type. */
149
+ void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec);
150
+ /* Expand out-of-line helper w/descriptor. */
151
+ gen_helper_gvec_2i *fno;
152
+ /* The optional opcodes, if any, utilized by .fniv. */
153
+ const TCGOpcode *opt_opc;
154
+ /* The data argument to the out-of-line helper. */
155
+ uint32_t data;
156
+ /* The vector element size, if applicable. */
157
+ uint8_t vece;
158
+ /* Prefer i64 to v64. */
159
+ bool prefer_i64;
160
+ /* Load scalar as 1st source operand. */
161
+ bool scalar_first;
162
+} GVecGen2s;
163
+
164
+typedef struct {
165
+ /* Expand inline as a 64-bit or 32-bit integer.
166
+ Only one of these will be non-NULL. */
167
+ void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64);
168
+ void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32);
169
+ /* Expand inline with a host vector type. */
170
+ void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec);
171
+ /* Expand out-of-line helper w/descriptor. */
172
+ gen_helper_gvec_3 *fno;
173
+ /* The optional opcodes, if any, utilized by .fniv. */
174
+ const TCGOpcode *opt_opc;
175
+ /* The data argument to the out-of-line helper. */
176
+ int32_t data;
177
+ /* The vector element size, if applicable. */
178
+ uint8_t vece;
179
+ /* Prefer i64 to v64. */
180
+ bool prefer_i64;
181
+ /* Load dest as a 3rd source operand. */
182
+ bool load_dest;
183
+} GVecGen3;
184
+
185
+typedef struct {
186
+ /*
187
+ * Expand inline as a 64-bit or 32-bit integer. Only one of these will be
188
+ * non-NULL.
189
+ */
190
+ void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64, int64_t);
191
+ void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32, int32_t);
192
+ /* Expand inline with a host vector type. */
193
+ void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec, int64_t);
194
+ /* Expand out-of-line helper w/descriptor, data in descriptor. */
195
+ gen_helper_gvec_3 *fno;
196
+ /* The optional opcodes, if any, utilized by .fniv. */
197
+ const TCGOpcode *opt_opc;
198
+ /* The vector element size, if applicable. */
199
+ uint8_t vece;
200
+ /* Prefer i64 to v64. */
201
+ bool prefer_i64;
202
+ /* Load dest as a 3rd source operand. */
203
+ bool load_dest;
204
+} GVecGen3i;
205
+
206
+typedef struct {
207
+ /* Expand inline as a 64-bit or 32-bit integer.
208
+ Only one of these will be non-NULL. */
209
+ void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64);
210
+ void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32);
211
+ /* Expand inline with a host vector type. */
212
+ void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec, TCGv_vec);
213
+ /* Expand out-of-line helper w/descriptor. */
214
+ gen_helper_gvec_4 *fno;
215
+ /* The optional opcodes, if any, utilized by .fniv. */
216
+ const TCGOpcode *opt_opc;
217
+ /* The data argument to the out-of-line helper. */
218
+ int32_t data;
219
+ /* The vector element size, if applicable. */
220
+ uint8_t vece;
221
+ /* Prefer i64 to v64. */
222
+ bool prefer_i64;
223
+ /* Write aofs as a 2nd dest operand. */
224
+ bool write_aofs;
225
+} GVecGen4;
226
+
227
+typedef struct {
228
+ /*
229
+ * Expand inline as a 64-bit or 32-bit integer. Only one of these will be
230
+ * non-NULL.
231
+ */
232
+ void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64, int64_t);
233
+ void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32, int32_t);
234
+ /* Expand inline with a host vector type. */
235
+ void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec, TCGv_vec, int64_t);
236
+ /* Expand out-of-line helper w/descriptor, data in descriptor. */
237
+ gen_helper_gvec_4 *fno;
238
+ /* The optional opcodes, if any, utilized by .fniv. */
239
+ const TCGOpcode *opt_opc;
240
+ /* The vector element size, if applicable. */
241
+ uint8_t vece;
242
+ /* Prefer i64 to v64. */
243
+ bool prefer_i64;
244
+} GVecGen4i;
245
+
246
+void tcg_gen_gvec_2(uint32_t dofs, uint32_t aofs,
247
+ uint32_t oprsz, uint32_t maxsz, const GVecGen2 *);
248
+void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
249
+ uint32_t maxsz, int64_t c, const GVecGen2i *);
250
+void tcg_gen_gvec_2s(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
251
+ uint32_t maxsz, TCGv_i64 c, const GVecGen2s *);
252
+void tcg_gen_gvec_3(uint32_t dofs, uint32_t aofs, uint32_t bofs,
253
+ uint32_t oprsz, uint32_t maxsz, const GVecGen3 *);
254
+void tcg_gen_gvec_3i(uint32_t dofs, uint32_t aofs, uint32_t bofs,
255
+ uint32_t oprsz, uint32_t maxsz, int64_t c,
256
+ const GVecGen3i *);
257
+void tcg_gen_gvec_4(uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t cofs,
258
+ uint32_t oprsz, uint32_t maxsz, const GVecGen4 *);
259
+void tcg_gen_gvec_4i(uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t cofs,
260
+ uint32_t oprsz, uint32_t maxsz, int64_t c,
261
+ const GVecGen4i *);
262
+
263
+/* Expand a specific vector operation. */
264
+
265
+void tcg_gen_gvec_mov(unsigned vece, uint32_t dofs, uint32_t aofs,
266
+ uint32_t oprsz, uint32_t maxsz);
267
+void tcg_gen_gvec_not(unsigned vece, uint32_t dofs, uint32_t aofs,
268
+ uint32_t oprsz, uint32_t maxsz);
269
+void tcg_gen_gvec_neg(unsigned vece, uint32_t dofs, uint32_t aofs,
270
+ uint32_t oprsz, uint32_t maxsz);
271
+void tcg_gen_gvec_abs(unsigned vece, uint32_t dofs, uint32_t aofs,
272
+ uint32_t oprsz, uint32_t maxsz);
273
+
274
+void tcg_gen_gvec_add(unsigned vece, uint32_t dofs, uint32_t aofs,
275
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
276
+void tcg_gen_gvec_sub(unsigned vece, uint32_t dofs, uint32_t aofs,
277
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
278
+void tcg_gen_gvec_mul(unsigned vece, uint32_t dofs, uint32_t aofs,
279
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
280
+
281
+void tcg_gen_gvec_addi(unsigned vece, uint32_t dofs, uint32_t aofs,
282
+ int64_t c, uint32_t oprsz, uint32_t maxsz);
283
+void tcg_gen_gvec_muli(unsigned vece, uint32_t dofs, uint32_t aofs,
284
+ int64_t c, uint32_t oprsz, uint32_t maxsz);
285
+
286
+void tcg_gen_gvec_adds(unsigned vece, uint32_t dofs, uint32_t aofs,
287
+ TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
288
+void tcg_gen_gvec_subs(unsigned vece, uint32_t dofs, uint32_t aofs,
289
+ TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
290
+void tcg_gen_gvec_muls(unsigned vece, uint32_t dofs, uint32_t aofs,
291
+ TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
292
+
293
+/* Saturated arithmetic. */
294
+void tcg_gen_gvec_ssadd(unsigned vece, uint32_t dofs, uint32_t aofs,
295
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
296
+void tcg_gen_gvec_sssub(unsigned vece, uint32_t dofs, uint32_t aofs,
297
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
298
+void tcg_gen_gvec_usadd(unsigned vece, uint32_t dofs, uint32_t aofs,
299
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
300
+void tcg_gen_gvec_ussub(unsigned vece, uint32_t dofs, uint32_t aofs,
301
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
302
+
303
+/* Min/max. */
304
+void tcg_gen_gvec_smin(unsigned vece, uint32_t dofs, uint32_t aofs,
305
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
306
+void tcg_gen_gvec_umin(unsigned vece, uint32_t dofs, uint32_t aofs,
307
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
308
+void tcg_gen_gvec_smax(unsigned vece, uint32_t dofs, uint32_t aofs,
309
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
310
+void tcg_gen_gvec_umax(unsigned vece, uint32_t dofs, uint32_t aofs,
311
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
312
+
313
+void tcg_gen_gvec_and(unsigned vece, uint32_t dofs, uint32_t aofs,
314
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
315
+void tcg_gen_gvec_or(unsigned vece, uint32_t dofs, uint32_t aofs,
316
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
317
+void tcg_gen_gvec_xor(unsigned vece, uint32_t dofs, uint32_t aofs,
318
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
319
+void tcg_gen_gvec_andc(unsigned vece, uint32_t dofs, uint32_t aofs,
320
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
321
+void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs,
322
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
323
+void tcg_gen_gvec_nand(unsigned vece, uint32_t dofs, uint32_t aofs,
324
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
325
+void tcg_gen_gvec_nor(unsigned vece, uint32_t dofs, uint32_t aofs,
326
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
327
+void tcg_gen_gvec_eqv(unsigned vece, uint32_t dofs, uint32_t aofs,
328
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
329
+
330
+void tcg_gen_gvec_andi(unsigned vece, uint32_t dofs, uint32_t aofs,
331
+ int64_t c, uint32_t oprsz, uint32_t maxsz);
332
+void tcg_gen_gvec_xori(unsigned vece, uint32_t dofs, uint32_t aofs,
333
+ int64_t c, uint32_t oprsz, uint32_t maxsz);
334
+void tcg_gen_gvec_ori(unsigned vece, uint32_t dofs, uint32_t aofs,
335
+ int64_t c, uint32_t oprsz, uint32_t maxsz);
336
+
337
+void tcg_gen_gvec_ands(unsigned vece, uint32_t dofs, uint32_t aofs,
338
+ TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
339
+void tcg_gen_gvec_andcs(unsigned vece, uint32_t dofs, uint32_t aofs,
340
+ TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
341
+void tcg_gen_gvec_xors(unsigned vece, uint32_t dofs, uint32_t aofs,
342
+ TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
343
+void tcg_gen_gvec_ors(unsigned vece, uint32_t dofs, uint32_t aofs,
344
+ TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
345
+
346
+void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, uint32_t aofs,
347
+ uint32_t s, uint32_t m);
348
+void tcg_gen_gvec_dup_imm(unsigned vece, uint32_t dofs, uint32_t s,
349
+ uint32_t m, uint64_t imm);
350
+void tcg_gen_gvec_dup_i32(unsigned vece, uint32_t dofs, uint32_t s,
351
+ uint32_t m, TCGv_i32);
352
+void tcg_gen_gvec_dup_i64(unsigned vece, uint32_t dofs, uint32_t s,
353
+ uint32_t m, TCGv_i64);
354
+
355
+void tcg_gen_gvec_shli(unsigned vece, uint32_t dofs, uint32_t aofs,
356
+ int64_t shift, uint32_t oprsz, uint32_t maxsz);
357
+void tcg_gen_gvec_shri(unsigned vece, uint32_t dofs, uint32_t aofs,
358
+ int64_t shift, uint32_t oprsz, uint32_t maxsz);
359
+void tcg_gen_gvec_sari(unsigned vece, uint32_t dofs, uint32_t aofs,
360
+ int64_t shift, uint32_t oprsz, uint32_t maxsz);
361
+void tcg_gen_gvec_rotli(unsigned vece, uint32_t dofs, uint32_t aofs,
362
+ int64_t shift, uint32_t oprsz, uint32_t maxsz);
363
+void tcg_gen_gvec_rotri(unsigned vece, uint32_t dofs, uint32_t aofs,
364
+ int64_t shift, uint32_t oprsz, uint32_t maxsz);
365
+
366
+void tcg_gen_gvec_shls(unsigned vece, uint32_t dofs, uint32_t aofs,
367
+ TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
368
+void tcg_gen_gvec_shrs(unsigned vece, uint32_t dofs, uint32_t aofs,
369
+ TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
370
+void tcg_gen_gvec_sars(unsigned vece, uint32_t dofs, uint32_t aofs,
371
+ TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
372
+void tcg_gen_gvec_rotls(unsigned vece, uint32_t dofs, uint32_t aofs,
373
+ TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
374
+void tcg_gen_gvec_rotrs(unsigned vece, uint32_t dofs, uint32_t aofs,
375
+ TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
376
+
377
+/*
378
+ * Perform vector shift by vector element, modulo the element size.
379
+ * E.g. D[i] = A[i] << (B[i] % (8 << vece)).
380
+ */
381
+void tcg_gen_gvec_shlv(unsigned vece, uint32_t dofs, uint32_t aofs,
382
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
383
+void tcg_gen_gvec_shrv(unsigned vece, uint32_t dofs, uint32_t aofs,
384
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
385
+void tcg_gen_gvec_sarv(unsigned vece, uint32_t dofs, uint32_t aofs,
386
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
387
+void tcg_gen_gvec_rotlv(unsigned vece, uint32_t dofs, uint32_t aofs,
388
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
389
+void tcg_gen_gvec_rotrv(unsigned vece, uint32_t dofs, uint32_t aofs,
390
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
391
+
392
+void tcg_gen_gvec_cmp(TCGCond cond, unsigned vece, uint32_t dofs,
393
+ uint32_t aofs, uint32_t bofs,
394
+ uint32_t oprsz, uint32_t maxsz);
395
+
396
+/*
397
+ * Perform vector bit select: d = (b & a) | (c & ~a).
398
+ */
399
+void tcg_gen_gvec_bitsel(unsigned vece, uint32_t dofs, uint32_t aofs,
400
+ uint32_t bofs, uint32_t cofs,
401
+ uint32_t oprsz, uint32_t maxsz);
402
+
403
+/*
404
+ * 64-bit vector operations. Use these when the register has been allocated
405
+ * with tcg_global_mem_new_i64, and so we cannot also address it via pointer.
406
+ * OPRSZ = MAXSZ = 8.
407
+ */
408
+
409
+void tcg_gen_vec_neg8_i64(TCGv_i64 d, TCGv_i64 a);
410
+void tcg_gen_vec_neg16_i64(TCGv_i64 d, TCGv_i64 a);
411
+void tcg_gen_vec_neg32_i64(TCGv_i64 d, TCGv_i64 a);
412
+
413
+void tcg_gen_vec_add8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
414
+void tcg_gen_vec_add16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
415
+void tcg_gen_vec_add32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
416
+
417
+void tcg_gen_vec_sub8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
418
+void tcg_gen_vec_sub16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
419
+void tcg_gen_vec_sub32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
420
+
421
+void tcg_gen_vec_shl8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
422
+void tcg_gen_vec_shl16i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
423
+void tcg_gen_vec_shr8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
424
+void tcg_gen_vec_shr16i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
425
+void tcg_gen_vec_sar8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
426
+void tcg_gen_vec_sar16i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
427
+void tcg_gen_vec_rotl8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t c);
428
+void tcg_gen_vec_rotl16i_i64(TCGv_i64 d, TCGv_i64 a, int64_t c);
429
+
430
+/* 32-bit vector operations. */
431
+void tcg_gen_vec_add8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
432
+void tcg_gen_vec_add16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
433
+
434
+void tcg_gen_vec_sub8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
435
+void tcg_gen_vec_sub16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
436
+
437
+void tcg_gen_vec_shl8i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
438
+void tcg_gen_vec_shl16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
439
+void tcg_gen_vec_shr8i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
440
+void tcg_gen_vec_shr16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
441
+void tcg_gen_vec_sar8i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
442
+void tcg_gen_vec_sar16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
443
+
444
+#endif
445
diff --git a/include/tcg/tcg-op-gvec.h b/include/tcg/tcg-op-gvec.h
446
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
447
--- a/include/tcg/tcg-op-gvec.h
29
--- a/tcg/optimize.c
448
+++ b/include/tcg/tcg-op-gvec.h
30
+++ b/tcg/optimize.c
449
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@ typedef struct TempOptInfo {
450
+/* SPDX-License-Identifier: GPL-2.0-or-later */
32
QSIMPLEQ_HEAD(, MemCopyInfo) mem_copy;
451
/*
33
uint64_t val;
452
- * Generic vector operation expansion
34
uint64_t z_mask; /* mask bit is 0 if and only if value bit is 0 */
453
+ * Target dependent generic vector operation expansion
35
- uint64_t s_mask; /* a left-aligned mask of clrsb(value) bits. */
454
*
36
+ uint64_t s_mask; /* mask bit is 1 if value bit matches msb */
455
* Copyright (c) 2018 Linaro
37
} TempOptInfo;
456
- *
38
457
- * This library is free software; you can redistribute it and/or
39
typedef struct OptContext {
458
- * modify it under the terms of the GNU Lesser General Public
40
@@ -XXX,XX +XXX,XX @@ typedef struct OptContext {
459
- * License as published by the Free Software Foundation; either
41
460
- * version 2.1 of the License, or (at your option) any later version.
42
/* In flight values from optimization. */
461
- *
43
uint64_t z_mask; /* mask bit is 0 iff value bit is 0 */
462
- * This library is distributed in the hope that it will be useful,
44
- uint64_t s_mask; /* mask of clrsb(value) bits */
463
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
45
+ uint64_t s_mask; /* mask bit is 1 if value bit matches msb */
464
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
46
TCGType type;
465
- * Lesser General Public License for more details.
47
} OptContext;
466
- *
48
467
- * You should have received a copy of the GNU Lesser General Public
49
-/* Calculate the smask for a specific value. */
468
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
50
-static uint64_t smask_from_value(uint64_t value)
469
*/
51
-{
470
52
- int rep = clrsb64(value);
471
#ifndef TCG_TCG_OP_GVEC_H
53
- return ~(~0ull >> rep);
472
#define TCG_TCG_OP_GVEC_H
54
-}
473
474
-/*
475
- * "Generic" vectors. All operands are given as offsets from ENV,
476
- * and therefore cannot also be allocated via tcg_global_mem_new_*.
477
- * OPRSZ is the byte size of the vector upon which the operation is performed.
478
- * MAXSZ is the byte size of the full vector; bytes beyond OPSZ are cleared.
479
- *
480
- * All sizes must be 8 or any multiple of 16.
481
- * When OPRSZ is 8, the alignment may be 8, otherwise must be 16.
482
- * Operands may completely, but not partially, overlap.
483
- */
484
+#include "tcg/tcg-op-gvec-common.h"
485
486
-/* Expand a call to a gvec-style helper, with pointers to two vector
487
- operands, and a descriptor (see tcg-gvec-desc.h). */
488
-typedef void gen_helper_gvec_2(TCGv_ptr, TCGv_ptr, TCGv_i32);
489
-void tcg_gen_gvec_2_ool(uint32_t dofs, uint32_t aofs,
490
- uint32_t oprsz, uint32_t maxsz, int32_t data,
491
- gen_helper_gvec_2 *fn);
492
-
493
-/* Similarly, passing an extra data value. */
494
-typedef void gen_helper_gvec_2i(TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i32);
495
-void tcg_gen_gvec_2i_ool(uint32_t dofs, uint32_t aofs, TCGv_i64 c,
496
- uint32_t oprsz, uint32_t maxsz, int32_t data,
497
- gen_helper_gvec_2i *fn);
498
-
499
-/* Similarly, passing an extra pointer (e.g. env or float_status). */
500
-typedef void gen_helper_gvec_2_ptr(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
501
-void tcg_gen_gvec_2_ptr(uint32_t dofs, uint32_t aofs,
502
- TCGv_ptr ptr, uint32_t oprsz, uint32_t maxsz,
503
- int32_t data, gen_helper_gvec_2_ptr *fn);
504
-
505
-/* Similarly, with three vector operands. */
506
-typedef void gen_helper_gvec_3(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
507
-void tcg_gen_gvec_3_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
508
- uint32_t oprsz, uint32_t maxsz, int32_t data,
509
- gen_helper_gvec_3 *fn);
510
-
511
-/* Similarly, with four vector operands. */
512
-typedef void gen_helper_gvec_4(TCGv_ptr, TCGv_ptr, TCGv_ptr,
513
- TCGv_ptr, TCGv_i32);
514
-void tcg_gen_gvec_4_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
515
- uint32_t cofs, uint32_t oprsz, uint32_t maxsz,
516
- int32_t data, gen_helper_gvec_4 *fn);
517
-
518
-/* Similarly, with five vector operands. */
519
-typedef void gen_helper_gvec_5(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr,
520
- TCGv_ptr, TCGv_i32);
521
-void tcg_gen_gvec_5_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
522
- uint32_t cofs, uint32_t xofs, uint32_t oprsz,
523
- uint32_t maxsz, int32_t data, gen_helper_gvec_5 *fn);
524
-
525
-typedef void gen_helper_gvec_3_ptr(TCGv_ptr, TCGv_ptr, TCGv_ptr,
526
- TCGv_ptr, TCGv_i32);
527
-void tcg_gen_gvec_3_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
528
- TCGv_ptr ptr, uint32_t oprsz, uint32_t maxsz,
529
- int32_t data, gen_helper_gvec_3_ptr *fn);
530
-
531
-typedef void gen_helper_gvec_4_ptr(TCGv_ptr, TCGv_ptr, TCGv_ptr,
532
- TCGv_ptr, TCGv_ptr, TCGv_i32);
533
-void tcg_gen_gvec_4_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
534
- uint32_t cofs, TCGv_ptr ptr, uint32_t oprsz,
535
- uint32_t maxsz, int32_t data,
536
- gen_helper_gvec_4_ptr *fn);
537
-
538
-typedef void gen_helper_gvec_5_ptr(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr,
539
- TCGv_ptr, TCGv_ptr, TCGv_i32);
540
-void tcg_gen_gvec_5_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
541
- uint32_t cofs, uint32_t eofs, TCGv_ptr ptr,
542
- uint32_t oprsz, uint32_t maxsz, int32_t data,
543
- gen_helper_gvec_5_ptr *fn);
544
-
545
-/* Expand a gvec operation. Either inline or out-of-line depending on
546
- the actual vector size and the operations supported by the host. */
547
-typedef struct {
548
- /* Expand inline as a 64-bit or 32-bit integer.
549
- Only one of these will be non-NULL. */
550
- void (*fni8)(TCGv_i64, TCGv_i64);
551
- void (*fni4)(TCGv_i32, TCGv_i32);
552
- /* Expand inline with a host vector type. */
553
- void (*fniv)(unsigned, TCGv_vec, TCGv_vec);
554
- /* Expand out-of-line helper w/descriptor. */
555
- gen_helper_gvec_2 *fno;
556
- /* The optional opcodes, if any, utilized by .fniv. */
557
- const TCGOpcode *opt_opc;
558
- /* The data argument to the out-of-line helper. */
559
- int32_t data;
560
- /* The vector element size, if applicable. */
561
- uint8_t vece;
562
- /* Prefer i64 to v64. */
563
- bool prefer_i64;
564
- /* Load dest as a 2nd source operand. */
565
- bool load_dest;
566
-} GVecGen2;
567
-
568
-typedef struct {
569
- /* Expand inline as a 64-bit or 32-bit integer.
570
- Only one of these will be non-NULL. */
571
- void (*fni8)(TCGv_i64, TCGv_i64, int64_t);
572
- void (*fni4)(TCGv_i32, TCGv_i32, int32_t);
573
- /* Expand inline with a host vector type. */
574
- void (*fniv)(unsigned, TCGv_vec, TCGv_vec, int64_t);
575
- /* Expand out-of-line helper w/descriptor, data in descriptor. */
576
- gen_helper_gvec_2 *fno;
577
- /* Expand out-of-line helper w/descriptor, data as argument. */
578
- gen_helper_gvec_2i *fnoi;
579
- /* The optional opcodes, if any, utilized by .fniv. */
580
- const TCGOpcode *opt_opc;
581
- /* The vector element size, if applicable. */
582
- uint8_t vece;
583
- /* Prefer i64 to v64. */
584
- bool prefer_i64;
585
- /* Load dest as a 3rd source operand. */
586
- bool load_dest;
587
-} GVecGen2i;
588
-
589
-typedef struct {
590
- /* Expand inline as a 64-bit or 32-bit integer.
591
- Only one of these will be non-NULL. */
592
- void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64);
593
- void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32);
594
- /* Expand inline with a host vector type. */
595
- void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec);
596
- /* Expand out-of-line helper w/descriptor. */
597
- gen_helper_gvec_2i *fno;
598
- /* The optional opcodes, if any, utilized by .fniv. */
599
- const TCGOpcode *opt_opc;
600
- /* The data argument to the out-of-line helper. */
601
- uint32_t data;
602
- /* The vector element size, if applicable. */
603
- uint8_t vece;
604
- /* Prefer i64 to v64. */
605
- bool prefer_i64;
606
- /* Load scalar as 1st source operand. */
607
- bool scalar_first;
608
-} GVecGen2s;
609
-
610
-typedef struct {
611
- /* Expand inline as a 64-bit or 32-bit integer.
612
- Only one of these will be non-NULL. */
613
- void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64);
614
- void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32);
615
- /* Expand inline with a host vector type. */
616
- void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec);
617
- /* Expand out-of-line helper w/descriptor. */
618
- gen_helper_gvec_3 *fno;
619
- /* The optional opcodes, if any, utilized by .fniv. */
620
- const TCGOpcode *opt_opc;
621
- /* The data argument to the out-of-line helper. */
622
- int32_t data;
623
- /* The vector element size, if applicable. */
624
- uint8_t vece;
625
- /* Prefer i64 to v64. */
626
- bool prefer_i64;
627
- /* Load dest as a 3rd source operand. */
628
- bool load_dest;
629
-} GVecGen3;
630
-
631
-typedef struct {
632
- /*
633
- * Expand inline as a 64-bit or 32-bit integer. Only one of these will be
634
- * non-NULL.
635
- */
636
- void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64, int64_t);
637
- void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32, int32_t);
638
- /* Expand inline with a host vector type. */
639
- void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec, int64_t);
640
- /* Expand out-of-line helper w/descriptor, data in descriptor. */
641
- gen_helper_gvec_3 *fno;
642
- /* The optional opcodes, if any, utilized by .fniv. */
643
- const TCGOpcode *opt_opc;
644
- /* The vector element size, if applicable. */
645
- uint8_t vece;
646
- /* Prefer i64 to v64. */
647
- bool prefer_i64;
648
- /* Load dest as a 3rd source operand. */
649
- bool load_dest;
650
-} GVecGen3i;
651
-
652
-typedef struct {
653
- /* Expand inline as a 64-bit or 32-bit integer.
654
- Only one of these will be non-NULL. */
655
- void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64);
656
- void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32);
657
- /* Expand inline with a host vector type. */
658
- void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec, TCGv_vec);
659
- /* Expand out-of-line helper w/descriptor. */
660
- gen_helper_gvec_4 *fno;
661
- /* The optional opcodes, if any, utilized by .fniv. */
662
- const TCGOpcode *opt_opc;
663
- /* The data argument to the out-of-line helper. */
664
- int32_t data;
665
- /* The vector element size, if applicable. */
666
- uint8_t vece;
667
- /* Prefer i64 to v64. */
668
- bool prefer_i64;
669
- /* Write aofs as a 2nd dest operand. */
670
- bool write_aofs;
671
-} GVecGen4;
672
-
673
-typedef struct {
674
- /*
675
- * Expand inline as a 64-bit or 32-bit integer. Only one of these will be
676
- * non-NULL.
677
- */
678
- void (*fni8)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64, int64_t);
679
- void (*fni4)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32, int32_t);
680
- /* Expand inline with a host vector type. */
681
- void (*fniv)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec, TCGv_vec, int64_t);
682
- /* Expand out-of-line helper w/descriptor, data in descriptor. */
683
- gen_helper_gvec_4 *fno;
684
- /* The optional opcodes, if any, utilized by .fniv. */
685
- const TCGOpcode *opt_opc;
686
- /* The vector element size, if applicable. */
687
- uint8_t vece;
688
- /* Prefer i64 to v64. */
689
- bool prefer_i64;
690
-} GVecGen4i;
691
-
692
-void tcg_gen_gvec_2(uint32_t dofs, uint32_t aofs,
693
- uint32_t oprsz, uint32_t maxsz, const GVecGen2 *);
694
-void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
695
- uint32_t maxsz, int64_t c, const GVecGen2i *);
696
-void tcg_gen_gvec_2s(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
697
- uint32_t maxsz, TCGv_i64 c, const GVecGen2s *);
698
-void tcg_gen_gvec_3(uint32_t dofs, uint32_t aofs, uint32_t bofs,
699
- uint32_t oprsz, uint32_t maxsz, const GVecGen3 *);
700
-void tcg_gen_gvec_3i(uint32_t dofs, uint32_t aofs, uint32_t bofs,
701
- uint32_t oprsz, uint32_t maxsz, int64_t c,
702
- const GVecGen3i *);
703
-void tcg_gen_gvec_4(uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t cofs,
704
- uint32_t oprsz, uint32_t maxsz, const GVecGen4 *);
705
-void tcg_gen_gvec_4i(uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t cofs,
706
- uint32_t oprsz, uint32_t maxsz, int64_t c,
707
- const GVecGen4i *);
708
-
709
-/* Expand a specific vector operation. */
710
-
711
-void tcg_gen_gvec_mov(unsigned vece, uint32_t dofs, uint32_t aofs,
712
- uint32_t oprsz, uint32_t maxsz);
713
-void tcg_gen_gvec_not(unsigned vece, uint32_t dofs, uint32_t aofs,
714
- uint32_t oprsz, uint32_t maxsz);
715
-void tcg_gen_gvec_neg(unsigned vece, uint32_t dofs, uint32_t aofs,
716
- uint32_t oprsz, uint32_t maxsz);
717
-void tcg_gen_gvec_abs(unsigned vece, uint32_t dofs, uint32_t aofs,
718
- uint32_t oprsz, uint32_t maxsz);
719
-
720
-void tcg_gen_gvec_add(unsigned vece, uint32_t dofs, uint32_t aofs,
721
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
722
-void tcg_gen_gvec_sub(unsigned vece, uint32_t dofs, uint32_t aofs,
723
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
724
-void tcg_gen_gvec_mul(unsigned vece, uint32_t dofs, uint32_t aofs,
725
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
726
-
727
-void tcg_gen_gvec_addi(unsigned vece, uint32_t dofs, uint32_t aofs,
728
- int64_t c, uint32_t oprsz, uint32_t maxsz);
729
-void tcg_gen_gvec_muli(unsigned vece, uint32_t dofs, uint32_t aofs,
730
- int64_t c, uint32_t oprsz, uint32_t maxsz);
731
-
732
-void tcg_gen_gvec_adds(unsigned vece, uint32_t dofs, uint32_t aofs,
733
- TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
734
-void tcg_gen_gvec_subs(unsigned vece, uint32_t dofs, uint32_t aofs,
735
- TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
736
-void tcg_gen_gvec_muls(unsigned vece, uint32_t dofs, uint32_t aofs,
737
- TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
738
-
739
-/* Saturated arithmetic. */
740
-void tcg_gen_gvec_ssadd(unsigned vece, uint32_t dofs, uint32_t aofs,
741
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
742
-void tcg_gen_gvec_sssub(unsigned vece, uint32_t dofs, uint32_t aofs,
743
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
744
-void tcg_gen_gvec_usadd(unsigned vece, uint32_t dofs, uint32_t aofs,
745
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
746
-void tcg_gen_gvec_ussub(unsigned vece, uint32_t dofs, uint32_t aofs,
747
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
748
-
749
-/* Min/max. */
750
-void tcg_gen_gvec_smin(unsigned vece, uint32_t dofs, uint32_t aofs,
751
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
752
-void tcg_gen_gvec_umin(unsigned vece, uint32_t dofs, uint32_t aofs,
753
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
754
-void tcg_gen_gvec_smax(unsigned vece, uint32_t dofs, uint32_t aofs,
755
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
756
-void tcg_gen_gvec_umax(unsigned vece, uint32_t dofs, uint32_t aofs,
757
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
758
-
759
-void tcg_gen_gvec_and(unsigned vece, uint32_t dofs, uint32_t aofs,
760
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
761
-void tcg_gen_gvec_or(unsigned vece, uint32_t dofs, uint32_t aofs,
762
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
763
-void tcg_gen_gvec_xor(unsigned vece, uint32_t dofs, uint32_t aofs,
764
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
765
-void tcg_gen_gvec_andc(unsigned vece, uint32_t dofs, uint32_t aofs,
766
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
767
-void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs,
768
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
769
-void tcg_gen_gvec_nand(unsigned vece, uint32_t dofs, uint32_t aofs,
770
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
771
-void tcg_gen_gvec_nor(unsigned vece, uint32_t dofs, uint32_t aofs,
772
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
773
-void tcg_gen_gvec_eqv(unsigned vece, uint32_t dofs, uint32_t aofs,
774
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
775
-
776
-void tcg_gen_gvec_andi(unsigned vece, uint32_t dofs, uint32_t aofs,
777
- int64_t c, uint32_t oprsz, uint32_t maxsz);
778
-void tcg_gen_gvec_xori(unsigned vece, uint32_t dofs, uint32_t aofs,
779
- int64_t c, uint32_t oprsz, uint32_t maxsz);
780
-void tcg_gen_gvec_ori(unsigned vece, uint32_t dofs, uint32_t aofs,
781
- int64_t c, uint32_t oprsz, uint32_t maxsz);
782
-
783
-void tcg_gen_gvec_ands(unsigned vece, uint32_t dofs, uint32_t aofs,
784
- TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
785
-void tcg_gen_gvec_andcs(unsigned vece, uint32_t dofs, uint32_t aofs,
786
- TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
787
-void tcg_gen_gvec_xors(unsigned vece, uint32_t dofs, uint32_t aofs,
788
- TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
789
-void tcg_gen_gvec_ors(unsigned vece, uint32_t dofs, uint32_t aofs,
790
- TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
791
-
792
-void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, uint32_t aofs,
793
- uint32_t s, uint32_t m);
794
-void tcg_gen_gvec_dup_imm(unsigned vece, uint32_t dofs, uint32_t s,
795
- uint32_t m, uint64_t imm);
796
-void tcg_gen_gvec_dup_i32(unsigned vece, uint32_t dofs, uint32_t s,
797
- uint32_t m, TCGv_i32);
798
-void tcg_gen_gvec_dup_i64(unsigned vece, uint32_t dofs, uint32_t s,
799
- uint32_t m, TCGv_i64);
800
-
801
-#if TARGET_LONG_BITS == 64
802
-# define tcg_gen_gvec_dup_tl tcg_gen_gvec_dup_i64
803
-#else
804
-# define tcg_gen_gvec_dup_tl tcg_gen_gvec_dup_i32
805
+#ifndef TARGET_LONG_BITS
806
+#error must include QEMU headers
807
#endif
808
809
-void tcg_gen_gvec_shli(unsigned vece, uint32_t dofs, uint32_t aofs,
810
- int64_t shift, uint32_t oprsz, uint32_t maxsz);
811
-void tcg_gen_gvec_shri(unsigned vece, uint32_t dofs, uint32_t aofs,
812
- int64_t shift, uint32_t oprsz, uint32_t maxsz);
813
-void tcg_gen_gvec_sari(unsigned vece, uint32_t dofs, uint32_t aofs,
814
- int64_t shift, uint32_t oprsz, uint32_t maxsz);
815
-void tcg_gen_gvec_rotli(unsigned vece, uint32_t dofs, uint32_t aofs,
816
- int64_t shift, uint32_t oprsz, uint32_t maxsz);
817
-void tcg_gen_gvec_rotri(unsigned vece, uint32_t dofs, uint32_t aofs,
818
- int64_t shift, uint32_t oprsz, uint32_t maxsz);
819
-
820
-void tcg_gen_gvec_shls(unsigned vece, uint32_t dofs, uint32_t aofs,
821
- TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
822
-void tcg_gen_gvec_shrs(unsigned vece, uint32_t dofs, uint32_t aofs,
823
- TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
824
-void tcg_gen_gvec_sars(unsigned vece, uint32_t dofs, uint32_t aofs,
825
- TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
826
-void tcg_gen_gvec_rotls(unsigned vece, uint32_t dofs, uint32_t aofs,
827
- TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
828
-void tcg_gen_gvec_rotrs(unsigned vece, uint32_t dofs, uint32_t aofs,
829
- TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
830
-
55
-
831
-/*
56
-/*
832
- * Perform vector shift by vector element, modulo the element size.
57
- * Calculate the smask for a given set of known-zeros.
833
- * E.g. D[i] = A[i] << (B[i] % (8 << vece)).
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.
834
- */
61
- */
835
-void tcg_gen_gvec_shlv(unsigned vece, uint32_t dofs, uint32_t aofs,
62
-static uint64_t smask_from_zmask(uint64_t zmask)
836
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
63
-{
837
-void tcg_gen_gvec_shrv(unsigned vece, uint32_t dofs, uint32_t aofs,
64
- /*
838
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
65
- * Only the 0 bits are significant for zmask, thus the msb itself
839
-void tcg_gen_gvec_sarv(unsigned vece, uint32_t dofs, uint32_t aofs,
66
- * must be zero, else we have no sign information.
840
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
67
- */
841
-void tcg_gen_gvec_rotlv(unsigned vece, uint32_t dofs, uint32_t aofs,
68
- int rep = clz64(zmask);
842
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
69
- if (rep == 0) {
843
-void tcg_gen_gvec_rotrv(unsigned vece, uint32_t dofs, uint32_t aofs,
70
- return 0;
844
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
71
- }
845
-
72
- rep -= 1;
846
-void tcg_gen_gvec_cmp(TCGCond cond, unsigned vece, uint32_t dofs,
73
- return ~(~0ull >> rep);
847
- uint32_t aofs, uint32_t bofs,
74
-}
848
- uint32_t oprsz, uint32_t maxsz);
849
-
75
-
850
-/*
76
-/*
851
- * Perform vector bit select: d = (b & a) | (c & ~a).
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.
852
- */
81
- */
853
-void tcg_gen_gvec_bitsel(unsigned vece, uint32_t dofs, uint32_t aofs,
82
-static uint64_t smask_from_smask(int64_t smask)
854
- uint32_t bofs, uint32_t cofs,
83
-{
855
- uint32_t oprsz, uint32_t maxsz);
84
- /* Only the 1 bits are significant for smask */
85
- return smask_from_zmask(~smask);
86
-}
856
-
87
-
857
-/*
88
static inline TempOptInfo *ts_info(TCGTemp *ts)
858
- * 64-bit vector operations. Use these when the register has been allocated
89
{
859
- * with tcg_global_mem_new_i64, and so we cannot also address it via pointer.
90
return ts->state_ptr;
860
- * OPRSZ = MAXSZ = 8.
91
@@ -XXX,XX +XXX,XX @@ static void init_ts_info(OptContext *ctx, TCGTemp *ts)
861
- */
92
ti->is_const = true;
862
-
93
ti->val = ts->val;
863
-void tcg_gen_vec_neg8_i64(TCGv_i64 d, TCGv_i64 a);
94
ti->z_mask = ts->val;
864
-void tcg_gen_vec_neg16_i64(TCGv_i64 d, TCGv_i64 a);
95
- ti->s_mask = smask_from_value(ts->val);
865
-void tcg_gen_vec_neg32_i64(TCGv_i64 d, TCGv_i64 a);
96
+ ti->s_mask = INT64_MIN >> clrsb64(ts->val);
866
-
97
} else {
867
-void tcg_gen_vec_add8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
98
ti->is_const = false;
868
-void tcg_gen_vec_add16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
99
ti->z_mask = -1;
869
-void tcg_gen_vec_add32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
100
@@ -XXX,XX +XXX,XX @@ static void finish_folding(OptContext *ctx, TCGOp *op)
870
-
101
*/
871
-void tcg_gen_vec_sub8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
102
if (i == 0) {
872
-void tcg_gen_vec_sub16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
103
ts_info(ts)->z_mask = ctx->z_mask;
873
-void tcg_gen_vec_sub32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
104
- ts_info(ts)->s_mask = ctx->s_mask;
874
-
105
}
875
-void tcg_gen_vec_shl8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
106
}
876
-void tcg_gen_vec_shl16i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
107
}
877
-void tcg_gen_vec_shr8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
108
@@ -XXX,XX +XXX,XX @@ static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
878
-void tcg_gen_vec_shr16i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
109
* The passed s_mask may be augmented by z_mask.
879
-void tcg_gen_vec_sar8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
110
*/
880
-void tcg_gen_vec_sar16i_i64(TCGv_i64 d, TCGv_i64 a, int64_t);
111
static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
881
-void tcg_gen_vec_rotl8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t c);
112
- uint64_t z_mask, uint64_t s_mask)
882
-void tcg_gen_vec_rotl16i_i64(TCGv_i64 d, TCGv_i64 a, int64_t c);
113
+ uint64_t z_mask, int64_t s_mask)
883
-
114
{
884
-/* 32-bit vector operations. */
115
const TCGOpDef *def = &tcg_op_defs[op->opc];
885
-void tcg_gen_vec_add8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
116
TCGTemp *ts;
886
-void tcg_gen_vec_add16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
117
TempOptInfo *ti;
887
-
118
+ int rep;
888
-void tcg_gen_vec_sub8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
119
889
-void tcg_gen_vec_sub16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
120
/* Only single-output opcodes are supported here. */
890
-
121
tcg_debug_assert(def->nb_oargs == 1);
891
-void tcg_gen_vec_shl8i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
122
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
892
-void tcg_gen_vec_shl16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
123
*/
893
-void tcg_gen_vec_shr8i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
124
if (ctx->type == TCG_TYPE_I32) {
894
-void tcg_gen_vec_shr16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
125
z_mask = (int32_t)z_mask;
895
-void tcg_gen_vec_sar8i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
126
- s_mask |= MAKE_64BIT_MASK(32, 32);
896
-void tcg_gen_vec_sar16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
127
+ s_mask |= INT32_MIN;
897
-
128
}
898
#if TARGET_LONG_BITS == 64
129
899
+#define tcg_gen_gvec_dup_tl tcg_gen_gvec_dup_i64
130
if (z_mask == 0) {
900
#define tcg_gen_vec_add8_tl tcg_gen_vec_add8_i64
131
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_zs(OptContext *ctx, TCGOp *op,
901
#define tcg_gen_vec_sub8_tl tcg_gen_vec_sub8_i64
132
902
#define tcg_gen_vec_add16_tl tcg_gen_vec_add16_i64
133
ti = ts_info(ts);
903
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_sar16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
134
ti->z_mask = z_mask;
904
#define tcg_gen_vec_shl16i_tl tcg_gen_vec_shl16i_i64
135
- ti->s_mask = s_mask | smask_from_zmask(z_mask);
905
#define tcg_gen_vec_shr16i_tl tcg_gen_vec_shr16i_i64
136
+
906
#define tcg_gen_vec_sar16i_tl tcg_gen_vec_sar16i_i64
137
+ /* Canonicalize s_mask and incorporate data from z_mask. */
907
-
138
+ rep = clz64(~s_mask);
908
-#else
139
+ rep = MAX(rep, clz64(z_mask));
909
+#elif TARGET_LONG_BITS == 32
140
+ rep = MAX(rep - 1, 0);
910
+#define tcg_gen_gvec_dup_tl tcg_gen_gvec_dup_i32
141
+ ti->s_mask = INT64_MIN >> rep;
911
#define tcg_gen_vec_add8_tl tcg_gen_vec_add8_i32
142
+
912
#define tcg_gen_vec_sub8_tl tcg_gen_vec_sub8_i32
143
return true;
913
#define tcg_gen_vec_add16_tl tcg_gen_vec_add16_i32
144
}
914
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_sar16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t);
145
915
#define tcg_gen_vec_shl16i_tl tcg_gen_vec_shl16i_i32
146
@@ -XXX,XX +XXX,XX @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
916
#define tcg_gen_vec_shr16i_tl tcg_gen_vec_shr16i_i32
147
917
#define tcg_gen_vec_sar16i_tl tcg_gen_vec_sar16i_i32
148
ctx->z_mask = z_mask;
918
+#else
149
ctx->s_mask = s_mask;
919
+# error
150
- if (!type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
920
#endif
151
+ if (0 && !type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
921
152
return true;
922
#endif
153
}
923
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
154
924
index XXXXXXX..XXXXXXX 100644
155
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
925
--- a/tcg/tcg-op-gvec.c
156
s_mask |= MAKE_64BIT_MASK(len, 64 - len);
926
+++ b/tcg/tcg-op-gvec.c
157
ctx->s_mask = s_mask;
927
@@ -XXX,XX +XXX,XX @@
158
928
#include "tcg/tcg.h"
159
- if (pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
929
#include "tcg/tcg-temp-internal.h"
160
+ if (0 && pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
930
#include "tcg/tcg-op-common.h"
161
return true;
931
-#include "tcg/tcg-op-gvec.h"
162
}
932
+#include "tcg/tcg-op-gvec-common.h"
163
933
#include "tcg/tcg-gvec-desc.h"
164
@@ -XXX,XX +XXX,XX @@ static bool fold_shift(OptContext *ctx, TCGOp *op)
934
165
ctx->z_mask = do_constant_folding(op->opc, ctx->type, z_mask, sh);
935
#define MAX_UNROLL 4
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);
171
}
936
--
172
--
937
2.34.1
173
2.43.0
938
939
diff view generated by jsdifflib
1
Make tcg_gen_callN a static function. Create tcg_gen_call[0-7]
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
functions for use by helper-gen.h.inc.
3
4
Removes a multiplicty of calls to __stack_chk_fail, saving up
5
to 143kiB of .text space as measured on an x86_64 host.
6
7
Old New Less %Change
8
8888680    8741816    146864    1.65%    qemu-system-aarch64
9
5911832    5856152    55680    0.94%    qemu-system-riscv64
10
5816728    5767512    49216    0.85%    qemu-system-mips64
11
6707832    6659144    48688    0.73%    qemu-system-ppc64
12
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
---
3
---
16
include/exec/helper-gen.h | 40 ++++++++++++++---------------
4
tcg/optimize.c | 9 +++++----
17
include/tcg/tcg.h | 14 +++++++++-
5
1 file changed, 5 insertions(+), 4 deletions(-)
18
tcg/tcg.c | 54 ++++++++++++++++++++++++++++++++++++++-
19
3 files changed, 86 insertions(+), 22 deletions(-)
20
6
21
diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
22
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
23
--- a/include/exec/helper-gen.h
9
--- a/tcg/optimize.c
24
+++ b/include/exec/helper-gen.h
10
+++ b/tcg/optimize.c
25
@@ -XXX,XX +XXX,XX @@
11
@@ -XXX,XX +XXX,XX @@ static void finish_ebb(OptContext *ctx)
26
extern TCGHelperInfo glue(helper_info_, name); \
12
remove_mem_copy_all(ctx);
27
static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
28
{ \
29
- tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 0, NULL); \
30
+ tcg_gen_call0(&glue(helper_info_, name), dh_retvar(ret)); \
31
}
13
}
32
14
33
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
15
-static void finish_folding(OptContext *ctx, TCGOp *op)
34
@@ -XXX,XX +XXX,XX @@ extern TCGHelperInfo glue(helper_info_, name); \
16
+static bool finish_folding(OptContext *ctx, TCGOp *op)
35
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
17
{
36
dh_arg_decl(t1, 1)) \
18
const TCGOpDef *def = &tcg_op_defs[op->opc];
37
{ \
19
int i, nb_oargs;
38
- TCGTemp *args[1] = { dh_arg(t1, 1) }; \
20
@@ -XXX,XX +XXX,XX @@ static void finish_folding(OptContext *ctx, TCGOp *op)
39
- tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 1, args); \
21
ts_info(ts)->z_mask = ctx->z_mask;
40
+ tcg_gen_call1(&glue(helper_info_, name), dh_retvar(ret), \
22
}
41
+ dh_arg(t1, 1)); \
23
}
24
+ return true;
42
}
25
}
43
26
44
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
27
/*
45
@@ -XXX,XX +XXX,XX @@ extern TCGHelperInfo glue(helper_info_, name); \
28
@@ -XXX,XX +XXX,XX @@ static bool fold_add(OptContext *ctx, TCGOp *op)
46
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
29
fold_xi_to_x(ctx, op, 0)) {
47
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2)) \
30
return true;
48
{ \
31
}
49
- TCGTemp *args[2] = { dh_arg(t1, 1), dh_arg(t2, 2) }; \
32
- return false;
50
- tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 2, args); \
33
+ return finish_folding(ctx, op);
51
+ tcg_gen_call2(&glue(helper_info_, name), dh_retvar(ret), \
52
+ dh_arg(t1, 1), dh_arg(t2, 2)); \
53
}
34
}
54
35
55
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
36
/* We cannot as yet do_constant_folding with vectors. */
56
@@ -XXX,XX +XXX,XX @@ extern TCGHelperInfo glue(helper_info_, name); \
37
@@ -XXX,XX +XXX,XX @@ static bool fold_add_vec(OptContext *ctx, TCGOp *op)
57
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
38
fold_xi_to_x(ctx, op, 0)) {
58
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
39
return true;
59
{ \
40
}
60
- TCGTemp *args[3] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3) }; \
41
- return false;
61
- tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 3, args); \
42
+ return finish_folding(ctx, op);
62
+ tcg_gen_call3(&glue(helper_info_, name), dh_retvar(ret), \
63
+ dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3)); \
64
}
43
}
65
44
66
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
45
static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add)
67
@@ -XXX,XX +XXX,XX @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
46
@@ -XXX,XX +XXX,XX @@ static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add)
68
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), \
47
op->args[4] = arg_new_constant(ctx, bl);
69
dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
48
op->args[5] = arg_new_constant(ctx, bh);
70
{ \
49
}
71
- TCGTemp *args[4] = { dh_arg(t1, 1), dh_arg(t2, 2), \
50
- return false;
72
- dh_arg(t3, 3), dh_arg(t4, 4) }; \
51
+ return finish_folding(ctx, op);
73
- tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 4, args); \
74
+ tcg_gen_call4(&glue(helper_info_, name), dh_retvar(ret), \
75
+ dh_arg(t1, 1), dh_arg(t2, 2), \
76
+ dh_arg(t3, 3), dh_arg(t4, 4)); \
77
}
52
}
78
53
79
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
54
static bool fold_add2(OptContext *ctx, TCGOp *op)
80
@@ -XXX,XX +XXX,XX @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
81
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
82
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
83
{ \
84
- TCGTemp *args[5] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
85
- dh_arg(t4, 4), dh_arg(t5, 5) }; \
86
- tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 5, args); \
87
+ tcg_gen_call5(&glue(helper_info_, name), dh_retvar(ret), \
88
+ dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
89
+ dh_arg(t4, 4), dh_arg(t5, 5)); \
90
}
91
92
#define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \
93
@@ -XXX,XX +XXX,XX @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
94
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
95
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6)) \
96
{ \
97
- TCGTemp *args[6] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
98
- dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6) }; \
99
- tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 6, args); \
100
+ tcg_gen_call6(&glue(helper_info_, name), dh_retvar(ret), \
101
+ dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
102
+ dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6)); \
103
}
104
105
#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7)\
106
@@ -XXX,XX +XXX,XX @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
107
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6), \
108
dh_arg_decl(t7, 7)) \
109
{ \
110
- TCGTemp *args[7] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
111
- dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \
112
- dh_arg(t7, 7) }; \
113
- tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 7, args); \
114
+ tcg_gen_call7(&glue(helper_info_, name), dh_retvar(ret), \
115
+ dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
116
+ dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \
117
+ dh_arg(t7, 7)); \
118
}
119
120
#include "helper.h"
121
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
122
index XXXXXXX..XXXXXXX 100644
123
--- a/include/tcg/tcg.h
124
+++ b/include/tcg/tcg.h
125
@@ -XXX,XX +XXX,XX @@ typedef struct TCGTargetOpDef {
126
127
bool tcg_op_supported(TCGOpcode op);
128
129
-void tcg_gen_callN(TCGHelperInfo *, TCGTemp *ret, int nargs, TCGTemp **args);
130
+void tcg_gen_call0(TCGHelperInfo *, TCGTemp *ret);
131
+void tcg_gen_call1(TCGHelperInfo *, TCGTemp *ret, TCGTemp *);
132
+void tcg_gen_call2(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *);
133
+void tcg_gen_call3(TCGHelperInfo *, TCGTemp *ret, TCGTemp *,
134
+ TCGTemp *, TCGTemp *);
135
+void tcg_gen_call4(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *,
136
+ TCGTemp *, TCGTemp *);
137
+void tcg_gen_call5(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *,
138
+ TCGTemp *, TCGTemp *, TCGTemp *);
139
+void tcg_gen_call6(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *,
140
+ TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *);
141
+void tcg_gen_call7(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *,
142
+ TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *);
143
144
TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs);
145
void tcg_op_remove(TCGContext *s, TCGOp *op);
146
diff --git a/tcg/tcg.c b/tcg/tcg.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/tcg/tcg.c
149
+++ b/tcg/tcg.c
150
@@ -XXX,XX +XXX,XX @@ bool tcg_op_supported(TCGOpcode op)
151
152
static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs);
153
154
-void tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, int nargs, TCGTemp **args)
155
+static void tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, TCGTemp **args)
156
{
157
TCGv_i64 extend_free[MAX_CALL_IARGS];
158
int n_extend = 0;
159
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, int nargs, TCGTemp **args)
160
}
161
}
162
163
+void tcg_gen_call0(TCGHelperInfo *info, TCGTemp *ret)
164
+{
165
+ tcg_gen_callN(info, ret, NULL);
166
+}
167
+
168
+void tcg_gen_call1(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1)
169
+{
170
+ tcg_gen_callN(info, ret, &t1);
171
+}
172
+
173
+void tcg_gen_call2(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1, TCGTemp *t2)
174
+{
175
+ TCGTemp *args[2] = { t1, t2 };
176
+ tcg_gen_callN(info, ret, args);
177
+}
178
+
179
+void tcg_gen_call3(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
180
+ TCGTemp *t2, TCGTemp *t3)
181
+{
182
+ TCGTemp *args[3] = { t1, t2, t3 };
183
+ tcg_gen_callN(info, ret, args);
184
+}
185
+
186
+void tcg_gen_call4(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
187
+ TCGTemp *t2, TCGTemp *t3, TCGTemp *t4)
188
+{
189
+ TCGTemp *args[4] = { t1, t2, t3, t4 };
190
+ tcg_gen_callN(info, ret, args);
191
+}
192
+
193
+void tcg_gen_call5(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
194
+ TCGTemp *t2, TCGTemp *t3, TCGTemp *t4, TCGTemp *t5)
195
+{
196
+ TCGTemp *args[5] = { t1, t2, t3, t4, t5 };
197
+ tcg_gen_callN(info, ret, args);
198
+}
199
+
200
+void tcg_gen_call6(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1, TCGTemp *t2,
201
+ TCGTemp *t3, TCGTemp *t4, TCGTemp *t5, TCGTemp *t6)
202
+{
203
+ TCGTemp *args[6] = { t1, t2, t3, t4, t5, t6 };
204
+ tcg_gen_callN(info, ret, args);
205
+}
206
+
207
+void tcg_gen_call7(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
208
+ TCGTemp *t2, TCGTemp *t3, TCGTemp *t4,
209
+ TCGTemp *t5, TCGTemp *t6, TCGTemp *t7)
210
+{
211
+ TCGTemp *args[7] = { t1, t2, t3, t4, t5, t6, t7 };
212
+ tcg_gen_callN(info, ret, args);
213
+}
214
+
215
static void tcg_reg_alloc_start(TCGContext *s)
216
{
217
int i, n;
218
--
55
--
219
2.34.1
56
2.43.0
220
221
diff view generated by jsdifflib
1
Create helper-gen-common.h without the target specific portion.
1
Introduce ti_is_const, ti_const_val, ti_is_const_val.
2
Use that in tcg-op-common.h. Reorg headers in target/arm to
3
ensure that helper-gen.h is included before helper-info.c.inc.
4
All other targets are already correct in this regard.
5
2
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
4
---
9
MAINTAINERS | 1 +
5
tcg/optimize.c | 20 +++++++++++++++++---
10
include/exec/helper-gen-common.h | 18 ++++++
6
1 file changed, 17 insertions(+), 3 deletions(-)
11
include/exec/helper-gen.h | 101 ++----------------------------
12
include/tcg/tcg-op-common.h | 2 +-
13
include/exec/helper-gen.h.inc | 102 +++++++++++++++++++++++++++++++
14
target/arm/tcg/translate.c | 8 +--
15
6 files changed, 129 insertions(+), 103 deletions(-)
16
create mode 100644 include/exec/helper-gen-common.h
17
create mode 100644 include/exec/helper-gen.h.inc
18
7
19
diff --git a/MAINTAINERS b/MAINTAINERS
8
diff --git a/tcg/optimize.c b/tcg/optimize.c
20
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
21
--- a/MAINTAINERS
10
--- a/tcg/optimize.c
22
+++ b/MAINTAINERS
11
+++ b/tcg/optimize.c
23
@@ -XXX,XX +XXX,XX @@ F: include/exec/exec-all.h
12
@@ -XXX,XX +XXX,XX @@ static inline TempOptInfo *arg_info(TCGArg arg)
24
F: include/exec/tb-flush.h
13
return ts_info(arg_temp(arg));
25
F: include/exec/target_long.h
14
}
26
F: include/exec/helper*.h
15
27
+F: include/exec/helper*.h.inc
16
+static inline bool ti_is_const(TempOptInfo *ti)
28
F: include/exec/helper-info.c.inc
17
+{
29
F: include/sysemu/cpus.h
18
+ return ti->is_const;
30
F: include/sysemu/tcg.h
31
diff --git a/include/exec/helper-gen-common.h b/include/exec/helper-gen-common.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/exec/helper-gen-common.h
36
@@ -XXX,XX +XXX,XX @@
37
+/* SPDX-License-Identifier: GPL-2.0-or-later */
38
+/*
39
+ * Helper file for declaring TCG helper functions.
40
+ * This one expands generation functions for tcg opcodes.
41
+ */
42
+
43
+#ifndef HELPER_GEN_COMMON_H
44
+#define HELPER_GEN_COMMON_H
45
+
46
+#define HELPER_H "accel/tcg/tcg-runtime.h"
47
+#include "exec/helper-gen.h.inc"
48
+#undef HELPER_H
49
+
50
+#define HELPER_H "accel/tcg/plugin-helpers.h"
51
+#include "exec/helper-gen.h.inc"
52
+#undef HELPER_H
53
+
54
+#endif /* HELPER_GEN_COMMON_H */
55
diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/include/exec/helper-gen.h
58
+++ b/include/exec/helper-gen.h
59
@@ -XXX,XX +XXX,XX @@
60
/*
61
* Helper file for declaring TCG helper functions.
62
* This one expands generation functions for tcg opcodes.
63
- * Define HELPER_H for the header file to be expanded,
64
- * and static inline to change from global file scope.
65
*/
66
67
#ifndef HELPER_GEN_H
68
#define HELPER_GEN_H
69
70
-#include "tcg/tcg.h"
71
-#include "tcg/helper-info.h"
72
-#include "exec/helper-head.h"
73
+#include "exec/helper-gen-common.h"
74
75
-#define DEF_HELPER_FLAGS_0(name, flags, ret) \
76
-extern TCGHelperInfo glue(helper_info_, name); \
77
-static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
78
-{ \
79
- tcg_gen_call0(&glue(helper_info_, name), dh_retvar(ret)); \
80
-}
81
-
82
-#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
83
-extern TCGHelperInfo glue(helper_info_, name); \
84
-static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
85
- dh_arg_decl(t1, 1)) \
86
-{ \
87
- tcg_gen_call1(&glue(helper_info_, name), dh_retvar(ret), \
88
- dh_arg(t1, 1)); \
89
-}
90
-
91
-#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
92
-extern TCGHelperInfo glue(helper_info_, name); \
93
-static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
94
- dh_arg_decl(t1, 1), dh_arg_decl(t2, 2)) \
95
-{ \
96
- tcg_gen_call2(&glue(helper_info_, name), dh_retvar(ret), \
97
- dh_arg(t1, 1), dh_arg(t2, 2)); \
98
-}
99
-
100
-#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
101
-extern TCGHelperInfo glue(helper_info_, name); \
102
-static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
103
- dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
104
-{ \
105
- tcg_gen_call3(&glue(helper_info_, name), dh_retvar(ret), \
106
- dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3)); \
107
-}
108
-
109
-#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
110
-extern TCGHelperInfo glue(helper_info_, name); \
111
-static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
112
- dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), \
113
- dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
114
-{ \
115
- tcg_gen_call4(&glue(helper_info_, name), dh_retvar(ret), \
116
- dh_arg(t1, 1), dh_arg(t2, 2), \
117
- dh_arg(t3, 3), dh_arg(t4, 4)); \
118
-}
119
-
120
-#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
121
-extern TCGHelperInfo glue(helper_info_, name); \
122
-static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
123
- dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
124
- dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
125
-{ \
126
- tcg_gen_call5(&glue(helper_info_, name), dh_retvar(ret), \
127
- dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
128
- dh_arg(t4, 4), dh_arg(t5, 5)); \
129
-}
130
-
131
-#define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \
132
-extern TCGHelperInfo glue(helper_info_, name); \
133
-static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
134
- dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
135
- dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6)) \
136
-{ \
137
- tcg_gen_call6(&glue(helper_info_, name), dh_retvar(ret), \
138
- dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
139
- dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6)); \
140
-}
141
-
142
-#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7)\
143
-extern TCGHelperInfo glue(helper_info_, name); \
144
-static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
145
- dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
146
- dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6), \
147
- dh_arg_decl(t7, 7)) \
148
-{ \
149
- tcg_gen_call7(&glue(helper_info_, name), dh_retvar(ret), \
150
- dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
151
- dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \
152
- dh_arg(t7, 7)); \
153
-}
154
-
155
-#include "helper.h"
156
-#include "accel/tcg/tcg-runtime.h"
157
-#include "accel/tcg/plugin-helpers.h"
158
-
159
-#undef DEF_HELPER_FLAGS_0
160
-#undef DEF_HELPER_FLAGS_1
161
-#undef DEF_HELPER_FLAGS_2
162
-#undef DEF_HELPER_FLAGS_3
163
-#undef DEF_HELPER_FLAGS_4
164
-#undef DEF_HELPER_FLAGS_5
165
-#undef DEF_HELPER_FLAGS_6
166
-#undef DEF_HELPER_FLAGS_7
167
+#define HELPER_H "helper.h"
168
+#include "exec/helper-gen.h.inc"
169
+#undef HELPER_H
170
171
#endif /* HELPER_GEN_H */
172
diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
173
index XXXXXXX..XXXXXXX 100644
174
--- a/include/tcg/tcg-op-common.h
175
+++ b/include/tcg/tcg-op-common.h
176
@@ -XXX,XX +XXX,XX @@
177
178
#include "tcg/tcg.h"
179
#include "exec/helper-proto.h"
180
-#include "exec/helper-gen.h"
181
+#include "exec/helper-gen-common.h"
182
183
/* Basic output routines. Not for general consumption. */
184
185
diff --git a/include/exec/helper-gen.h.inc b/include/exec/helper-gen.h.inc
186
new file mode 100644
187
index XXXXXXX..XXXXXXX
188
--- /dev/null
189
+++ b/include/exec/helper-gen.h.inc
190
@@ -XXX,XX +XXX,XX @@
191
+/* SPDX-License-Identifier: GPL-2.0-or-later */
192
+/*
193
+ * Helper file for declaring TCG helper functions.
194
+ * This one expands generation functions for tcg opcodes.
195
+ * Define HELPER_H for the header file to be expanded,
196
+ * and static inline to change from global file scope.
197
+ */
198
+
199
+#include "tcg/tcg.h"
200
+#include "tcg/helper-info.h"
201
+#include "exec/helper-head.h"
202
+
203
+#define DEF_HELPER_FLAGS_0(name, flags, ret) \
204
+extern TCGHelperInfo glue(helper_info_, name); \
205
+static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
206
+{ \
207
+ tcg_gen_call0(&glue(helper_info_, name), dh_retvar(ret)); \
208
+}
19
+}
209
+
20
+
210
+#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
21
+static inline uint64_t ti_const_val(TempOptInfo *ti)
211
+extern TCGHelperInfo glue(helper_info_, name); \
22
+{
212
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
23
+ return ti->val;
213
+ dh_arg_decl(t1, 1)) \
214
+{ \
215
+ tcg_gen_call1(&glue(helper_info_, name), dh_retvar(ret), \
216
+ dh_arg(t1, 1)); \
217
+}
24
+}
218
+
25
+
219
+#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
26
+static inline bool ti_is_const_val(TempOptInfo *ti, uint64_t val)
220
+extern TCGHelperInfo glue(helper_info_, name); \
27
+{
221
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
28
+ return ti_is_const(ti) && ti_const_val(ti) == val;
222
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2)) \
223
+{ \
224
+ tcg_gen_call2(&glue(helper_info_, name), dh_retvar(ret), \
225
+ dh_arg(t1, 1), dh_arg(t2, 2)); \
226
+}
29
+}
227
+
30
+
228
+#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
31
static inline bool ts_is_const(TCGTemp *ts)
229
+extern TCGHelperInfo glue(helper_info_, name); \
32
{
230
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
33
- return ts_info(ts)->is_const;
231
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
34
+ return ti_is_const(ts_info(ts));
232
+{ \
35
}
233
+ tcg_gen_call3(&glue(helper_info_, name), dh_retvar(ret), \
36
234
+ dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3)); \
37
static inline bool ts_is_const_val(TCGTemp *ts, uint64_t val)
235
+}
38
{
236
+
39
- TempOptInfo *ti = ts_info(ts);
237
+#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
40
- return ti->is_const && ti->val == val;
238
+extern TCGHelperInfo glue(helper_info_, name); \
41
+ return ti_is_const_val(ts_info(ts), val);
239
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
42
}
240
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), \
43
241
+ dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
44
static inline bool arg_is_const(TCGArg arg)
242
+{ \
243
+ tcg_gen_call4(&glue(helper_info_, name), dh_retvar(ret), \
244
+ dh_arg(t1, 1), dh_arg(t2, 2), \
245
+ dh_arg(t3, 3), dh_arg(t4, 4)); \
246
+}
247
+
248
+#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
249
+extern TCGHelperInfo glue(helper_info_, name); \
250
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
251
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
252
+ dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
253
+{ \
254
+ tcg_gen_call5(&glue(helper_info_, name), dh_retvar(ret), \
255
+ dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
256
+ dh_arg(t4, 4), dh_arg(t5, 5)); \
257
+}
258
+
259
+#define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \
260
+extern TCGHelperInfo glue(helper_info_, name); \
261
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
262
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
263
+ dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6)) \
264
+{ \
265
+ tcg_gen_call6(&glue(helper_info_, name), dh_retvar(ret), \
266
+ dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
267
+ dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6)); \
268
+}
269
+
270
+#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7)\
271
+extern TCGHelperInfo glue(helper_info_, name); \
272
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
273
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
274
+ dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6), \
275
+ dh_arg_decl(t7, 7)) \
276
+{ \
277
+ tcg_gen_call7(&glue(helper_info_, name), dh_retvar(ret), \
278
+ dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
279
+ dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \
280
+ dh_arg(t7, 7)); \
281
+}
282
+
283
+#include HELPER_H
284
+
285
+#undef DEF_HELPER_FLAGS_0
286
+#undef DEF_HELPER_FLAGS_1
287
+#undef DEF_HELPER_FLAGS_2
288
+#undef DEF_HELPER_FLAGS_3
289
+#undef DEF_HELPER_FLAGS_4
290
+#undef DEF_HELPER_FLAGS_5
291
+#undef DEF_HELPER_FLAGS_6
292
+#undef DEF_HELPER_FLAGS_7
293
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
294
index XXXXXXX..XXXXXXX 100644
295
--- a/target/arm/tcg/translate.c
296
+++ b/target/arm/tcg/translate.c
297
@@ -XXX,XX +XXX,XX @@
298
#include "semihosting/semihost.h"
299
#include "exec/log.h"
300
#include "cpregs.h"
301
+#include "translate.h"
302
+#include "translate-a32.h"
303
+#include "exec/gen-icount.h"
304
305
#define HELPER_H "helper.h"
306
#include "exec/helper-info.c.inc"
307
@@ -XXX,XX +XXX,XX @@
308
#define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
309
#define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
310
311
-#include "translate.h"
312
-#include "translate-a32.h"
313
-
314
/* These are TCG temporaries used only by the legacy iwMMXt decoder */
315
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
316
/* These are TCG globals which alias CPUARMState fields */
317
@@ -XXX,XX +XXX,XX @@ TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
318
TCGv_i64 cpu_exclusive_addr;
319
TCGv_i64 cpu_exclusive_val;
320
321
-#include "exec/gen-icount.h"
322
-
323
static const char * const regnames[] =
324
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
325
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
326
--
45
--
327
2.34.1
46
2.43.0
328
329
diff view generated by jsdifflib
1
This is all that is required by tcg/ from exec-all.h.
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Sink mask computation below fold_affected_mask early exit.
2
3
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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
include/exec/exec-all.h | 132 +--------------------------
7
tcg/optimize.c | 30 ++++++++++++++++--------------
7
include/exec/translation-block.h | 149 +++++++++++++++++++++++++++++++
8
1 file changed, 16 insertions(+), 14 deletions(-)
8
tcg/tcg-op-ldst.c | 2 +-
9
3 files changed, 151 insertions(+), 132 deletions(-)
10
create mode 100644 include/exec/translation-block.h
11
9
12
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/include/exec/exec-all.h
12
--- a/tcg/optimize.c
15
+++ b/include/exec/exec-all.h
13
+++ b/tcg/optimize.c
16
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static bool fold_add2(OptContext *ctx, TCGOp *op)
17
#ifdef CONFIG_TCG
15
18
#include "exec/cpu_ldst.h"
16
static bool fold_and(OptContext *ctx, TCGOp *op)
19
#endif
17
{
20
-#include "qemu/interval-tree.h"
18
- uint64_t z1, z2;
21
+#include "exec/translation-block.h"
19
+ uint64_t z1, z2, z_mask, s_mask;
22
#include "qemu/clang-tsa.h"
20
+ TempOptInfo *t1, *t2;
23
21
24
-/* Page tracking code uses ram addresses in system mode, and virtual
22
if (fold_const2_commutative(ctx, op) ||
25
- addresses in userspace mode. Define tb_page_addr_t to be an appropriate
23
fold_xi_to_i(ctx, op, 0) ||
26
- type. */
24
@@ -XXX,XX +XXX,XX @@ static bool fold_and(OptContext *ctx, TCGOp *op)
27
-#if defined(CONFIG_USER_ONLY)
25
return true;
28
-typedef vaddr tb_page_addr_t;
26
}
29
-#define TB_PAGE_ADDR_FMT "%" VADDR_PRIx
27
30
-#else
28
- z1 = arg_info(op->args[1])->z_mask;
31
-typedef ram_addr_t tb_page_addr_t;
29
- z2 = arg_info(op->args[2])->z_mask;
32
-#define TB_PAGE_ADDR_FMT RAM_ADDR_FMT
30
- ctx->z_mask = z1 & z2;
33
-#endif
34
-
35
/**
36
* cpu_unwind_state_data:
37
* @cpu: the cpu context
38
@@ -XXX,XX +XXX,XX @@ int probe_access_full(CPUArchState *env, target_ulong addr, int size,
39
CPUTLBEntryFull **pfull, uintptr_t retaddr);
40
#endif
41
42
-#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
43
-
44
/* Estimated block size for TB allocation. */
45
/* ??? The following is based on a 2015 survey of x86_64 host output.
46
Better would seem to be some sort of dynamically sized TB array,
47
@@ -XXX,XX +XXX,XX @@ int probe_access_full(CPUArchState *env, target_ulong addr, int size,
48
#define CODE_GEN_AVG_BLOCK_SIZE 150
49
#endif
50
51
-/*
52
- * Translation Cache-related fields of a TB.
53
- * This struct exists just for convenience; we keep track of TB's in a binary
54
- * search tree, and the only fields needed to compare TB's in the tree are
55
- * @ptr and @size.
56
- * Note: the address of search data can be obtained by adding @size to @ptr.
57
- */
58
-struct tb_tc {
59
- const void *ptr; /* pointer to the translated code */
60
- size_t size;
61
-};
62
-
63
-struct TranslationBlock {
64
- /*
65
- * Guest PC corresponding to this block. This must be the true
66
- * virtual address. Therefore e.g. x86 stores EIP + CS_BASE, and
67
- * targets like Arm, MIPS, HP-PA, which reuse low bits for ISA or
68
- * privilege, must store those bits elsewhere.
69
- *
70
- * If CF_PCREL, the opcodes for the TranslationBlock are written
71
- * such that the TB is associated only with the physical page and
72
- * may be run in any virtual address context. In this case, PC
73
- * must always be taken from ENV in a target-specific manner.
74
- * Unwind information is taken as offsets from the page, to be
75
- * deposited into the "current" PC.
76
- */
77
- vaddr pc;
78
-
31
-
79
- /*
32
- /*
80
- * Target-specific data associated with the TranslationBlock, e.g.:
33
- * Sign repetitions are perforce all identical, whether they are 1 or 0.
81
- * x86: the original user, the Code Segment virtual base,
34
- * Bitwise operations preserve the relative quantity of the repetitions.
82
- * arm: an extension of tb->flags,
83
- * s390x: instruction data for EXECUTE,
84
- * sparc: the next pc of the instruction queue (for delay slots).
85
- */
35
- */
86
- uint64_t cs_base;
36
- ctx->s_mask = arg_info(op->args[1])->s_mask
87
-
37
- & arg_info(op->args[2])->s_mask;
88
- uint32_t flags; /* flags defining in which context the code was generated */
38
+ t1 = arg_info(op->args[1]);
89
- uint32_t cflags; /* compile flags */
39
+ t2 = arg_info(op->args[2]);
90
-
40
+ z1 = t1->z_mask;
91
-/* Note that TCG_MAX_INSNS is 512; we validate this match elsewhere. */
41
+ z2 = t2->z_mask;
92
-#define CF_COUNT_MASK 0x000001ff
42
93
-#define CF_NO_GOTO_TB 0x00000200 /* Do not chain with goto_tb */
43
/*
94
-#define CF_NO_GOTO_PTR 0x00000400 /* Do not chain with goto_ptr */
44
* Known-zeros does not imply known-ones. Therefore unless
95
-#define CF_SINGLE_STEP 0x00000800 /* gdbstub single-step in effect */
45
* arg2 is constant, we can't infer affected bits from it.
96
-#define CF_LAST_IO 0x00008000 /* Last insn may be an IO access. */
46
*/
97
-#define CF_MEMI_ONLY 0x00010000 /* Only instrument memory ops */
47
- if (arg_is_const(op->args[2]) &&
98
-#define CF_USE_ICOUNT 0x00020000
48
- fold_affected_mask(ctx, op, z1 & ~z2)) {
99
-#define CF_INVALID 0x00040000 /* TB is stale. Set with @jmp_lock held */
49
+ if (ti_is_const(t2) && fold_affected_mask(ctx, op, z1 & ~z2)) {
100
-#define CF_PARALLEL 0x00080000 /* Generate code for a parallel context */
50
return true;
101
-#define CF_NOIRQ 0x00100000 /* Generate an uninterruptible TB */
51
}
102
-#define CF_PCREL 0x00200000 /* Opcodes in TB are PC-relative */
52
103
-#define CF_CLUSTER_MASK 0xff000000 /* Top 8 bits are cluster ID */
53
- return fold_masks(ctx, op);
104
-#define CF_CLUSTER_SHIFT 24
54
+ z_mask = z1 & z2;
105
-
106
- /*
107
- * Above fields used for comparing
108
- */
109
-
110
- /* size of target code for this block (1 <= size <= TARGET_PAGE_SIZE) */
111
- uint16_t size;
112
- uint16_t icount;
113
-
114
- struct tb_tc tc;
115
-
116
- /*
117
- * Track tb_page_addr_t intervals that intersect this TB.
118
- * For user-only, the virtual addresses are always contiguous,
119
- * and we use a unified interval tree. For system, we use a
120
- * linked list headed in each PageDesc. Within the list, the lsb
121
- * of the previous pointer tells the index of page_next[], and the
122
- * list is protected by the PageDesc lock(s).
123
- */
124
-#ifdef CONFIG_USER_ONLY
125
- IntervalTreeNode itree;
126
-#else
127
- uintptr_t page_next[2];
128
- tb_page_addr_t page_addr[2];
129
-#endif
130
-
131
- /* jmp_lock placed here to fill a 4-byte hole. Its documentation is below */
132
- QemuSpin jmp_lock;
133
-
134
- /* The following data are used to directly call another TB from
135
- * the code of this one. This can be done either by emitting direct or
136
- * indirect native jump instructions. These jumps are reset so that the TB
137
- * just continues its execution. The TB can be linked to another one by
138
- * setting one of the jump targets (or patching the jump instruction). Only
139
- * two of such jumps are supported.
140
- */
141
-#define TB_JMP_OFFSET_INVALID 0xffff /* indicates no jump generated */
142
- uint16_t jmp_reset_offset[2]; /* offset of original jump target */
143
- uint16_t jmp_insn_offset[2]; /* offset of direct jump insn */
144
- uintptr_t jmp_target_addr[2]; /* target address */
145
-
146
- /*
147
- * Each TB has a NULL-terminated list (jmp_list_head) of incoming jumps.
148
- * Each TB can have two outgoing jumps, and therefore can participate
149
- * in two lists. The list entries are kept in jmp_list_next[2]. The least
150
- * significant bit (LSB) of the pointers in these lists is used to encode
151
- * which of the two list entries is to be used in the pointed TB.
152
- *
153
- * List traversals are protected by jmp_lock. The destination TB of each
154
- * outgoing jump is kept in jmp_dest[] so that the appropriate jmp_lock
155
- * can be acquired from any origin TB.
156
- *
157
- * jmp_dest[] are tagged pointers as well. The LSB is set when the TB is
158
- * being invalidated, so that no further outgoing jumps from it can be set.
159
- *
160
- * jmp_lock also protects the CF_INVALID cflag; a jump must not be chained
161
- * to a destination TB that has CF_INVALID set.
162
- */
163
- uintptr_t jmp_list_head;
164
- uintptr_t jmp_list_next[2];
165
- uintptr_t jmp_dest[2];
166
-};
167
-
168
/* Hide the qatomic_read to make code a little easier on the eyes */
169
static inline uint32_t tb_cflags(const TranslationBlock *tb)
170
{
171
diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h
172
new file mode 100644
173
index XXXXXXX..XXXXXXX
174
--- /dev/null
175
+++ b/include/exec/translation-block.h
176
@@ -XXX,XX +XXX,XX @@
177
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
178
+/*
179
+ * Definition of TranslationBlock.
180
+ * Copyright (c) 2003 Fabrice Bellard
181
+ */
182
+
183
+#ifndef EXEC_TRANSLATION_BLOCK_H
184
+#define EXEC_TRANSLATION_BLOCK_H
185
+
186
+#include "qemu/atomic.h"
187
+#include "qemu/thread.h"
188
+#include "qemu/interval-tree.h"
189
+#include "exec/cpu-common.h"
190
+#include "exec/target_page.h"
191
+
192
+/*
193
+ * Page tracking code uses ram addresses in system mode, and virtual
194
+ * addresses in userspace mode. Define tb_page_addr_t to be an
195
+ * appropriate type.
196
+ */
197
+#if defined(CONFIG_USER_ONLY)
198
+typedef vaddr tb_page_addr_t;
199
+#define TB_PAGE_ADDR_FMT "%" VADDR_PRIx
200
+#else
201
+typedef ram_addr_t tb_page_addr_t;
202
+#define TB_PAGE_ADDR_FMT RAM_ADDR_FMT
203
+#endif
204
+
205
+/*
206
+ * Translation Cache-related fields of a TB.
207
+ * This struct exists just for convenience; we keep track of TB's in a binary
208
+ * search tree, and the only fields needed to compare TB's in the tree are
209
+ * @ptr and @size.
210
+ * Note: the address of search data can be obtained by adding @size to @ptr.
211
+ */
212
+struct tb_tc {
213
+ const void *ptr; /* pointer to the translated code */
214
+ size_t size;
215
+};
216
+
217
+struct TranslationBlock {
218
+ /*
219
+ * Guest PC corresponding to this block. This must be the true
220
+ * virtual address. Therefore e.g. x86 stores EIP + CS_BASE, and
221
+ * targets like Arm, MIPS, HP-PA, which reuse low bits for ISA or
222
+ * privilege, must store those bits elsewhere.
223
+ *
224
+ * If CF_PCREL, the opcodes for the TranslationBlock are written
225
+ * such that the TB is associated only with the physical page and
226
+ * may be run in any virtual address context. In this case, PC
227
+ * must always be taken from ENV in a target-specific manner.
228
+ * Unwind information is taken as offsets from the page, to be
229
+ * deposited into the "current" PC.
230
+ */
231
+ vaddr pc;
232
+
55
+
233
+ /*
56
+ /*
234
+ * Target-specific data associated with the TranslationBlock, e.g.:
57
+ * Sign repetitions are perforce all identical, whether they are 1 or 0.
235
+ * x86: the original user, the Code Segment virtual base,
58
+ * Bitwise operations preserve the relative quantity of the repetitions.
236
+ * arm: an extension of tb->flags,
237
+ * s390x: instruction data for EXECUTE,
238
+ * sparc: the next pc of the instruction queue (for delay slots).
239
+ */
59
+ */
240
+ uint64_t cs_base;
60
+ s_mask = t1->s_mask & t2->s_mask;
241
+
61
+
242
+ uint32_t flags; /* flags defining in which context the code was generated */
62
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
243
+ uint32_t cflags; /* compile flags */
63
}
244
+
64
245
+/* Note that TCG_MAX_INSNS is 512; we validate this match elsewhere. */
65
static bool fold_andc(OptContext *ctx, TCGOp *op)
246
+#define CF_COUNT_MASK 0x000001ff
247
+#define CF_NO_GOTO_TB 0x00000200 /* Do not chain with goto_tb */
248
+#define CF_NO_GOTO_PTR 0x00000400 /* Do not chain with goto_ptr */
249
+#define CF_SINGLE_STEP 0x00000800 /* gdbstub single-step in effect */
250
+#define CF_LAST_IO 0x00008000 /* Last insn may be an IO access. */
251
+#define CF_MEMI_ONLY 0x00010000 /* Only instrument memory ops */
252
+#define CF_USE_ICOUNT 0x00020000
253
+#define CF_INVALID 0x00040000 /* TB is stale. Set with @jmp_lock held */
254
+#define CF_PARALLEL 0x00080000 /* Generate code for a parallel context */
255
+#define CF_NOIRQ 0x00100000 /* Generate an uninterruptible TB */
256
+#define CF_PCREL 0x00200000 /* Opcodes in TB are PC-relative */
257
+#define CF_CLUSTER_MASK 0xff000000 /* Top 8 bits are cluster ID */
258
+#define CF_CLUSTER_SHIFT 24
259
+
260
+ /*
261
+ * Above fields used for comparing
262
+ */
263
+
264
+ /* size of target code for this block (1 <= size <= TARGET_PAGE_SIZE) */
265
+ uint16_t size;
266
+ uint16_t icount;
267
+
268
+ struct tb_tc tc;
269
+
270
+ /*
271
+ * Track tb_page_addr_t intervals that intersect this TB.
272
+ * For user-only, the virtual addresses are always contiguous,
273
+ * and we use a unified interval tree. For system, we use a
274
+ * linked list headed in each PageDesc. Within the list, the lsb
275
+ * of the previous pointer tells the index of page_next[], and the
276
+ * list is protected by the PageDesc lock(s).
277
+ */
278
+#ifdef CONFIG_USER_ONLY
279
+ IntervalTreeNode itree;
280
+#else
281
+ uintptr_t page_next[2];
282
+ tb_page_addr_t page_addr[2];
283
+#endif
284
+
285
+ /* jmp_lock placed here to fill a 4-byte hole. Its documentation is below */
286
+ QemuSpin jmp_lock;
287
+
288
+ /* The following data are used to directly call another TB from
289
+ * the code of this one. This can be done either by emitting direct or
290
+ * indirect native jump instructions. These jumps are reset so that the TB
291
+ * just continues its execution. The TB can be linked to another one by
292
+ * setting one of the jump targets (or patching the jump instruction). Only
293
+ * two of such jumps are supported.
294
+ */
295
+#define TB_JMP_OFFSET_INVALID 0xffff /* indicates no jump generated */
296
+ uint16_t jmp_reset_offset[2]; /* offset of original jump target */
297
+ uint16_t jmp_insn_offset[2]; /* offset of direct jump insn */
298
+ uintptr_t jmp_target_addr[2]; /* target address */
299
+
300
+ /*
301
+ * Each TB has a NULL-terminated list (jmp_list_head) of incoming jumps.
302
+ * Each TB can have two outgoing jumps, and therefore can participate
303
+ * in two lists. The list entries are kept in jmp_list_next[2]. The least
304
+ * significant bit (LSB) of the pointers in these lists is used to encode
305
+ * which of the two list entries is to be used in the pointed TB.
306
+ *
307
+ * List traversals are protected by jmp_lock. The destination TB of each
308
+ * outgoing jump is kept in jmp_dest[] so that the appropriate jmp_lock
309
+ * can be acquired from any origin TB.
310
+ *
311
+ * jmp_dest[] are tagged pointers as well. The LSB is set when the TB is
312
+ * being invalidated, so that no further outgoing jumps from it can be set.
313
+ *
314
+ * jmp_lock also protects the CF_INVALID cflag; a jump must not be chained
315
+ * to a destination TB that has CF_INVALID set.
316
+ */
317
+ uintptr_t jmp_list_head;
318
+ uintptr_t jmp_list_next[2];
319
+ uintptr_t jmp_dest[2];
320
+};
321
+
322
+/* The alignment given to TranslationBlock during allocation. */
323
+#define CODE_GEN_ALIGN 16
324
+
325
+#endif /* EXEC_TRANSLATION_BLOCK_H */
326
diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c
327
index XXXXXXX..XXXXXXX 100644
328
--- a/tcg/tcg-op-ldst.c
329
+++ b/tcg/tcg-op-ldst.c
330
@@ -XXX,XX +XXX,XX @@
331
*/
332
333
#include "qemu/osdep.h"
334
-#include "exec/exec-all.h"
335
#include "tcg/tcg.h"
336
#include "tcg/tcg-temp-internal.h"
337
#include "tcg/tcg-op-common.h"
338
#include "tcg/tcg-mo.h"
339
+#include "exec/translation-block.h"
340
#include "exec/plugin-gen.h"
341
#include "tcg-internal.h"
342
343
--
66
--
344
2.34.1
67
2.43.0
345
346
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Avoid double inversion of the value of second const operand.
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 | 21 +++++++++++----------
8
1 file changed, 11 insertions(+), 10 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_and(OptContext *ctx, TCGOp *op)
15
16
static bool fold_andc(OptContext *ctx, TCGOp *op)
17
{
18
- uint64_t z1;
19
+ uint64_t z_mask, s_mask;
20
+ TempOptInfo *t1, *t2;
21
22
if (fold_const2(ctx, op) ||
23
fold_xx_to_i(ctx, op, 0) ||
24
@@ -XXX,XX +XXX,XX @@ static bool fold_andc(OptContext *ctx, TCGOp *op)
25
return true;
26
}
27
28
- z1 = arg_info(op->args[1])->z_mask;
29
+ t1 = arg_info(op->args[1]);
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)) {
43
return true;
44
}
45
- z1 &= z2;
46
+ z_mask &= ~v2;
47
}
48
- ctx->z_mask = z1;
49
50
- ctx->s_mask = arg_info(op->args[1])->s_mask
51
- & arg_info(op->args[2])->s_mask;
52
- return fold_masks(ctx, op);
53
+ s_mask = t1->s_mask & t2->s_mask;
54
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
55
}
56
57
static bool fold_brcond(OptContext *ctx, TCGOp *op)
58
--
59
2.43.0
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
New patch
1
Add fold_masks_z as a trivial wrapper around fold_masks_zs.
2
Avoid the use of the OptContext slots.
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 | 13 ++++++++++---
8
1 file changed, 10 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_masks_zs(OptContext *ctx, TCGOp *op,
15
return true;
16
}
17
18
+static bool fold_masks_z(OptContext *ctx, TCGOp *op, uint64_t z_mask)
19
+{
20
+ return fold_masks_zs(ctx, op, z_mask, 0);
21
+}
22
+
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);
50
}
51
52
static bool fold_deposit(OptContext *ctx, TCGOp *op)
53
--
54
2.43.0
diff view generated by jsdifflib
1
All uses replaced with TCGContext.addr_type.
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
When we fold to and, use fold_and.
2
3
3
Reviewed-by: Anton Johansson <anjo@rev.ng>
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
tcg/ppc/tcg-target.c.inc | 21 +++++++++++----------
7
tcg/optimize.c | 35 +++++++++++++++++------------------
7
1 file changed, 11 insertions(+), 10 deletions(-)
8
1 file changed, 17 insertions(+), 18 deletions(-)
8
9
9
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/ppc/tcg-target.c.inc
12
--- a/tcg/optimize.c
12
+++ b/tcg/ppc/tcg-target.c.inc
13
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
14
@@ -XXX,XX +XXX,XX @@ static bool fold_ctpop(OptContext *ctx, TCGOp *op)
14
TCGReg addrlo, TCGReg addrhi,
15
15
MemOpIdx oi, bool is_ld)
16
static bool fold_deposit(OptContext *ctx, TCGOp *op)
16
{
17
{
17
+ TCGType addr_type = s->addr_type;
18
+ TempOptInfo *t1 = arg_info(op->args[1]);
18
TCGLabelQemuLdst *ldst = NULL;
19
+ TempOptInfo *t2 = arg_info(op->args[2]);
19
MemOp opc = get_memop(oi);
20
+ int ofs = op->args[3];
20
MemOp a_bits, s_bits;
21
+ int len = op->args[4];
21
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
22
TCGOpcode and_opc;
22
tcg_out32(s, AND | SAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_R0));
23
+ uint64_t z_mask;
23
24
24
/* Load the (low part) TLB comparator into TMP2. */
25
- if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) {
25
- if (cmp_off == 0 && TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) {
26
- uint64_t t1 = arg_info(op->args[1])->val;
26
- uint32_t lxu = (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32
27
- uint64_t t2 = arg_info(op->args[2])->val;
27
+ if (cmp_off == 0
28
-
28
+ && (TCG_TARGET_REG_BITS == 64 || addr_type == TCG_TYPE_I32)) {
29
- t1 = deposit64(t1, op->args[3], op->args[4], t2);
29
+ uint32_t lxu = (TCG_TARGET_REG_BITS == 32 || addr_type == TCG_TYPE_I32
30
- return tcg_opt_gen_movi(ctx, op, op->args[0], t1);
30
? LWZUX : LDUX);
31
+ if (ti_is_const(t1) && ti_is_const(t2)) {
31
tcg_out32(s, lxu | TAB(TCG_REG_TMP2, TCG_REG_TMP1, TCG_REG_TMP2));
32
+ return tcg_opt_gen_movi(ctx, op, op->args[0],
32
} else {
33
+ deposit64(ti_const_val(t1), ofs, len,
33
tcg_out32(s, ADD | TAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_TMP2));
34
+ ti_const_val(t2)));
34
- if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
35
+ if (TCG_TARGET_REG_BITS == 32 && addr_type != TCG_TYPE_I32) {
36
tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP2,
37
TCG_REG_TMP1, cmp_off + 4 * HOST_BIG_ENDIAN);
38
} else {
39
- tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP2, TCG_REG_TMP1, cmp_off);
40
+ tcg_out_ld(s, addr_type, TCG_REG_TMP2, TCG_REG_TMP1, cmp_off);
41
}
42
}
35
}
43
36
44
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
37
switch (ctx->type) {
45
* Load the TLB addend for use on the fast path.
38
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
46
* Do this asap to minimize any load use delay.
47
*/
48
- if (TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) {
49
+ if (TCG_TARGET_REG_BITS == 64 || addr_type == TCG_TYPE_I32) {
50
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_REG_TMP1,
51
offsetof(CPUTLBEntry, addend));
52
}
39
}
53
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
40
54
}
41
/* Inserting a value into zero at offset 0. */
55
42
- if (arg_is_const_val(op->args[1], 0) && op->args[3] == 0) {
56
/* Mask the address for the requested alignment. */
43
- uint64_t mask = MAKE_64BIT_MASK(0, op->args[4]);
57
- if (TARGET_LONG_BITS == 32) {
44
+ if (ti_is_const_val(t1, 0) && ofs == 0) {
58
+ if (addr_type == TCG_TYPE_I32) {
45
+ uint64_t mask = MAKE_64BIT_MASK(0, len);
59
tcg_out_rlw(s, RLWINM, TCG_REG_R0, t, 0,
46
60
(32 - a_bits) & 31, 31 - s->page_bits);
47
op->opc = and_opc;
61
} else if (a_bits == 0) {
48
op->args[1] = op->args[2];
62
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
49
op->args[2] = arg_new_constant(ctx, mask);
63
}
50
- ctx->z_mask = mask & arg_info(op->args[1])->z_mask;
51
- return false;
52
+ return fold_and(ctx, op);
64
}
53
}
65
54
66
- if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
55
/* Inserting zero into a value. */
67
+ if (TCG_TARGET_REG_BITS == 32 && addr_type != TCG_TYPE_I32) {
56
- if (arg_is_const_val(op->args[2], 0)) {
68
/* Low part comparison into cr7. */
57
- uint64_t mask = deposit64(-1, op->args[3], op->args[4], 0);
69
tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2,
58
+ if (ti_is_const_val(t2, 0)) {
70
0, 7, TCG_TYPE_I32);
59
+ uint64_t mask = deposit64(-1, ofs, len, 0);
71
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
60
72
tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
61
op->opc = and_opc;
73
} else {
62
op->args[2] = arg_new_constant(ctx, mask);
74
/* Full comparison into cr7. */
63
- ctx->z_mask = mask & arg_info(op->args[1])->z_mask;
75
- tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2,
64
- return false;
76
- 0, 7, TCG_TYPE_TL);
65
+ return fold_and(ctx, op);
77
+ tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2, 0, 7, addr_type);
78
}
66
}
79
67
80
/* Load a pointer into the current opcode w/conditional branch-link. */
68
- ctx->z_mask = deposit64(arg_info(op->args[1])->z_mask,
81
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
69
- op->args[3], op->args[4],
82
h->base = guest_base ? TCG_GUEST_BASE_REG : 0;
70
- arg_info(op->args[2])->z_mask);
83
#endif
71
- return false;
84
72
+ z_mask = deposit64(t1->z_mask, ofs, len, t2->z_mask);
85
- if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
73
+ return fold_masks_z(ctx, op, z_mask);
86
+ if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
74
}
87
/* Zero-extend the guest address for use in the host address. */
75
88
tcg_out_ext32u(s, TCG_REG_R0, addrlo);
76
static bool fold_divide(OptContext *ctx, TCGOp *op)
89
h->index = TCG_REG_R0;
90
--
77
--
91
2.34.1
78
2.43.0
diff view generated by jsdifflib
New patch
1
The input which overlaps the sign bit of the output can
2
have its input s_mask propagated to the output s_mask.
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 | 14 ++++++++++++--
8
1 file changed, 12 insertions(+), 2 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_deposit(OptContext *ctx, TCGOp *op)
15
TempOptInfo *t2 = arg_info(op->args[2]);
16
int ofs = op->args[3];
17
int len = op->args[4];
18
+ int width;
19
TCGOpcode and_opc;
20
- uint64_t z_mask;
21
+ uint64_t z_mask, s_mask;
22
23
if (ti_is_const(t1) && ti_is_const(t2)) {
24
return tcg_opt_gen_movi(ctx, op, op->args[0],
25
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
26
switch (ctx->type) {
27
case TCG_TYPE_I32:
28
and_opc = INDEX_op_and_i32;
29
+ width = 32;
30
break;
31
case TCG_TYPE_I64:
32
and_opc = INDEX_op_and_i64;
33
+ width = 64;
34
break;
35
default:
36
g_assert_not_reached();
37
@@ -XXX,XX +XXX,XX @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
38
return fold_and(ctx, op);
39
}
40
41
+ /* The s_mask from the top portion of the deposit is still valid. */
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);
46
+ }
47
+
48
z_mask = deposit64(t1->z_mask, ofs, len, t2->z_mask);
49
- return fold_masks_z(ctx, op, z_mask);
50
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
51
}
52
53
static bool fold_divide(OptContext *ctx, TCGOp *op)
54
--
55
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 2 +-
5
1 file changed, 1 insertion(+), 1 deletion(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_divide(OptContext *ctx, TCGOp *op)
12
fold_xi_to_x(ctx, op, 1)) {
13
return true;
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_dup(OptContext *ctx, TCGOp *op)
20
--
21
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 4 ++--
5
1 file changed, 2 insertions(+), 2 deletions(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_dup(OptContext *ctx, TCGOp *op)
12
t = dup_const(TCGOP_VECE(op), t);
13
return tcg_opt_gen_movi(ctx, op, op->args[0], t);
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_dup2(OptContext *ctx, TCGOp *op)
20
@@ -XXX,XX +XXX,XX @@ static bool fold_dup2(OptContext *ctx, TCGOp *op)
21
op->opc = INDEX_op_dup_vec;
22
TCGOP_VECE(op) = MO_32;
23
}
24
- return false;
25
+ return finish_folding(ctx, op);
26
}
27
28
static bool fold_eqv(OptContext *ctx, TCGOp *op)
29
--
30
2.43.0
diff view generated by jsdifflib
1
The replacement isn't ideal, as the raw count of bits
1
Add fold_masks_s as a trivial wrapper around fold_masks_zs.
2
is not easily synced with exec/cpu-all.h, but it does
2
Avoid the use of the OptContext slots.
3
remove from tcg.h the target dependency on TARGET_PAGE_BITS_MIN
4
which is built into TLB_FLAGS_MASK.
5
3
6
Reviewed-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
6
---
9
include/exec/cpu-all.h | 3 +++
7
tcg/optimize.c | 13 ++++++++++---
10
include/tcg/tcg.h | 4 ----
8
1 file changed, 10 insertions(+), 3 deletions(-)
11
tcg/tcg-op-ldst.c | 18 ++++++++++++++++--
12
3 files changed, 19 insertions(+), 6 deletions(-)
13
9
14
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/cpu-all.h
12
--- a/tcg/optimize.c
17
+++ b/include/exec/cpu-all.h
13
+++ b/tcg/optimize.c
18
@@ -XXX,XX +XXX,XX @@ CPUArchState *cpu_copy(CPUArchState *env);
14
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_z(OptContext *ctx, TCGOp *op, uint64_t z_mask)
19
*
15
return fold_masks_zs(ctx, op, z_mask, 0);
20
* Use TARGET_PAGE_BITS_MIN so that these bits are constant
21
* when TARGET_PAGE_BITS_VARY is in effect.
22
+ *
23
+ * The count, if not the placement of these bits is known
24
+ * to tcg/tcg-op-ldst.c, check_max_alignment().
25
*/
26
/* Zero if TLB entry is valid. */
27
#define TLB_INVALID_MASK (1 << (TARGET_PAGE_BITS_MIN - 1))
28
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/tcg/tcg.h
31
+++ b/include/tcg/tcg.h
32
@@ -XXX,XX +XXX,XX @@ static inline unsigned get_alignment_bits(MemOp memop)
33
/* A specific alignment requirement. */
34
a = a >> MO_ASHIFT;
35
}
36
-#if defined(CONFIG_SOFTMMU)
37
- /* The requested alignment cannot overlap the TLB flags. */
38
- tcg_debug_assert((TLB_FLAGS_MASK & ((1 << a) - 1)) == 0);
39
-#endif
40
return a;
41
}
16
}
42
17
43
diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c
18
+static bool fold_masks_s(OptContext *ctx, TCGOp *op, uint64_t s_mask)
44
index XXXXXXX..XXXXXXX 100644
45
--- a/tcg/tcg-op-ldst.c
46
+++ b/tcg/tcg-op-ldst.c
47
@@ -XXX,XX +XXX,XX @@
48
#include "tcg-internal.h"
49
50
51
-static inline MemOp tcg_canonicalize_memop(MemOp op, bool is64, bool st)
52
+static void check_max_alignment(unsigned a_bits)
53
+{
19
+{
54
+#if defined(CONFIG_SOFTMMU)
20
+ return fold_masks_zs(ctx, op, -1, s_mask);
55
+ /*
56
+ * The requested alignment cannot overlap the TLB flags.
57
+ * FIXME: Must keep the count up-to-date with "exec/cpu-all.h".
58
+ */
59
+ tcg_debug_assert(a_bits + 6 <= tcg_ctx->page_bits);
60
+#endif
61
+}
21
+}
62
+
22
+
63
+static MemOp tcg_canonicalize_memop(MemOp op, bool is64, bool st)
23
static bool fold_masks(OptContext *ctx, TCGOp *op)
64
{
24
{
65
- /* Trigger the asserts within as early as possible. */
25
return fold_masks_zs(ctx, op, ctx->z_mask, ctx->s_mask);
66
unsigned a_bits = get_alignment_bits(op);
26
@@ -XXX,XX +XXX,XX @@ static bool fold_dup2(OptContext *ctx, TCGOp *op)
67
27
68
+ check_max_alignment(a_bits);
28
static bool fold_eqv(OptContext *ctx, TCGOp *op)
29
{
30
+ uint64_t s_mask;
69
+
31
+
70
/* Prefer MO_ALIGN+MO_XX over MO_ALIGN_XX+MO_XX */
32
if (fold_const2_commutative(ctx, op) ||
71
if (a_bits == (op & MO_SIZE)) {
33
fold_xi_to_x(ctx, op, -1) ||
72
op = (op & ~MO_AMASK) | MO_ALIGN;
34
fold_xi_to_not(ctx, op, 0)) {
73
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
35
return true;
74
TCGv_i64 ext_addr = NULL;
36
}
75
TCGOpcode opc;
37
76
38
- ctx->s_mask = arg_info(op->args[1])->s_mask
77
+ check_max_alignment(get_alignment_bits(memop));
39
- & arg_info(op->args[2])->s_mask;
78
tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
40
- return false;
79
41
+ s_mask = arg_info(op->args[1])->s_mask
80
/* TODO: For now, force 32-bit hosts to use the helper. */
42
+ & arg_info(op->args[2])->s_mask;
81
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
43
+ return fold_masks_s(ctx, op, s_mask);
82
TCGv_i64 ext_addr = NULL;
44
}
83
TCGOpcode opc;
45
84
46
static bool fold_extract(OptContext *ctx, TCGOp *op)
85
+ check_max_alignment(get_alignment_bits(memop));
86
tcg_gen_req_mo(TCG_MO_ST_LD | TCG_MO_ST_ST);
87
88
/* TODO: For now, force 32-bit hosts to use the helper. */
89
--
47
--
90
2.34.1
48
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 15 ++++++---------
7
1 file changed, 6 insertions(+), 9 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_eqv(OptContext *ctx, TCGOp *op)
14
static bool fold_extract(OptContext *ctx, TCGOp *op)
15
{
16
uint64_t z_mask_old, z_mask;
17
+ TempOptInfo *t1 = arg_info(op->args[1]);
18
int pos = op->args[2];
19
int len = op->args[3];
20
21
- if (arg_is_const(op->args[1])) {
22
- uint64_t t;
23
-
24
- t = arg_info(op->args[1])->val;
25
- t = extract64(t, pos, len);
26
- return tcg_opt_gen_movi(ctx, op, op->args[0], t);
27
+ if (ti_is_const(t1)) {
28
+ return tcg_opt_gen_movi(ctx, op, op->args[0],
29
+ extract64(ti_const_val(t1), pos, len));
30
}
31
32
- z_mask_old = arg_info(op->args[1])->z_mask;
33
+ z_mask_old = t1->z_mask;
34
z_mask = extract64(z_mask_old, pos, len);
35
if (pos == 0 && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
36
return true;
37
}
38
- ctx->z_mask = z_mask;
39
40
- return fold_masks(ctx, op);
41
+ return fold_masks_z(ctx, op, z_mask);
42
}
43
44
static bool fold_extract2(OptContext *ctx, TCGOp *op)
45
--
46
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 2 +-
5
1 file changed, 1 insertion(+), 1 deletion(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_extract2(OptContext *ctx, TCGOp *op)
12
}
13
return tcg_opt_gen_movi(ctx, op, op->args[0], v1 | v2);
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_exts(OptContext *ctx, TCGOp *op)
20
--
21
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Explicitly sign-extend z_mask instead of doing that manually.
1
3
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/optimize.c | 29 ++++++++++++-----------------
8
1 file changed, 12 insertions(+), 17 deletions(-)
9
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/optimize.c
13
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ static bool fold_extract2(OptContext *ctx, TCGOp *op)
15
16
static bool fold_exts(OptContext *ctx, TCGOp *op)
17
{
18
- uint64_t s_mask_old, s_mask, z_mask, sign;
19
+ uint64_t s_mask_old, s_mask, z_mask;
20
bool type_change = false;
21
+ TempOptInfo *t1;
22
23
if (fold_const1(ctx, op)) {
24
return true;
25
}
26
27
- z_mask = arg_info(op->args[1])->z_mask;
28
- s_mask = arg_info(op->args[1])->s_mask;
29
+ t1 = arg_info(op->args[1]);
30
+ z_mask = t1->z_mask;
31
+ s_mask = t1->s_mask;
32
s_mask_old = s_mask;
33
34
switch (op->opc) {
35
CASE_OP_32_64(ext8s):
36
- sign = INT8_MIN;
37
- z_mask = (uint8_t)z_mask;
38
+ s_mask |= INT8_MIN;
39
+ z_mask = (int8_t)z_mask;
40
break;
41
CASE_OP_32_64(ext16s):
42
- sign = INT16_MIN;
43
- z_mask = (uint16_t)z_mask;
44
+ s_mask |= INT16_MIN;
45
+ z_mask = (int16_t)z_mask;
46
break;
47
case INDEX_op_ext_i32_i64:
48
type_change = true;
49
QEMU_FALLTHROUGH;
50
case INDEX_op_ext32s_i64:
51
- sign = INT32_MIN;
52
- z_mask = (uint32_t)z_mask;
53
+ s_mask |= INT32_MIN;
54
+ z_mask = (int32_t)z_mask;
55
break;
56
default:
57
g_assert_not_reached();
58
}
59
60
- if (z_mask & sign) {
61
- z_mask |= sign;
62
- }
63
- s_mask |= sign << 1;
64
-
65
- ctx->z_mask = z_mask;
66
- ctx->s_mask = s_mask;
67
if (0 && !type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
68
return true;
69
}
70
71
- return fold_masks(ctx, op);
72
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
73
}
74
75
static bool fold_extu(OptContext *ctx, TCGOp *op)
76
--
77
2.43.0
diff view generated by jsdifflib
1
This is a step toward making TranslationBlock agnostic
1
Avoid the use of the OptContext slots.
2
to the address size of the guest.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.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
include/exec/exec-all.h | 4 ++--
6
tcg/optimize.c | 4 ++--
8
1 file changed, 2 insertions(+), 2 deletions(-)
7
1 file changed, 2 insertions(+), 2 deletions(-)
9
8
10
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.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/exec/exec-all.h
11
--- a/tcg/optimize.c
13
+++ b/include/exec/exec-all.h
12
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@ static bool fold_extu(OptContext *ctx, TCGOp *op)
15
addresses in userspace mode. Define tb_page_addr_t to be an appropriate
14
g_assert_not_reached();
16
type. */
15
}
17
#if defined(CONFIG_USER_ONLY)
16
18
-typedef abi_ulong tb_page_addr_t;
17
- ctx->z_mask = z_mask;
19
-#define TB_PAGE_ADDR_FMT TARGET_ABI_FMT_lx
18
if (!type_change && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
20
+typedef vaddr tb_page_addr_t;
19
return true;
21
+#define TB_PAGE_ADDR_FMT "%" VADDR_PRIx
20
}
22
#else
21
- return fold_masks(ctx, op);
23
typedef ram_addr_t tb_page_addr_t;
22
+
24
#define TB_PAGE_ADDR_FMT RAM_ADDR_FMT
23
+ return fold_masks_z(ctx, op, z_mask);
24
}
25
26
static bool fold_mb(OptContext *ctx, TCGOp *op)
25
--
27
--
26
2.34.1
28
2.43.0
27
28
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 19 +++++++++++--------
7
1 file changed, 11 insertions(+), 8 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_mov(OptContext *ctx, TCGOp *op)
14
15
static bool fold_movcond(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t z_mask, s_mask;
18
+ TempOptInfo *tt, *ft;
19
int i;
20
21
/* If true and false values are the same, eliminate the cmp. */
22
@@ -XXX,XX +XXX,XX @@ static bool fold_movcond(OptContext *ctx, TCGOp *op)
23
return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[4 - i]);
24
}
25
26
- ctx->z_mask = arg_info(op->args[3])->z_mask
27
- | arg_info(op->args[4])->z_mask;
28
- ctx->s_mask = arg_info(op->args[3])->s_mask
29
- & arg_info(op->args[4])->s_mask;
30
+ tt = arg_info(op->args[3]);
31
+ ft = arg_info(op->args[4]);
32
+ z_mask = tt->z_mask | ft->z_mask;
33
+ s_mask = tt->s_mask & ft->s_mask;
34
35
- if (arg_is_const(op->args[3]) && arg_is_const(op->args[4])) {
36
- uint64_t tv = arg_info(op->args[3])->val;
37
- uint64_t fv = arg_info(op->args[4])->val;
38
+ if (ti_is_const(tt) && ti_is_const(ft)) {
39
+ uint64_t tv = ti_const_val(tt);
40
+ uint64_t fv = ti_const_val(ft);
41
TCGOpcode opc, negopc = 0;
42
TCGCond cond = op->args[5];
43
44
@@ -XXX,XX +XXX,XX @@ static bool fold_movcond(OptContext *ctx, TCGOp *op)
45
}
46
}
47
}
48
- return false;
49
+
50
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
51
}
52
53
static bool fold_mul(OptContext *ctx, TCGOp *op)
54
--
55
2.43.0
diff view generated by jsdifflib
New patch
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/optimize.c | 6 +++---
5
1 file changed, 3 insertions(+), 3 deletions(-)
1
6
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/optimize.c
10
+++ b/tcg/optimize.c
11
@@ -XXX,XX +XXX,XX @@ static bool fold_mul(OptContext *ctx, TCGOp *op)
12
fold_xi_to_x(ctx, op, 1)) {
13
return true;
14
}
15
- return false;
16
+ return finish_folding(ctx, op);
17
}
18
19
static bool fold_mul_highpart(OptContext *ctx, TCGOp *op)
20
@@ -XXX,XX +XXX,XX @@ static bool fold_mul_highpart(OptContext *ctx, TCGOp *op)
21
fold_xi_to_i(ctx, op, 0)) {
22
return true;
23
}
24
- return false;
25
+ return finish_folding(ctx, op);
26
}
27
28
static bool fold_multiply2(OptContext *ctx, TCGOp *op)
29
@@ -XXX,XX +XXX,XX @@ static bool fold_multiply2(OptContext *ctx, TCGOp *op)
30
tcg_opt_gen_movi(ctx, op2, rh, h);
31
return true;
32
}
33
- return false;
34
+ return finish_folding(ctx, op);
35
}
36
37
static bool fold_nand(OptContext *ctx, TCGOp *op)
38
--
39
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 8 +++++---
7
1 file changed, 5 insertions(+), 3 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_multiply2(OptContext *ctx, TCGOp *op)
14
15
static bool fold_nand(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t s_mask;
18
+
19
if (fold_const2_commutative(ctx, op) ||
20
fold_xi_to_not(ctx, op, -1)) {
21
return true;
22
}
23
24
- ctx->s_mask = arg_info(op->args[1])->s_mask
25
- & arg_info(op->args[2])->s_mask;
26
- return false;
27
+ s_mask = arg_info(op->args[1])->s_mask
28
+ & arg_info(op->args[2])->s_mask;
29
+ return fold_masks_s(ctx, op, s_mask);
30
}
31
32
static bool fold_neg_no_const(OptContext *ctx, TCGOp *op)
33
--
34
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 9 ++-------
7
1 file changed, 2 insertions(+), 7 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_neg_no_const(OptContext *ctx, TCGOp *op)
14
{
15
/* Set to 1 all bits to the left of the rightmost. */
16
uint64_t z_mask = arg_info(op->args[1])->z_mask;
17
- ctx->z_mask = -(z_mask & -z_mask);
18
+ z_mask = -(z_mask & -z_mask);
19
20
- /*
21
- * Because of fold_sub_to_neg, we want to always return true,
22
- * via finish_folding.
23
- */
24
- finish_folding(ctx, op);
25
- return true;
26
+ return fold_masks_z(ctx, op, z_mask);
27
}
28
29
static bool fold_neg(OptContext *ctx, TCGOp *op)
30
--
31
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 8 +++++---
7
1 file changed, 5 insertions(+), 3 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_neg(OptContext *ctx, TCGOp *op)
14
15
static bool fold_nor(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t s_mask;
18
+
19
if (fold_const2_commutative(ctx, op) ||
20
fold_xi_to_not(ctx, op, 0)) {
21
return true;
22
}
23
24
- ctx->s_mask = arg_info(op->args[1])->s_mask
25
- & arg_info(op->args[2])->s_mask;
26
- return false;
27
+ s_mask = arg_info(op->args[1])->s_mask
28
+ & arg_info(op->args[2])->s_mask;
29
+ return fold_masks_s(ctx, op, s_mask);
30
}
31
32
static bool fold_not(OptContext *ctx, TCGOp *op)
33
--
34
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 7 +------
7
1 file changed, 1 insertion(+), 6 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_not(OptContext *ctx, TCGOp *op)
14
if (fold_const1(ctx, op)) {
15
return true;
16
}
17
-
18
- ctx->s_mask = arg_info(op->args[1])->s_mask;
19
-
20
- /* Because of fold_to_not, we want to always return true, via finish. */
21
- finish_folding(ctx, op);
22
- return true;
23
+ return fold_masks_s(ctx, op, arg_info(op->args[1])->s_mask);
24
}
25
26
static bool fold_or(OptContext *ctx, TCGOp *op)
27
--
28
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 13 ++++++++-----
7
1 file changed, 8 insertions(+), 5 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_not(OptContext *ctx, TCGOp *op)
14
15
static bool fold_or(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t z_mask, s_mask;
18
+ TempOptInfo *t1, *t2;
19
+
20
if (fold_const2_commutative(ctx, op) ||
21
fold_xi_to_x(ctx, op, 0) ||
22
fold_xx_to_x(ctx, op)) {
23
return true;
24
}
25
26
- ctx->z_mask = arg_info(op->args[1])->z_mask
27
- | arg_info(op->args[2])->z_mask;
28
- ctx->s_mask = arg_info(op->args[1])->s_mask
29
- & arg_info(op->args[2])->s_mask;
30
- return fold_masks(ctx, op);
31
+ t1 = arg_info(op->args[1]);
32
+ t2 = arg_info(op->args[2]);
33
+ z_mask = t1->z_mask | t2->z_mask;
34
+ s_mask = t1->s_mask & t2->s_mask;
35
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
36
}
37
38
static bool fold_orc(OptContext *ctx, TCGOp *op)
39
--
40
2.43.0
diff view generated by jsdifflib
New patch
1
Avoid the use of the OptContext slots.
1
2
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 8 +++++---
7
1 file changed, 5 insertions(+), 3 deletions(-)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static bool fold_or(OptContext *ctx, TCGOp *op)
14
15
static bool fold_orc(OptContext *ctx, TCGOp *op)
16
{
17
+ uint64_t s_mask;
18
+
19
if (fold_const2(ctx, op) ||
20
fold_xx_to_i(ctx, op, -1) ||
21
fold_xi_to_x(ctx, op, -1) ||
22
@@ -XXX,XX +XXX,XX @@ static bool fold_orc(OptContext *ctx, TCGOp *op)
23
return true;
24
}
25
26
- ctx->s_mask = arg_info(op->args[1])->s_mask
27
- & arg_info(op->args[2])->s_mask;
28
- return false;
29
+ s_mask = arg_info(op->args[1])->s_mask
30
+ & arg_info(op->args[2])->s_mask;
31
+ return fold_masks_s(ctx, op, s_mask);
32
}
33
34
static bool fold_qemu_ld(OptContext *ctx, TCGOp *op)
35
--
36
2.43.0
diff view generated by jsdifflib
1
This function is only used in translator.c, and uses a
1
Avoid the use of the OptContext slots.
2
target-specific typedef: abi_ptr.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
9
---
7
include/exec/plugin-gen.h | 22 ----------------------
10
tcg/optimize.c | 26 +++++++++++++++++++++-----
8
accel/tcg/translator.c | 21 +++++++++++++++++++++
11
1 file changed, 21 insertions(+), 5 deletions(-)
9
2 files changed, 21 insertions(+), 22 deletions(-)
10
12
11
diff --git a/include/exec/plugin-gen.h b/include/exec/plugin-gen.h
13
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/include/exec/plugin-gen.h
15
--- a/tcg/optimize.c
14
+++ b/include/exec/plugin-gen.h
16
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@ void plugin_gen_insn_end(void);
17
@@ -XXX,XX +XXX,XX @@ static bool fold_orc(OptContext *ctx, TCGOp *op)
16
void plugin_gen_disable_mem_helpers(void);
18
return fold_masks_s(ctx, op, s_mask);
17
void plugin_gen_empty_mem_callback(TCGv_i64 addr, uint32_t info);
18
19
-static inline void plugin_insn_append(abi_ptr pc, const void *from, size_t size)
20
-{
21
- struct qemu_plugin_insn *insn = tcg_ctx->plugin_insn;
22
- abi_ptr off;
23
-
24
- if (insn == NULL) {
25
- return;
26
- }
27
- off = pc - insn->vaddr;
28
- if (off < insn->data->len) {
29
- g_byte_array_set_size(insn->data, off);
30
- } else if (off > insn->data->len) {
31
- /* we have an unexpected gap */
32
- g_assert_not_reached();
33
- }
34
-
35
- insn->data = g_byte_array_append(insn->data, from, size);
36
-}
37
-
38
#else /* !CONFIG_PLUGIN */
39
40
static inline bool
41
@@ -XXX,XX +XXX,XX @@ static inline void plugin_gen_disable_mem_helpers(void)
42
static inline void plugin_gen_empty_mem_callback(TCGv_i64 addr, uint32_t info)
43
{ }
44
45
-static inline void plugin_insn_append(abi_ptr pc, const void *from, size_t size)
46
-{ }
47
-
48
#endif /* CONFIG_PLUGIN */
49
50
#endif /* QEMU_PLUGIN_GEN_H */
51
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/accel/tcg/translator.c
54
+++ b/accel/tcg/translator.c
55
@@ -XXX,XX +XXX,XX @@ static void *translator_access(CPUArchState *env, DisasContextBase *db,
56
return host + (pc - base);
57
}
19
}
58
20
59
+static void plugin_insn_append(abi_ptr pc, const void *from, size_t size)
21
-static bool fold_qemu_ld(OptContext *ctx, TCGOp *op)
60
+{
22
+static bool fold_qemu_ld_1reg(OptContext *ctx, TCGOp *op)
61
+#ifdef CONFIG_PLUGIN
23
{
62
+ struct qemu_plugin_insn *insn = tcg_ctx->plugin_insn;
24
const TCGOpDef *def = &tcg_op_defs[op->opc];
63
+ abi_ptr off;
25
MemOpIdx oi = op->args[def->nb_oargs + def->nb_iargs];
26
MemOp mop = get_memop(oi);
27
int width = 8 * memop_size(mop);
28
+ uint64_t z_mask = -1, s_mask = 0;
29
30
if (width < 64) {
31
if (mop & MO_SIGN) {
32
- ctx->s_mask = MAKE_64BIT_MASK(width, 64 - width);
33
+ s_mask = MAKE_64BIT_MASK(width - 1, 64 - (width - 1));
34
} else {
35
- ctx->z_mask = MAKE_64BIT_MASK(0, width);
36
+ z_mask = MAKE_64BIT_MASK(0, width);
37
}
38
}
39
40
/* Opcodes that touch guest memory stop the mb optimization. */
41
ctx->prev_mb = NULL;
42
- return false;
64
+
43
+
65
+ if (insn == NULL) {
44
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
66
+ return;
67
+ }
68
+ off = pc - insn->vaddr;
69
+ if (off < insn->data->len) {
70
+ g_byte_array_set_size(insn->data, off);
71
+ } else if (off > insn->data->len) {
72
+ /* we have an unexpected gap */
73
+ g_assert_not_reached();
74
+ }
75
+
76
+ insn->data = g_byte_array_append(insn->data, from, size);
77
+#endif
78
+}
45
+}
79
+
46
+
80
uint8_t translator_ldub(CPUArchState *env, DisasContextBase *db, abi_ptr pc)
47
+static bool fold_qemu_ld_2reg(OptContext *ctx, TCGOp *op)
81
{
48
+{
82
uint8_t ret;
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:
83
--
75
--
84
2.34.1
76
2.43.0
85
86
diff view generated by jsdifflib
1
New wrapper around gen_io_start which takes care of the USE_ICOUNT
1
Stores have no output operands, and so need no further work.
2
check, as well as marking the DisasContext to end the TB.
3
Remove exec/gen-icount.h.
4
2
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
5
---
8
MAINTAINERS | 1 -
6
tcg/optimize.c | 11 +++++------
9
include/exec/gen-icount.h | 6 --
7
1 file changed, 5 insertions(+), 6 deletions(-)
10
include/exec/translator.h | 10 +++
11
target/arm/cpregs.h | 4 +-
12
accel/tcg/translator.c | 27 ++++++-
13
target/alpha/translate.c | 15 +---
14
target/arm/tcg/translate-a64.c | 23 +++---
15
target/arm/tcg/translate-mve.c | 1 -
16
target/arm/tcg/translate-neon.c | 1 -
17
target/arm/tcg/translate-vfp.c | 4 +-
18
target/arm/tcg/translate.c | 20 ++---
19
target/avr/translate.c | 1 -
20
target/cris/translate.c | 2 -
21
target/hppa/translate.c | 5 +-
22
target/i386/tcg/translate.c | 52 +++----------
23
target/loongarch/translate.c | 2 -
24
target/m68k/translate.c | 2 -
25
target/microblaze/translate.c | 2 -
26
target/mips/tcg/translate.c | 29 +++----
27
target/nios2/translate.c | 1 -
28
target/openrisc/translate.c | 9 +--
29
target/ppc/translate.c | 13 +---
30
target/riscv/translate.c | 2 -
31
target/rx/translate.c | 2 -
32
target/s390x/tcg/translate.c | 6 +-
33
target/sh4/translate.c | 2 -
34
target/sparc/translate.c | 75 +++++--------------
35
target/tricore/translate.c | 2 -
36
target/xtensa/translate.c | 27 ++-----
37
target/loongarch/insn_trans/trans_extra.c.inc | 4 +-
38
.../insn_trans/trans_privileged.c.inc | 4 +-
39
.../riscv/insn_trans/trans_privileged.c.inc | 8 +-
40
target/riscv/insn_trans/trans_rvi.c.inc | 24 ++----
41
33 files changed, 117 insertions(+), 269 deletions(-)
42
delete mode 100644 include/exec/gen-icount.h
43
8
44
diff --git a/MAINTAINERS b/MAINTAINERS
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
45
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
46
--- a/MAINTAINERS
11
--- a/tcg/optimize.c
47
+++ b/MAINTAINERS
12
+++ b/tcg/optimize.c
48
@@ -XXX,XX +XXX,XX @@ F: ui/cocoa.m
13
@@ -XXX,XX +XXX,XX @@ static bool fold_qemu_st(OptContext *ctx, TCGOp *op)
49
Main loop
50
M: Paolo Bonzini <pbonzini@redhat.com>
51
S: Maintained
52
-F: include/exec/gen-icount.h
53
F: include/qemu/main-loop.h
54
F: include/sysemu/runstate.h
55
F: include/sysemu/runstate-action.h
56
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
57
deleted file mode 100644
58
index XXXXXXX..XXXXXXX
59
--- a/include/exec/gen-icount.h
60
+++ /dev/null
61
@@ -XXX,XX +XXX,XX @@
62
-#ifndef GEN_ICOUNT_H
63
-#define GEN_ICOUNT_H
64
-
65
-void gen_io_start(void);
66
-
67
-#endif
68
diff --git a/include/exec/translator.h b/include/exec/translator.h
69
index XXXXXXX..XXXXXXX 100644
70
--- a/include/exec/translator.h
71
+++ b/include/exec/translator.h
72
@@ -XXX,XX +XXX,XX @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
73
*/
74
bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest);
75
76
+/**
77
+ * translator_io_start
78
+ * @db: Disassembly context
79
+ *
80
+ * If icount is enabled, set cpu->can_to_io, adjust db->is_jmp to
81
+ * DISAS_TOO_MANY if it is still DISAS_NEXT, and return true.
82
+ * Otherwise return false.
83
+ */
84
+bool translator_io_start(DisasContextBase *db);
85
+
86
/*
87
* Translator Load Functions
88
*
89
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/cpregs.h
92
+++ b/target/arm/cpregs.h
93
@@ -XXX,XX +XXX,XX @@ enum {
94
ARM_CP_ALIAS = 1 << 8,
95
/*
96
* Flag: Register does I/O and therefore its accesses need to be marked
97
- * with gen_io_start() and also end the TB. In particular, registers which
98
- * implement clocks or timers require this.
99
+ * with translator_io_start() and also end the TB. In particular,
100
+ * registers which implement clocks or timers require this.
101
*/
102
ARM_CP_IO = 1 << 9,
103
/*
104
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/accel/tcg/translator.c
107
+++ b/accel/tcg/translator.c
108
@@ -XXX,XX +XXX,XX @@
109
#include "tcg/tcg.h"
110
#include "tcg/tcg-op.h"
111
#include "exec/exec-all.h"
112
-#include "exec/gen-icount.h"
113
#include "exec/log.h"
114
#include "exec/translator.h"
115
#include "exec/plugin-gen.h"
116
#include "exec/replay-core.h"
117
118
119
-void gen_io_start(void)
120
+static void gen_io_start(void)
121
{
14
{
122
tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
15
/* Opcodes that touch guest memory stop the mb optimization. */
123
offsetof(ArchCPU, parent_obj.can_do_io) -
16
ctx->prev_mb = NULL;
124
offsetof(ArchCPU, env));
17
- return false;
18
+ return true;
125
}
19
}
126
20
127
+bool translator_io_start(DisasContextBase *db)
21
static bool fold_remainder(OptContext *ctx, TCGOp *op)
128
+{
22
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st(OptContext *ctx, TCGOp *op)
129
+ uint32_t cflags = tb_cflags(db->tb);
23
130
+
24
if (op->args[1] != tcgv_ptr_arg(tcg_env)) {
131
+ if (!(cflags & CF_USE_ICOUNT)) {
25
remove_mem_copy_all(ctx);
132
+ return false;
26
- return false;
133
+ }
134
+ if (db->num_insns == db->max_insns && (cflags & CF_LAST_IO)) {
135
+ /* Already started in translator_loop. */
136
+ return true;
27
+ return true;
137
+ }
138
+
139
+ gen_io_start();
140
+
141
+ /*
142
+ * Ensure that this instruction will be the last in the TB.
143
+ * The target may override this to something more forceful.
144
+ */
145
+ if (db->is_jmp == DISAS_NEXT) {
146
+ db->is_jmp = DISAS_TOO_MANY;
147
+ }
148
+ return true;
149
+}
150
+
151
static TCGOp *gen_tb_start(uint32_t cflags)
152
{
153
TCGv_i32 count = tcg_temp_new_i32();
154
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/target/alpha/translate.c
157
+++ b/target/alpha/translate.c
158
@@ -XXX,XX +XXX,XX @@ static TCGv cpu_lock_value;
159
static TCGv cpu_pal_ir[31];
160
#endif
161
162
-#include "exec/gen-icount.h"
163
-
164
void alpha_translate_init(void)
165
{
166
#define DEF_VAR(V) { &cpu_##V, #V, offsetof(CPUAlphaState, V) }
167
@@ -XXX,XX +XXX,XX @@ static DisasJumpType gen_mfpr(DisasContext *ctx, TCGv va, int regno)
168
case 249: /* VMTIME */
169
helper = gen_helper_get_vmtime;
170
do_helper:
171
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
172
- gen_io_start();
173
+ if (translator_io_start(&ctx->base)) {
174
helper(va);
175
return DISAS_PC_STALE;
176
} else {
177
@@ -XXX,XX +XXX,XX @@ static DisasJumpType gen_mtpr(DisasContext *ctx, TCGv vb, int regno)
178
179
case 251:
180
/* ALARM */
181
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
182
- gen_io_start();
183
+ if (translator_io_start(&ctx->base)) {
184
ret = DISAS_PC_STALE;
185
}
186
gen_helper_set_alarm(cpu_env, vb);
187
@@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
188
case 0xC000:
189
/* RPCC */
190
va = dest_gpr(ctx, ra);
191
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
192
- gen_io_start();
193
- gen_helper_load_pcc(va, cpu_env);
194
+ if (translator_io_start(&ctx->base)) {
195
ret = DISAS_PC_STALE;
196
- } else {
197
- gen_helper_load_pcc(va, cpu_env);
198
}
199
+ gen_helper_load_pcc(va, cpu_env);
200
break;
201
case 0xE000:
202
/* RC */
203
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
204
index XXXXXXX..XXXXXXX 100644
205
--- a/target/arm/tcg/translate-a64.c
206
+++ b/target/arm/tcg/translate-a64.c
207
@@ -XXX,XX +XXX,XX @@
208
#include "internals.h"
209
#include "qemu/host-utils.h"
210
#include "semihosting/semihost.h"
211
-#include "exec/gen-icount.h"
212
#include "exec/log.h"
213
#include "cpregs.h"
214
#include "translate-a64.h"
215
@@ -XXX,XX +XXX,XX @@ static bool trans_ERET(DisasContext *s, arg_ERET *a)
216
tcg_gen_ld_i64(dst, cpu_env,
217
offsetof(CPUARMState, elr_el[s->current_el]));
218
219
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
220
- gen_io_start();
221
- }
222
+ translator_io_start(&s->base);
223
224
gen_helper_exception_return(cpu_env, dst);
225
/* Must exit loop to check un-masked IRQs */
226
@@ -XXX,XX +XXX,XX @@ static bool trans_ERETA(DisasContext *s, arg_reta *a)
227
offsetof(CPUARMState, elr_el[s->current_el]));
228
229
dst = auth_branch_target(s, dst, cpu_X[31], !a->m);
230
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
231
- gen_io_start();
232
- }
233
+
234
+ translator_io_start(&s->base);
235
236
gen_helper_exception_return(cpu_env, dst);
237
/* Must exit loop to check un-masked IRQs */
238
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
239
uint32_t key = ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
240
crn, crm, op0, op1, op2);
241
const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
242
+ bool need_exit_tb = false;
243
TCGv_ptr tcg_ri = NULL;
244
TCGv_i64 tcg_rt;
245
246
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
247
return;
248
}
28
}
249
29
250
- if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
30
switch (op->opc) {
251
- gen_io_start();
31
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st(OptContext *ctx, TCGOp *op)
252
+ if (ri->type & ARM_CP_IO) {
253
+ /* I/O operations must end the TB here (whether read or write) */
254
+ need_exit_tb = translator_io_start(&s->base);
255
}
256
257
tcg_rt = cpu_reg(s, rt);
258
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
259
}
260
}
261
262
- if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
263
- /* I/O operations must end the TB here (whether read or write) */
264
- s->base.is_jmp = DISAS_UPDATE_EXIT;
265
- }
266
if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
267
/*
268
* A write to any coprocessor regiser that ends a TB
269
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
270
* but allow this to be suppressed by the register definition
271
* (usually only necessary to work around guest bugs).
272
*/
273
+ need_exit_tb = true;
274
+ }
275
+ if (need_exit_tb) {
276
s->base.is_jmp = DISAS_UPDATE_EXIT;
277
}
278
}
279
diff --git a/target/arm/tcg/translate-mve.c b/target/arm/tcg/translate-mve.c
280
index XXXXXXX..XXXXXXX 100644
281
--- a/target/arm/tcg/translate-mve.c
282
+++ b/target/arm/tcg/translate-mve.c
283
@@ -XXX,XX +XXX,XX @@
284
#include "tcg/tcg-op.h"
285
#include "tcg/tcg-op-gvec.h"
286
#include "exec/exec-all.h"
287
-#include "exec/gen-icount.h"
288
#include "translate.h"
289
#include "translate-a32.h"
290
291
diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c
292
index XXXXXXX..XXXXXXX 100644
293
--- a/target/arm/tcg/translate-neon.c
294
+++ b/target/arm/tcg/translate-neon.c
295
@@ -XXX,XX +XXX,XX @@
296
#include "tcg/tcg-op.h"
297
#include "tcg/tcg-op-gvec.h"
298
#include "exec/exec-all.h"
299
-#include "exec/gen-icount.h"
300
#include "translate.h"
301
#include "translate-a32.h"
302
303
diff --git a/target/arm/tcg/translate-vfp.c b/target/arm/tcg/translate-vfp.c
304
index XXXXXXX..XXXXXXX 100644
305
--- a/target/arm/tcg/translate-vfp.c
306
+++ b/target/arm/tcg/translate-vfp.c
307
@@ -XXX,XX +XXX,XX @@
308
#include "tcg/tcg-op.h"
309
#include "tcg/tcg-op-gvec.h"
310
#include "exec/exec-all.h"
311
-#include "exec/gen-icount.h"
312
#include "translate.h"
313
#include "translate-a32.h"
314
315
@@ -XXX,XX +XXX,XX @@ static void gen_preserve_fp_state(DisasContext *s, bool skip_context_update)
316
* so we must mark it as an IO operation for icount (and cause
317
* this to be the last insn in the TB).
318
*/
319
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
320
+ if (translator_io_start(&s->base)) {
321
s->base.is_jmp = DISAS_UPDATE_EXIT;
322
- gen_io_start();
323
}
324
gen_helper_v7m_preserve_fp_state(cpu_env);
325
/*
326
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
327
index XXXXXXX..XXXXXXX 100644
328
--- a/target/arm/tcg/translate.c
329
+++ b/target/arm/tcg/translate.c
330
@@ -XXX,XX +XXX,XX @@
331
#include "cpregs.h"
332
#include "translate.h"
333
#include "translate-a32.h"
334
-#include "exec/gen-icount.h"
335
#include "exec/helper-proto.h"
336
337
#define HELPER_H "helper.h"
338
@@ -XXX,XX +XXX,XX @@ static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
339
* appropriately depending on the new Thumb bit, so it must
340
* be called after storing the new PC.
341
*/
342
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
343
- gen_io_start();
344
- }
345
+ translator_io_start(&s->base);
346
gen_helper_cpsr_write_eret(cpu_env, cpsr);
347
/* Must exit loop to check un-masked IRQs */
348
s->base.is_jmp = DISAS_EXIT;
349
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
350
uint32_t key = ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2);
351
const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
352
TCGv_ptr tcg_ri = NULL;
353
- bool need_exit_tb;
354
+ bool need_exit_tb = false;
355
uint32_t syndrome;
356
357
/*
358
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
359
g_assert_not_reached();
32
g_assert_not_reached();
360
}
33
}
361
34
remove_mem_copy_in(ctx, ofs, ofs + lm1);
362
- if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
35
- return false;
363
- gen_io_start();
36
+ return true;
364
+ if (ri->type & ARM_CP_IO) {
37
}
365
+ /* I/O operations must end the TB here (whether read or write) */
38
366
+ need_exit_tb = translator_io_start(&s->base);
39
static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
40
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
41
TCGType type;
42
43
if (op->args[1] != tcgv_ptr_arg(tcg_env)) {
44
- fold_tcg_st(ctx, op);
45
- return false;
46
+ return fold_tcg_st(ctx, op);
367
}
47
}
368
48
369
if (isread) {
49
src = arg_temp(op->args[0]);
370
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
50
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op)
371
}
51
last = ofs + tcg_type_size(type) - 1;
372
}
52
remove_mem_copy_in(ctx, ofs, last);
373
53
record_mem_copy(ctx, type, src, ofs, last);
374
- /* I/O operations must end the TB here (whether read or write) */
54
- return false;
375
- need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
55
+ return true;
376
- (ri->type & ARM_CP_IO));
377
-
378
if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
379
/*
380
* A write to any coprocessor register that ends a TB
381
@@ -XXX,XX +XXX,XX @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
382
if (exc_return) {
383
/* Restore CPSR from SPSR. */
384
tmp = load_cpu_field(spsr);
385
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
386
- gen_io_start();
387
- }
388
+ translator_io_start(&s->base);
389
gen_helper_cpsr_write_eret(cpu_env, tmp);
390
/* Must exit loop to check un-masked IRQs */
391
s->base.is_jmp = DISAS_EXIT;
392
diff --git a/target/avr/translate.c b/target/avr/translate.c
393
index XXXXXXX..XXXXXXX 100644
394
--- a/target/avr/translate.c
395
+++ b/target/avr/translate.c
396
@@ -XXX,XX +XXX,XX @@
397
#include "exec/helper-gen.h"
398
#include "exec/log.h"
399
#include "exec/translator.h"
400
-#include "exec/gen-icount.h"
401
402
#define HELPER_H "helper.h"
403
#include "exec/helper-info.c.inc"
404
diff --git a/target/cris/translate.c b/target/cris/translate.c
405
index XXXXXXX..XXXXXXX 100644
406
--- a/target/cris/translate.c
407
+++ b/target/cris/translate.c
408
@@ -XXX,XX +XXX,XX @@ static TCGv env_btaken;
409
static TCGv env_btarget;
410
static TCGv env_pc;
411
412
-#include "exec/gen-icount.h"
413
-
414
/* This is the state at translation time. */
415
typedef struct DisasContext {
416
DisasContextBase base;
417
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
418
index XXXXXXX..XXXXXXX 100644
419
--- a/target/hppa/translate.c
420
+++ b/target/hppa/translate.c
421
@@ -XXX,XX +XXX,XX @@ static TCGv_reg cpu_psw_v;
422
static TCGv_reg cpu_psw_cb;
423
static TCGv_reg cpu_psw_cb_msb;
424
425
-#include "exec/gen-icount.h"
426
-
427
void hppa_translate_init(void)
428
{
429
#define DEF_VAR(V) { &cpu_##V, #V, offsetof(CPUHPPAState, V) }
430
@@ -XXX,XX +XXX,XX @@ static bool trans_mfctl(DisasContext *ctx, arg_mfctl *a)
431
/* FIXME: Respect PSW_S bit. */
432
nullify_over(ctx);
433
tmp = dest_gpr(ctx, rt);
434
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
435
- gen_io_start();
436
+ if (translator_io_start(&ctx->base)) {
437
gen_helper_read_interval_timer(tmp);
438
ctx->base.is_jmp = DISAS_IAQ_N_STALE;
439
} else {
440
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
441
index XXXXXXX..XXXXXXX 100644
442
--- a/target/i386/tcg/translate.c
443
+++ b/target/i386/tcg/translate.c
444
@@ -XXX,XX +XXX,XX @@ static TCGv cpu_seg_base[6];
445
static TCGv_i64 cpu_bndl[4];
446
static TCGv_i64 cpu_bndu[4];
447
448
-#include "exec/gen-icount.h"
449
-
450
typedef struct DisasContext {
451
DisasContextBase base;
452
453
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
454
!(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
455
goto illegal_op;
456
}
457
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
458
- gen_io_start();
459
- s->base.is_jmp = DISAS_TOO_MANY;
460
- }
461
+ translator_io_start(&s->base);
462
gen_helper_rdrand(s->T0, cpu_env);
463
rm = (modrm & 7) | REX_B(s);
464
gen_op_mov_reg_v(s, dflag, rm, s->T0);
465
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
466
SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
467
break;
468
}
469
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
470
- gen_io_start();
471
- s->base.is_jmp = DISAS_TOO_MANY;
472
- }
473
+ translator_io_start(&s->base);
474
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
475
gen_repz_ins(s, ot);
476
} else {
477
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
478
if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_STR_MASK)) {
479
break;
480
}
481
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
482
- gen_io_start();
483
- s->base.is_jmp = DISAS_TOO_MANY;
484
- }
485
+ translator_io_start(&s->base);
486
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
487
gen_repz_outs(s, ot);
488
} else {
489
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
490
if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
491
break;
492
}
493
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
494
- gen_io_start();
495
- s->base.is_jmp = DISAS_TOO_MANY;
496
- }
497
+ translator_io_start(&s->base);
498
gen_helper_in_func(ot, s->T1, s->tmp2_i32);
499
gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
500
gen_bpt_io(s, s->tmp2_i32, ot);
501
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
502
if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
503
break;
504
}
505
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
506
- gen_io_start();
507
- s->base.is_jmp = DISAS_TOO_MANY;
508
- }
509
+ translator_io_start(&s->base);
510
gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
511
tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
512
gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
513
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
514
if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
515
break;
516
}
517
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
518
- gen_io_start();
519
- s->base.is_jmp = DISAS_TOO_MANY;
520
- }
521
+ translator_io_start(&s->base);
522
gen_helper_in_func(ot, s->T1, s->tmp2_i32);
523
gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
524
gen_bpt_io(s, s->tmp2_i32, ot);
525
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
526
if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
527
break;
528
}
529
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
530
- gen_io_start();
531
- s->base.is_jmp = DISAS_TOO_MANY;
532
- }
533
+ translator_io_start(&s->base);
534
gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
535
tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
536
gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
537
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
538
case 0x131: /* rdtsc */
539
gen_update_cc_op(s);
540
gen_update_eip_cur(s);
541
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
542
- gen_io_start();
543
- s->base.is_jmp = DISAS_TOO_MANY;
544
- }
545
+ translator_io_start(&s->base);
546
gen_helper_rdtsc(cpu_env);
547
break;
548
case 0x133: /* rdpmc */
549
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
550
}
551
gen_update_cc_op(s);
552
gen_update_eip_cur(s);
553
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
554
- gen_io_start();
555
- s->base.is_jmp = DISAS_TOO_MANY;
556
- }
557
+ translator_io_start(&s->base);
558
gen_helper_rdtscp(cpu_env);
559
break;
560
561
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
562
}
563
ot = (CODE64(s) ? MO_64 : MO_32);
564
565
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
566
- gen_io_start();
567
- s->base.is_jmp = DISAS_TOO_MANY;
568
- }
569
+ translator_io_start(&s->base);
570
if (b & 2) {
571
gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
572
gen_op_mov_v_reg(s, ot, s->T0, rm);
573
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
574
index XXXXXXX..XXXXXXX 100644
575
--- a/target/loongarch/translate.c
576
+++ b/target/loongarch/translate.c
577
@@ -XXX,XX +XXX,XX @@
578
TCGv cpu_gpr[32], cpu_pc;
579
static TCGv cpu_lladdr, cpu_llval;
580
581
-#include "exec/gen-icount.h"
582
-
583
#define HELPER_H "helper.h"
584
#include "exec/helper-info.c.inc"
585
#undef HELPER_H
586
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
587
index XXXXXXX..XXXXXXX 100644
588
--- a/target/m68k/translate.c
589
+++ b/target/m68k/translate.c
590
@@ -XXX,XX +XXX,XX @@ static TCGv NULL_QREG;
591
/* Used to distinguish stores from bad addressing modes. */
592
static TCGv store_dummy;
593
594
-#include "exec/gen-icount.h"
595
-
596
void m68k_tcg_init(void)
597
{
598
char *p;
599
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
600
index XXXXXXX..XXXXXXX 100644
601
--- a/target/microblaze/translate.c
602
+++ b/target/microblaze/translate.c
603
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 cpu_iflags;
604
static TCGv cpu_res_addr;
605
static TCGv_i32 cpu_res_val;
606
607
-#include "exec/gen-icount.h"
608
-
609
/* This is the state at translation time. */
610
typedef struct DisasContext {
611
DisasContextBase base;
612
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
613
index XXXXXXX..XXXXXXX 100644
614
--- a/target/mips/tcg/translate.c
615
+++ b/target/mips/tcg/translate.c
616
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 hflags;
617
TCGv_i32 fpu_fcr0, fpu_fcr31;
618
TCGv_i64 fpu_f64[32];
619
620
-#include "exec/gen-icount.h"
621
-
622
static const char regnames_HI[][4] = {
623
"HI0", "HI1", "HI2", "HI3",
624
};
625
@@ -XXX,XX +XXX,XX @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
626
switch (sel) {
627
case CP0_REG09__COUNT:
628
/* Mark as an IO operation because we read the time. */
629
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630
- gen_io_start();
631
- }
632
+ translator_io_start(&ctx->base);
633
+
634
gen_helper_mfc0_count(arg, cpu_env);
635
/*
636
* Break the TB to be able to take timer interrupts immediately
637
@@ -XXX,XX +XXX,XX @@ cp0_unimplemented:
638
static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
639
{
640
const char *register_name = "invalid";
641
+ bool icount;
642
643
if (sel != 0) {
644
check_insn(ctx, ISA_MIPS_R1);
645
}
646
647
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
648
- gen_io_start();
649
- }
650
+ icount = translator_io_start(&ctx->base);
651
652
switch (reg) {
653
case CP0_REGISTER_00:
654
@@ -XXX,XX +XXX,XX @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
655
trace_mips_translate_c0("mtc0", register_name, reg, sel);
656
657
/* For simplicity assume that all writes can cause interrupts. */
658
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
659
+ if (icount) {
660
/*
661
* DISAS_STOP isn't sufficient, we need to ensure we break out of
662
* translated code to check for pending interrupts.
663
@@ -XXX,XX +XXX,XX @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
664
switch (sel) {
665
case CP0_REG09__COUNT:
666
/* Mark as an IO operation because we read the time. */
667
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
668
- gen_io_start();
669
- }
670
+ translator_io_start(&ctx->base);
671
gen_helper_mfc0_count(arg, cpu_env);
672
/*
673
* Break the TB to be able to take timer interrupts immediately
674
@@ -XXX,XX +XXX,XX @@ cp0_unimplemented:
675
static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
676
{
677
const char *register_name = "invalid";
678
+ bool icount;
679
680
if (sel != 0) {
681
check_insn(ctx, ISA_MIPS_R1);
682
}
683
684
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
685
- gen_io_start();
686
- }
687
+ icount = translator_io_start(&ctx->base);
688
689
switch (reg) {
690
case CP0_REGISTER_00:
691
@@ -XXX,XX +XXX,XX @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
692
trace_mips_translate_c0("dmtc0", register_name, reg, sel);
693
694
/* For simplicity assume that all writes can cause interrupts. */
695
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
696
+ if (icount) {
697
/*
698
* DISAS_STOP isn't sufficient, we need to ensure we break out of
699
* translated code to check for pending interrupts.
700
@@ -XXX,XX +XXX,XX @@ void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
701
gen_store_gpr(t0, rt);
702
break;
703
case 2:
704
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
705
- gen_io_start();
706
- }
707
+ translator_io_start(&ctx->base);
708
gen_helper_rdhwr_cc(t0, cpu_env);
709
gen_store_gpr(t0, rt);
710
/*
711
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
712
index XXXXXXX..XXXXXXX 100644
713
--- a/target/nios2/translate.c
714
+++ b/target/nios2/translate.c
715
@@ -XXX,XX +XXX,XX @@
716
#include "exec/cpu_ldst.h"
717
#include "exec/translator.h"
718
#include "qemu/qemu-print.h"
719
-#include "exec/gen-icount.h"
720
#include "semihosting/semihost.h"
721
722
#define HELPER_H "helper.h"
723
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
724
index XXXXXXX..XXXXXXX 100644
725
--- a/target/openrisc/translate.c
726
+++ b/target/openrisc/translate.c
727
@@ -XXX,XX +XXX,XX @@
728
729
#include "exec/helper-proto.h"
730
#include "exec/helper-gen.h"
731
-#include "exec/gen-icount.h"
732
733
#include "exec/log.h"
734
735
@@ -XXX,XX +XXX,XX @@ static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a)
736
737
check_r0_write(dc, a->d);
738
739
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
740
- gen_io_start();
741
+ if (translator_io_start(&dc->base)) {
742
if (dc->delayed_branch) {
743
tcg_gen_mov_tl(cpu_pc, jmp_pc);
744
tcg_gen_discard_tl(jmp_pc);
745
@@ -XXX,XX +XXX,XX @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
746
{
747
TCGv spr = tcg_temp_new();
748
749
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
750
- gen_io_start();
751
- }
752
+ translator_io_start(&dc->base);
753
+
754
/*
755
* For SR, we will need to exit the TB to recognize the new
756
* exception state. For NPC, in theory this counts as a branch
757
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
758
index XXXXXXX..XXXXXXX 100644
759
--- a/target/ppc/translate.c
760
+++ b/target/ppc/translate.c
761
@@ -XXX,XX +XXX,XX @@ static TCGv cpu_reserve_val2;
762
static TCGv cpu_fpscr;
763
static TCGv_i32 cpu_access_type;
764
765
-#include "exec/gen-icount.h"
766
-
767
void ppc_translate_init(void)
768
{
769
int i;
770
@@ -XXX,XX +XXX,XX @@ static void gen_exception_nip(DisasContext *ctx, uint32_t excp,
771
772
static void gen_icount_io_start(DisasContext *ctx)
773
{
774
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
775
- gen_io_start();
776
- /*
777
- * An I/O instruction must be last in the TB.
778
- * Chain to the next TB, and let the code from gen_tb_start
779
- * decide if we need to return to the main loop.
780
- * Doing this first also allows this value to be overridden.
781
- */
782
- ctx->base.is_jmp = DISAS_TOO_MANY;
783
- }
784
+ translator_io_start(&ctx->base);
785
}
56
}
786
57
787
#if !defined(CONFIG_USER_ONLY)
58
static bool fold_xor(OptContext *ctx, TCGOp *op)
788
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
789
index XXXXXXX..XXXXXXX 100644
790
--- a/target/riscv/translate.c
791
+++ b/target/riscv/translate.c
792
@@ -XXX,XX +XXX,XX @@ static TCGv load_val;
793
static TCGv pm_mask;
794
static TCGv pm_base;
795
796
-#include "exec/gen-icount.h"
797
-
798
/*
799
* If an operation is being performed on less than TARGET_LONG_BITS,
800
* it may require the inputs to be sign- or zero-extended; which will
801
diff --git a/target/rx/translate.c b/target/rx/translate.c
802
index XXXXXXX..XXXXXXX 100644
803
--- a/target/rx/translate.c
804
+++ b/target/rx/translate.c
805
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 cpu_acc;
806
807
#define cpu_sp cpu_regs[0]
808
809
-#include "exec/gen-icount.h"
810
-
811
/* decoder helper */
812
static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
813
int i, int n)
814
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
815
index XXXXXXX..XXXXXXX 100644
816
--- a/target/s390x/tcg/translate.c
817
+++ b/target/s390x/tcg/translate.c
818
@@ -XXX,XX +XXX,XX @@
819
#include "qemu/log.h"
820
#include "qemu/host-utils.h"
821
#include "exec/cpu_ldst.h"
822
-#include "exec/gen-icount.h"
823
#include "exec/helper-proto.h"
824
#include "exec/helper-gen.h"
825
826
@@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
827
828
/* input/output is the special case for icount mode */
829
if (unlikely(insn->flags & IF_IO)) {
830
- icount = tb_cflags(s->base.tb) & CF_USE_ICOUNT;
831
- if (icount) {
832
- gen_io_start();
833
- }
834
+ icount = translator_io_start(&s->base);
835
}
836
}
837
838
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
839
index XXXXXXX..XXXXXXX 100644
840
--- a/target/sh4/translate.c
841
+++ b/target/sh4/translate.c
842
@@ -XXX,XX +XXX,XX @@ static TCGv cpu_fregs[32];
843
/* internal register indexes */
844
static TCGv cpu_flags, cpu_delayed_pc, cpu_delayed_cond;
845
846
-#include "exec/gen-icount.h"
847
-
848
void sh4_translate_init(void)
849
{
850
int i;
851
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
852
index XXXXXXX..XXXXXXX 100644
853
--- a/target/sparc/translate.c
854
+++ b/target/sparc/translate.c
855
@@ -XXX,XX +XXX,XX @@ static TCGv cpu_wim;
856
/* Floating point registers */
857
static TCGv_i64 cpu_fpr[TARGET_DPREGS];
858
859
-#include "exec/gen-icount.h"
860
-
861
typedef struct DisasContext {
862
DisasContextBase base;
863
target_ulong pc; /* current Program Counter: integer or DYNAMIC_PC */
864
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
865
r_const = tcg_constant_i32(dc->mem_idx);
866
tcg_gen_ld_ptr(r_tickptr, cpu_env,
867
offsetof(CPUSPARCState, tick));
868
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
869
- gen_io_start();
870
+ if (translator_io_start(&dc->base)) {
871
+ dc->base.is_jmp = DISAS_EXIT;
872
}
873
gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
874
r_const);
875
gen_store_gpr(dc, rd, cpu_dst);
876
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
877
- /* I/O operations in icount mode must end the TB */
878
- dc->base.is_jmp = DISAS_EXIT;
879
- }
880
}
881
break;
882
case 0x5: /* V9 rdpc */
883
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
884
r_const = tcg_constant_i32(dc->mem_idx);
885
tcg_gen_ld_ptr(r_tickptr, cpu_env,
886
offsetof(CPUSPARCState, stick));
887
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
888
- gen_io_start();
889
+ if (translator_io_start(&dc->base)) {
890
+ dc->base.is_jmp = DISAS_EXIT;
891
}
892
gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
893
r_const);
894
gen_store_gpr(dc, rd, cpu_dst);
895
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
896
- /* I/O operations in icount mode must end the TB */
897
- dc->base.is_jmp = DISAS_EXIT;
898
- }
899
}
900
break;
901
case 0x19: /* System tick compare */
902
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
903
r_const = tcg_constant_i32(dc->mem_idx);
904
tcg_gen_ld_ptr(r_tickptr, cpu_env,
905
offsetof(CPUSPARCState, tick));
906
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
907
- gen_io_start();
908
+ if (translator_io_start(&dc->base)) {
909
+ dc->base.is_jmp = DISAS_EXIT;
910
}
911
gen_helper_tick_get_count(cpu_tmp0, cpu_env,
912
r_tickptr, r_const);
913
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
914
- /* I/O operations in icount mode must end the TB */
915
- dc->base.is_jmp = DISAS_EXIT;
916
- }
917
}
918
break;
919
case 5: // tba
920
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
921
r_tickptr = tcg_temp_new_ptr();
922
tcg_gen_ld_ptr(r_tickptr, cpu_env,
923
offsetof(CPUSPARCState, tick));
924
- if (tb_cflags(dc->base.tb) &
925
- CF_USE_ICOUNT) {
926
- gen_io_start();
927
- }
928
+ translator_io_start(&dc->base);
929
gen_helper_tick_set_limit(r_tickptr,
930
cpu_tick_cmpr);
931
/* End TB to handle timer interrupt */
932
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
933
r_tickptr = tcg_temp_new_ptr();
934
tcg_gen_ld_ptr(r_tickptr, cpu_env,
935
offsetof(CPUSPARCState, stick));
936
- if (tb_cflags(dc->base.tb) &
937
- CF_USE_ICOUNT) {
938
- gen_io_start();
939
- }
940
+ translator_io_start(&dc->base);
941
gen_helper_tick_set_count(r_tickptr,
942
cpu_tmp0);
943
/* End TB to handle timer interrupt */
944
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
945
r_tickptr = tcg_temp_new_ptr();
946
tcg_gen_ld_ptr(r_tickptr, cpu_env,
947
offsetof(CPUSPARCState, stick));
948
- if (tb_cflags(dc->base.tb) &
949
- CF_USE_ICOUNT) {
950
- gen_io_start();
951
- }
952
+ translator_io_start(&dc->base);
953
gen_helper_tick_set_limit(r_tickptr,
954
cpu_stick_cmpr);
955
/* End TB to handle timer interrupt */
956
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
957
r_tickptr = tcg_temp_new_ptr();
958
tcg_gen_ld_ptr(r_tickptr, cpu_env,
959
offsetof(CPUSPARCState, tick));
960
- if (tb_cflags(dc->base.tb) &
961
- CF_USE_ICOUNT) {
962
- gen_io_start();
963
- }
964
+ translator_io_start(&dc->base);
965
gen_helper_tick_set_count(r_tickptr,
966
cpu_tmp0);
967
/* End TB to handle timer interrupt */
968
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
969
break;
970
case 6: // pstate
971
save_state(dc);
972
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
973
- gen_io_start();
974
- }
975
- gen_helper_wrpstate(cpu_env, cpu_tmp0);
976
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
977
- /* I/O ops in icount mode must end the TB */
978
+ if (translator_io_start(&dc->base)) {
979
dc->base.is_jmp = DISAS_EXIT;
980
}
981
+ gen_helper_wrpstate(cpu_env, cpu_tmp0);
982
dc->npc = DYNAMIC_PC;
983
break;
984
case 7: // tl
985
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
986
dc->npc = DYNAMIC_PC;
987
break;
988
case 8: // pil
989
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
990
- gen_io_start();
991
- }
992
- gen_helper_wrpil(cpu_env, cpu_tmp0);
993
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
994
- /* I/O ops in icount mode must end the TB */
995
+ if (translator_io_start(&dc->base)) {
996
dc->base.is_jmp = DISAS_EXIT;
997
}
998
+ gen_helper_wrpil(cpu_env, cpu_tmp0);
999
break;
1000
case 9: // cwp
1001
gen_helper_wrcwp(cpu_env, cpu_tmp0);
1002
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
1003
r_tickptr = tcg_temp_new_ptr();
1004
tcg_gen_ld_ptr(r_tickptr, cpu_env,
1005
offsetof(CPUSPARCState, hstick));
1006
- if (tb_cflags(dc->base.tb) &
1007
- CF_USE_ICOUNT) {
1008
- gen_io_start();
1009
- }
1010
+ translator_io_start(&dc->base);
1011
gen_helper_tick_set_limit(r_tickptr,
1012
cpu_hstick_cmpr);
1013
/* End TB to handle timer interrupt */
1014
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
1015
goto priv_insn;
1016
dc->npc = DYNAMIC_PC;
1017
dc->pc = DYNAMIC_PC;
1018
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
1019
- gen_io_start();
1020
- }
1021
+ translator_io_start(&dc->base);
1022
gen_helper_done(cpu_env);
1023
goto jmp_insn;
1024
case 1:
1025
@@ -XXX,XX +XXX,XX @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
1026
goto priv_insn;
1027
dc->npc = DYNAMIC_PC;
1028
dc->pc = DYNAMIC_PC;
1029
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
1030
- gen_io_start();
1031
- }
1032
+ translator_io_start(&dc->base);
1033
gen_helper_retry(cpu_env);
1034
goto jmp_insn;
1035
default:
1036
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
1037
index XXXXXXX..XXXXXXX 100644
1038
--- a/target/tricore/translate.c
1039
+++ b/target/tricore/translate.c
1040
@@ -XXX,XX +XXX,XX @@ static TCGv cpu_PSW_SV;
1041
static TCGv cpu_PSW_AV;
1042
static TCGv cpu_PSW_SAV;
1043
1044
-#include "exec/gen-icount.h"
1045
-
1046
static const char *regnames_a[] = {
1047
"a0" , "a1" , "a2" , "a3" , "a4" , "a5" ,
1048
"a6" , "a7" , "a8" , "a9" , "sp" , "a11" ,
1049
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
1050
index XXXXXXX..XXXXXXX 100644
1051
--- a/target/xtensa/translate.c
1052
+++ b/target/xtensa/translate.c
1053
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 cpu_exclusive_val;
1054
1055
static GHashTable *xtensa_regfile_table;
1056
1057
-#include "exec/gen-icount.h"
1058
-
1059
static char *sr_name[256];
1060
static char *ur_name[256];
1061
1062
@@ -XXX,XX +XXX,XX @@ static int gen_postprocess(DisasContext *dc, int slot)
1063
1064
#ifndef CONFIG_USER_ONLY
1065
if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) {
1066
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
1067
- gen_io_start();
1068
- }
1069
+ translator_io_start(&dc->base);
1070
gen_helper_check_interrupts(cpu_env);
1071
}
1072
#endif
1073
@@ -XXX,XX +XXX,XX @@ static void translate_rsr_ccount(DisasContext *dc, const OpcodeArg arg[],
1074
const uint32_t par[])
1075
{
1076
#ifndef CONFIG_USER_ONLY
1077
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
1078
- gen_io_start();
1079
- }
1080
+ translator_io_start(&dc->base);
1081
gen_helper_update_ccount(cpu_env);
1082
tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
1083
#endif
1084
@@ -XXX,XX +XXX,XX @@ static void translate_waiti(DisasContext *dc, const OpcodeArg arg[],
1085
#ifndef CONFIG_USER_ONLY
1086
TCGv_i32 pc = tcg_constant_i32(dc->base.pc_next);
1087
1088
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
1089
- gen_io_start();
1090
- }
1091
+ translator_io_start(&dc->base);
1092
gen_helper_waiti(cpu_env, pc, tcg_constant_i32(arg[0].imm));
1093
#endif
1094
}
1095
@@ -XXX,XX +XXX,XX @@ static void translate_wsr_ccompare(DisasContext *dc, const OpcodeArg arg[],
1096
uint32_t id = par[0] - CCOMPARE;
1097
1098
assert(id < dc->config->nccompare);
1099
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
1100
- gen_io_start();
1101
- }
1102
+ translator_io_start(&dc->base);
1103
tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
1104
gen_helper_update_ccompare(cpu_env, tcg_constant_i32(id));
1105
#endif
1106
@@ -XXX,XX +XXX,XX @@ static void translate_wsr_ccount(DisasContext *dc, const OpcodeArg arg[],
1107
const uint32_t par[])
1108
{
1109
#ifndef CONFIG_USER_ONLY
1110
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
1111
- gen_io_start();
1112
- }
1113
+ translator_io_start(&dc->base);
1114
gen_helper_wsr_ccount(cpu_env, arg[0].in);
1115
#endif
1116
}
1117
@@ -XXX,XX +XXX,XX @@ static void translate_xsr_ccount(DisasContext *dc, const OpcodeArg arg[],
1118
#ifndef CONFIG_USER_ONLY
1119
TCGv_i32 tmp = tcg_temp_new_i32();
1120
1121
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
1122
- gen_io_start();
1123
- }
1124
-
1125
+ translator_io_start(&dc->base);
1126
gen_helper_update_ccount(cpu_env);
1127
tcg_gen_mov_i32(tmp, cpu_SR[par[0]]);
1128
gen_helper_wsr_ccount(cpu_env, arg[0].in);
1129
diff --git a/target/loongarch/insn_trans/trans_extra.c.inc b/target/loongarch/insn_trans/trans_extra.c.inc
1130
index XXXXXXX..XXXXXXX 100644
1131
--- a/target/loongarch/insn_trans/trans_extra.c.inc
1132
+++ b/target/loongarch/insn_trans/trans_extra.c.inc
1133
@@ -XXX,XX +XXX,XX @@ static bool gen_rdtime(DisasContext *ctx, arg_rr *a,
1134
TCGv dst1 = gpr_dst(ctx, a->rd, EXT_NONE);
1135
TCGv dst2 = gpr_dst(ctx, a->rj, EXT_NONE);
1136
1137
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1138
- gen_io_start();
1139
- }
1140
+ translator_io_start(&ctx->base);
1141
gen_helper_rdtime_d(dst1, cpu_env);
1142
if (word) {
1143
tcg_gen_sextract_tl(dst1, dst1, high ? 32 : 0, 32);
1144
diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc b/target/loongarch/insn_trans/trans_privileged.c.inc
1145
index XXXXXXX..XXXXXXX 100644
1146
--- a/target/loongarch/insn_trans/trans_privileged.c.inc
1147
+++ b/target/loongarch/insn_trans/trans_privileged.c.inc
1148
@@ -XXX,XX +XXX,XX @@ static bool check_csr_flags(DisasContext *ctx, const CSRInfo *csr, bool write)
1149
if ((csr->flags & CSRFL_READONLY) && write) {
1150
return false;
1151
}
1152
- if ((csr->flags & CSRFL_IO) &&
1153
- (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT)) {
1154
- gen_io_start();
1155
+ if ((csr->flags & CSRFL_IO) && translator_io_start(&ctx->base)) {
1156
ctx->base.is_jmp = DISAS_EXIT_UPDATE;
1157
} else if ((csr->flags & CSRFL_EXITTB) && write) {
1158
ctx->base.is_jmp = DISAS_EXIT_UPDATE;
1159
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
1160
index XXXXXXX..XXXXXXX 100644
1161
--- a/target/riscv/insn_trans/trans_privileged.c.inc
1162
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
1163
@@ -XXX,XX +XXX,XX @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
1164
#ifndef CONFIG_USER_ONLY
1165
if (has_ext(ctx, RVS)) {
1166
decode_save_opc(ctx);
1167
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1168
- gen_io_start();
1169
- }
1170
+ translator_io_start(&ctx->base);
1171
gen_helper_sret(cpu_pc, cpu_env);
1172
exit_tb(ctx); /* no chaining */
1173
ctx->base.is_jmp = DISAS_NORETURN;
1174
@@ -XXX,XX +XXX,XX @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
1175
{
1176
#ifndef CONFIG_USER_ONLY
1177
decode_save_opc(ctx);
1178
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1179
- gen_io_start();
1180
- }
1181
+ translator_io_start(&ctx->base);
1182
gen_helper_mret(cpu_pc, cpu_env);
1183
exit_tb(ctx); /* no chaining */
1184
ctx->base.is_jmp = DISAS_NORETURN;
1185
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
1186
index XXXXXXX..XXXXXXX 100644
1187
--- a/target/riscv/insn_trans/trans_rvi.c.inc
1188
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
1189
@@ -XXX,XX +XXX,XX @@ static bool do_csrr(DisasContext *ctx, int rd, int rc)
1190
TCGv dest = dest_gpr(ctx, rd);
1191
TCGv_i32 csr = tcg_constant_i32(rc);
1192
1193
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1194
- gen_io_start();
1195
- }
1196
+ translator_io_start(&ctx->base);
1197
gen_helper_csrr(dest, cpu_env, csr);
1198
gen_set_gpr(ctx, rd, dest);
1199
return do_csr_post(ctx);
1200
@@ -XXX,XX +XXX,XX @@ static bool do_csrw(DisasContext *ctx, int rc, TCGv src)
1201
{
1202
TCGv_i32 csr = tcg_constant_i32(rc);
1203
1204
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1205
- gen_io_start();
1206
- }
1207
+ translator_io_start(&ctx->base);
1208
gen_helper_csrw(cpu_env, csr, src);
1209
return do_csr_post(ctx);
1210
}
1211
@@ -XXX,XX +XXX,XX @@ static bool do_csrrw(DisasContext *ctx, int rd, int rc, TCGv src, TCGv mask)
1212
TCGv dest = dest_gpr(ctx, rd);
1213
TCGv_i32 csr = tcg_constant_i32(rc);
1214
1215
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1216
- gen_io_start();
1217
- }
1218
+ translator_io_start(&ctx->base);
1219
gen_helper_csrrw(dest, cpu_env, csr, src, mask);
1220
gen_set_gpr(ctx, rd, dest);
1221
return do_csr_post(ctx);
1222
@@ -XXX,XX +XXX,XX @@ static bool do_csrr_i128(DisasContext *ctx, int rd, int rc)
1223
TCGv desth = dest_gprh(ctx, rd);
1224
TCGv_i32 csr = tcg_constant_i32(rc);
1225
1226
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1227
- gen_io_start();
1228
- }
1229
+ translator_io_start(&ctx->base);
1230
gen_helper_csrr_i128(destl, cpu_env, csr);
1231
tcg_gen_ld_tl(desth, cpu_env, offsetof(CPURISCVState, retxh));
1232
gen_set_gpr128(ctx, rd, destl, desth);
1233
@@ -XXX,XX +XXX,XX @@ static bool do_csrw_i128(DisasContext *ctx, int rc, TCGv srcl, TCGv srch)
1234
{
1235
TCGv_i32 csr = tcg_constant_i32(rc);
1236
1237
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1238
- gen_io_start();
1239
- }
1240
+ translator_io_start(&ctx->base);
1241
gen_helper_csrw_i128(cpu_env, csr, srcl, srch);
1242
return do_csr_post(ctx);
1243
}
1244
@@ -XXX,XX +XXX,XX @@ static bool do_csrrw_i128(DisasContext *ctx, int rd, int rc,
1245
TCGv desth = dest_gprh(ctx, rd);
1246
TCGv_i32 csr = tcg_constant_i32(rc);
1247
1248
- if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1249
- gen_io_start();
1250
- }
1251
+ translator_io_start(&ctx->base);
1252
gen_helper_csrrw_i128(destl, cpu_env, csr, srcl, srch, maskl, maskh);
1253
tcg_gen_ld_tl(desth, cpu_env, offsetof(CPURISCVState, retxh));
1254
gen_set_gpr128(ctx, rd, destl, desth);
1255
--
59
--
1256
2.34.1
60
2.43.0
1257
1258
diff view generated by jsdifflib
1
Create two static libraries for use by each execution mode.
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
3
---
6
tcg/meson.build | 30 +++++++++++++++++++++++++++---
4
tcg/optimize.c | 2 +-
7
1 file changed, 27 insertions(+), 3 deletions(-)
5
1 file changed, 1 insertion(+), 1 deletion(-)
8
6
9
diff --git a/tcg/meson.build b/tcg/meson.build
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/meson.build
9
--- a/tcg/optimize.c
12
+++ b/tcg/meson.build
10
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@
11
@@ -XXX,XX +XXX,XX @@ static bool fold_remainder(OptContext *ctx, TCGOp *op)
14
+if not get_option('tcg').allowed()
12
fold_xx_to_i(ctx, op, 0)) {
15
+ subdir_done()
13
return true;
16
+endif
14
}
17
+
15
- return false;
18
tcg_ss = ss.source_set()
16
+ return finish_folding(ctx, op);
19
17
}
20
tcg_ss.add(files(
18
21
@@ -XXX,XX +XXX,XX @@ tcg_ss.add(files(
19
static bool fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
22
if get_option('tcg_interpreter')
23
libffi = dependency('libffi', version: '>=3.0', required: true,
24
method: 'pkg-config')
25
- specific_ss.add(libffi)
26
- specific_ss.add(files('tci.c'))
27
+ tcg_ss.add(libffi)
28
+ tcg_ss.add(files('tci.c'))
29
endif
30
31
-specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
32
+tcg_ss = tcg_ss.apply(config_host, strict: false)
33
+
34
+libtcg_user = static_library('tcg_user',
35
+ tcg_ss.sources() + genh,
36
+ name_suffix: 'fa',
37
+ c_args: '-DCONFIG_USER_ONLY',
38
+ build_by_default: have_user)
39
+
40
+tcg_user = declare_dependency(link_with: libtcg_user,
41
+ dependencies: tcg_ss.dependencies())
42
+user_ss.add(tcg_user)
43
+
44
+libtcg_softmmu = static_library('tcg_softmmu',
45
+ tcg_ss.sources() + genh,
46
+ name_suffix: 'fa',
47
+ c_args: '-DCONFIG_SOFTMMU',
48
+ build_by_default: have_system)
49
+
50
+tcg_softmmu = declare_dependency(link_with: libtcg_softmmu,
51
+ dependencies: tcg_ss.dependencies())
52
+softmmu_ss.add(tcg_softmmu)
53
--
20
--
54
2.34.1
21
2.43.0
55
56
diff view generated by jsdifflib
1
This makes CPUTLBEntry agnostic to the address size of the guest.
1
Change return from bool to int; distinguish between
2
When 32-bit addresses are in effect, we can simply read the low
2
complete folding, simplification, and no change.
3
32 bits of the 64-bit field. Similarly when we need to update
4
the field for setting TLB_NOTDIRTY.
5
3
6
For TCG backends that could in theory be big-endian, but in
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
practice are not (arm, loongarch, riscv), use QEMU_BUILD_BUG_ON
8
to document and ensure this is not accidentally missed.
9
10
For s390x, which is always big-endian, use HOST_BIG_ENDIAN anyway,
11
to document the reason for the adjustment.
12
13
For sparc64 and ppc64, always perform a 64-bit load, and rely on
14
the following 32-bit comparison to ignore the high bits.
15
16
Rearrange mips and ppc if ladders for clarity.
17
18
Reviewed-by: Anton Johansson <anjo@rev.ng>
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
---
6
---
21
include/exec/cpu-defs.h | 37 +++++++++++---------------------
7
tcg/optimize.c | 22 ++++++++++++++--------
22
include/exec/cpu_ldst.h | 19 ++++++++++------
8
1 file changed, 14 insertions(+), 8 deletions(-)
23
accel/tcg/cputlb.c | 8 +++++--
24
tcg/aarch64/tcg-target.c.inc | 1 +
25
tcg/arm/tcg-target.c.inc | 1 +
26
tcg/loongarch64/tcg-target.c.inc | 1 +
27
tcg/mips/tcg-target.c.inc | 13 ++++++-----
28
tcg/ppc/tcg-target.c.inc | 28 +++++++++++++-----------
29
tcg/riscv/tcg-target.c.inc | 1 +
30
tcg/s390x/tcg-target.c.inc | 1 +
31
tcg/sparc64/tcg-target.c.inc | 8 +++++--
32
11 files changed, 67 insertions(+), 51 deletions(-)
33
9
34
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
35
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
36
--- a/include/exec/cpu-defs.h
12
--- a/tcg/optimize.c
37
+++ b/include/exec/cpu-defs.h
13
+++ b/tcg/optimize.c
38
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static bool fold_remainder(OptContext *ctx, TCGOp *op)
39
/* use a fully associative victim tlb of 8 entries */
15
return finish_folding(ctx, op);
40
#define CPU_VTLB_SIZE 8
16
}
41
17
42
-#if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32
18
-static bool fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
43
-#define CPU_TLB_ENTRY_BITS 4
19
+/* Return 1 if finished, -1 if simplified, 0 if unchanged. */
44
-#else
20
+static int fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
45
#define CPU_TLB_ENTRY_BITS 5
46
-#endif
47
48
#define CPU_TLB_DYN_MIN_BITS 6
49
#define CPU_TLB_DYN_DEFAULT_BITS 8
50
@@ -XXX,XX +XXX,XX @@
51
# endif
52
53
/* Minimalized TLB entry for use by TCG fast path. */
54
-typedef struct CPUTLBEntry {
55
- /* bit TARGET_LONG_BITS to TARGET_PAGE_BITS : virtual address
56
- bit TARGET_PAGE_BITS-1..4 : Nonzero for accesses that should not
57
- go directly to ram.
58
- bit 3 : indicates that the entry is invalid
59
- bit 2..0 : zero
60
- */
61
- union {
62
- struct {
63
- target_ulong addr_read;
64
- target_ulong addr_write;
65
- target_ulong addr_code;
66
- /* Addend to virtual address to get host address. IO accesses
67
- use the corresponding iotlb value. */
68
- uintptr_t addend;
69
- };
70
+typedef union CPUTLBEntry {
71
+ struct {
72
+ uint64_t addr_read;
73
+ uint64_t addr_write;
74
+ uint64_t addr_code;
75
/*
76
- * Padding to get a power of two size, as well as index
77
- * access to addr_{read,write,code}.
78
+ * Addend to virtual address to get host address. IO accesses
79
+ * use the corresponding iotlb value.
80
*/
81
- target_ulong addr_idx[(1 << CPU_TLB_ENTRY_BITS) / TARGET_LONG_SIZE];
82
+ uintptr_t addend;
83
};
84
+ /*
85
+ * Padding to get a power of two size, as well as index
86
+ * access to addr_{read,write,code}.
87
+ */
88
+ uint64_t addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(uint64_t)];
89
} CPUTLBEntry;
90
91
QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
92
93
-
94
#endif /* !CONFIG_USER_ONLY && CONFIG_TCG */
95
96
#if !defined(CONFIG_USER_ONLY)
97
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
98
index XXXXXXX..XXXXXXX 100644
99
--- a/include/exec/cpu_ldst.h
100
+++ b/include/exec/cpu_ldst.h
101
@@ -XXX,XX +XXX,XX @@ static inline target_ulong tlb_read_idx(const CPUTLBEntry *entry,
102
{
21
{
103
/* Do not rearrange the CPUTLBEntry structure members. */
22
uint64_t a_zmask, b_val;
104
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_read) !=
23
TCGCond cond;
105
- MMU_DATA_LOAD * TARGET_LONG_SIZE);
24
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg)
106
+ MMU_DATA_LOAD * sizeof(uint64_t));
25
op->opc = xor_opc;
107
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_write) !=
26
op->args[2] = arg_new_constant(ctx, 1);
108
- MMU_DATA_STORE * TARGET_LONG_SIZE);
27
}
109
+ MMU_DATA_STORE * sizeof(uint64_t));
28
- return false;
110
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_code) !=
29
+ return -1;
111
- MMU_INST_FETCH * TARGET_LONG_SIZE);
112
+ MMU_INST_FETCH * sizeof(uint64_t));
113
114
- const target_ulong *ptr = &entry->addr_idx[access_type];
115
-#if TCG_OVERSIZED_GUEST
116
- return *ptr;
117
+#if TARGET_LONG_BITS == 32
118
+ /* Use qatomic_read, in case of addr_write; only care about low bits. */
119
+ const uint32_t *ptr = (uint32_t *)&entry->addr_idx[access_type];
120
+ ptr += HOST_BIG_ENDIAN;
121
+ return qatomic_read(ptr);
122
#else
123
+ const uint64_t *ptr = &entry->addr_idx[access_type];
124
+# if TCG_OVERSIZED_GUEST
125
+ return *ptr;
126
+# else
127
/* ofs might correspond to .addr_write, so use qatomic_read */
128
return qatomic_read(ptr);
129
+# endif
130
#endif
131
}
132
133
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/accel/tcg/cputlb.c
136
+++ b/accel/tcg/cputlb.c
137
@@ -XXX,XX +XXX,XX @@ static void tlb_reset_dirty_range_locked(CPUTLBEntry *tlb_entry,
138
addr &= TARGET_PAGE_MASK;
139
addr += tlb_entry->addend;
140
if ((addr - start) < length) {
141
-#if TCG_OVERSIZED_GUEST
142
+#if TARGET_LONG_BITS == 32
143
+ uint32_t *ptr_write = (uint32_t *)&tlb_entry->addr_write;
144
+ ptr_write += HOST_BIG_ENDIAN;
145
+ qatomic_set(ptr_write, *ptr_write | TLB_NOTDIRTY);
146
+#elif TCG_OVERSIZED_GUEST
147
tlb_entry->addr_write |= TLB_NOTDIRTY;
148
#else
149
qatomic_set(&tlb_entry->addr_write,
150
- tlb_entry->addr_write | TLB_NOTDIRTY);
151
+ tlb_entry->addr_write | TLB_NOTDIRTY);
152
#endif
153
}
30
}
154
}
31
}
155
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
32
-
156
index XXXXXXX..XXXXXXX 100644
33
- return false;
157
--- a/tcg/aarch64/tcg-target.c.inc
34
+ return 0;
158
+++ b/tcg/aarch64/tcg-target.c.inc
35
}
159
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
36
160
tcg_out_insn(s, 3502, ADD, 1, TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_TMP0);
37
static void fold_setcond_tst_pow2(OptContext *ctx, TCGOp *op, bool neg)
161
38
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
162
/* Load the tlb comparator into TMP0, and the fast path addend into TMP1. */
39
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
163
+ QEMU_BUILD_BUG_ON(HOST_BIG_ENDIAN);
40
}
164
tcg_out_ld(s, addr_type, TCG_REG_TMP0, TCG_REG_TMP1,
41
165
is_ld ? offsetof(CPUTLBEntry, addr_read)
42
- if (fold_setcond_zmask(ctx, op, false)) {
166
: offsetof(CPUTLBEntry, addr_write));
43
+ i = fold_setcond_zmask(ctx, op, false);
167
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
44
+ if (i > 0) {
168
index XXXXXXX..XXXXXXX 100644
45
return true;
169
--- a/tcg/arm/tcg-target.c.inc
46
}
170
+++ b/tcg/arm/tcg-target.c.inc
47
- fold_setcond_tst_pow2(ctx, op, false);
171
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
48
+ if (i == 0) {
172
* Add the tlb_table pointer, creating the CPUTLBEntry address in R1.
49
+ fold_setcond_tst_pow2(ctx, op, false);
173
* Load the tlb comparator into R2/R3 and the fast path addend into R1.
174
*/
175
+ QEMU_BUILD_BUG_ON(HOST_BIG_ENDIAN);
176
if (cmp_off == 0) {
177
if (s->addr_type == TCG_TYPE_I32) {
178
tcg_out_ld32_rwb(s, COND_AL, TCG_REG_R2, TCG_REG_R1, TCG_REG_R0);
179
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
180
index XXXXXXX..XXXXXXX 100644
181
--- a/tcg/loongarch64/tcg-target.c.inc
182
+++ b/tcg/loongarch64/tcg-target.c.inc
183
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
184
tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP1);
185
186
/* Load the tlb comparator and the addend. */
187
+ QEMU_BUILD_BUG_ON(HOST_BIG_ENDIAN);
188
tcg_out_ld(s, addr_type, TCG_REG_TMP0, TCG_REG_TMP2,
189
is_ld ? offsetof(CPUTLBEntry, addr_read)
190
: offsetof(CPUTLBEntry, addr_write));
191
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
192
index XXXXXXX..XXXXXXX 100644
193
--- a/tcg/mips/tcg-target.c.inc
194
+++ b/tcg/mips/tcg-target.c.inc
195
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
196
/* Add the tlb_table pointer, creating the CPUTLBEntry address in TMP3. */
197
tcg_out_opc_reg(s, ALIAS_PADD, TCG_TMP3, TCG_TMP3, TCG_TMP1);
198
199
+ if (TCG_TARGET_REG_BITS == 32 || addr_type == TCG_TYPE_I32) {
200
+ /* Load the (low half) tlb comparator. */
201
+ tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_TMP3,
202
+ cmp_off + HOST_BIG_ENDIAN * 4);
203
+ } else {
204
+ tcg_out_ld(s, TCG_TYPE_I64, TCG_TMP0, TCG_TMP3, cmp_off);
205
+ }
50
+ }
206
+
51
207
if (TCG_TARGET_REG_BITS == 64 || addr_type == TCG_TYPE_I32) {
52
ctx->z_mask = 1;
208
- /* Load the tlb comparator. */
53
return false;
209
- tcg_out_ld(s, addr_type, TCG_TMP0, TCG_TMP3, cmp_off);
54
@@ -XXX,XX +XXX,XX @@ static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
210
/* Load the tlb addend for the fast path. */
55
return tcg_opt_gen_movi(ctx, op, op->args[0], -i);
211
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
212
- } else {
213
- /* Load the low half of the tlb comparator. */
214
- tcg_out_ldst(s, OPC_LW, TCG_TMP0, TCG_TMP3, cmp_off + LO_OFF);
215
}
56
}
216
57
217
/*
58
- if (fold_setcond_zmask(ctx, op, true)) {
218
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
59
+ i = fold_setcond_zmask(ctx, op, true);
219
index XXXXXXX..XXXXXXX 100644
60
+ if (i > 0) {
220
--- a/tcg/ppc/tcg-target.c.inc
61
return true;
221
+++ b/tcg/ppc/tcg-target.c.inc
222
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
223
}
62
}
224
tcg_out32(s, AND | SAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_R0));
63
- fold_setcond_tst_pow2(ctx, op, true);
225
64
+ if (i == 0) {
226
- /* Load the (low part) TLB comparator into TMP2. */
65
+ fold_setcond_tst_pow2(ctx, op, true);
227
- if (cmp_off == 0
66
+ }
228
- && (TCG_TARGET_REG_BITS == 64 || addr_type == TCG_TYPE_I32)) {
67
229
- uint32_t lxu = (TCG_TARGET_REG_BITS == 32 || addr_type == TCG_TYPE_I32
68
/* Value is {0,-1} so all bits are repetitions of the sign. */
230
- ? LWZUX : LDUX);
69
ctx->s_mask = -1;
231
- tcg_out32(s, lxu | TAB(TCG_REG_TMP2, TCG_REG_TMP1, TCG_REG_TMP2));
232
+ /*
233
+ * Load the (low part) TLB comparator into TMP2.
234
+ * For 64-bit host, always load the entire 64-bit slot for simplicity.
235
+ * We will ignore the high bits with tcg_out_cmp(..., addr_type).
236
+ */
237
+ if (TCG_TARGET_REG_BITS == 64) {
238
+ if (cmp_off == 0) {
239
+ tcg_out32(s, LDUX | TAB(TCG_REG_TMP2, TCG_REG_TMP1, TCG_REG_TMP2));
240
+ } else {
241
+ tcg_out32(s, ADD | TAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_TMP2));
242
+ tcg_out_ld(s, TCG_TYPE_I64, TCG_REG_TMP2, TCG_REG_TMP1, cmp_off);
243
+ }
244
+ } else if (cmp_off == 0 && !HOST_BIG_ENDIAN) {
245
+ tcg_out32(s, LWZUX | TAB(TCG_REG_TMP2, TCG_REG_TMP1, TCG_REG_TMP2));
246
} else {
247
tcg_out32(s, ADD | TAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_TMP2));
248
- if (TCG_TARGET_REG_BITS == 32 && addr_type != TCG_TYPE_I32) {
249
- tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP2,
250
- TCG_REG_TMP1, cmp_off + 4 * HOST_BIG_ENDIAN);
251
- } else {
252
- tcg_out_ld(s, addr_type, TCG_REG_TMP2, TCG_REG_TMP1, cmp_off);
253
- }
254
+ tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP2, TCG_REG_TMP1,
255
+ cmp_off + 4 * HOST_BIG_ENDIAN);
256
}
257
258
/*
259
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
260
index XXXXXXX..XXXXXXX 100644
261
--- a/tcg/riscv/tcg-target.c.inc
262
+++ b/tcg/riscv/tcg-target.c.inc
263
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
264
}
265
266
/* Load the tlb comparator and the addend. */
267
+ QEMU_BUILD_BUG_ON(HOST_BIG_ENDIAN);
268
tcg_out_ld(s, addr_type, TCG_REG_TMP0, TCG_REG_TMP2,
269
is_ld ? offsetof(CPUTLBEntry, addr_read)
270
: offsetof(CPUTLBEntry, addr_write));
271
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
272
index XXXXXXX..XXXXXXX 100644
273
--- a/tcg/s390x/tcg-target.c.inc
274
+++ b/tcg/s390x/tcg-target.c.inc
275
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
276
ofs = offsetof(CPUTLBEntry, addr_write);
277
}
278
if (addr_type == TCG_TYPE_I32) {
279
+ ofs += HOST_BIG_ENDIAN * 4;
280
tcg_out_insn(s, RX, C, TCG_REG_R0, TCG_TMP0, TCG_REG_NONE, ofs);
281
} else {
282
tcg_out_insn(s, RXY, CG, TCG_REG_R0, TCG_TMP0, TCG_REG_NONE, ofs);
283
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
284
index XXXXXXX..XXXXXXX 100644
285
--- a/tcg/sparc64/tcg-target.c.inc
286
+++ b/tcg/sparc64/tcg-target.c.inc
287
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
288
/* Add the tlb_table pointer, creating the CPUTLBEntry address into R2. */
289
tcg_out_arith(s, TCG_REG_T1, TCG_REG_T1, TCG_REG_T3, ARITH_ADD);
290
291
- /* Load the tlb comparator and the addend. */
292
- tcg_out_ld(s, addr_type, TCG_REG_T2, TCG_REG_T1, cmp_off);
293
+ /*
294
+ * Load the tlb comparator and the addend.
295
+ * Always load the entire 64-bit comparator for simplicity.
296
+ * We will ignore the high bits via BPCC_ICC below.
297
+ */
298
+ tcg_out_ld(s, TCG_TYPE_I64, TCG_REG_T2, TCG_REG_T1, cmp_off);
299
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_T1, TCG_REG_T1, add_off);
300
h->base = TCG_REG_T1;
301
302
--
70
--
303
2.34.1
71
2.43.0
diff view generated by jsdifflib
1
If CONFIG_USER_ONLY is ok generically, so is CONFIG_SOFTMMU,
1
Avoid the use of the OptContext slots.
2
because they are exactly opposite.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.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
include/exec/poison.h | 1 -
6
tcg/optimize.c | 3 +--
8
scripts/make-config-poison.sh | 5 +++--
7
1 file changed, 1 insertion(+), 2 deletions(-)
9
2 files changed, 3 insertions(+), 3 deletions(-)
10
8
11
diff --git a/include/exec/poison.h b/include/exec/poison.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
13
--- a/include/exec/poison.h
11
--- a/tcg/optimize.c
14
+++ b/include/exec/poison.h
12
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
16
#pragma GCC poison CONFIG_HVF
14
fold_setcond_tst_pow2(ctx, op, false);
17
#pragma GCC poison CONFIG_LINUX_USER
15
}
18
#pragma GCC poison CONFIG_KVM
16
19
-#pragma GCC poison CONFIG_SOFTMMU
17
- ctx->z_mask = 1;
20
#pragma GCC poison CONFIG_WHPX
18
- return false;
21
#pragma GCC poison CONFIG_XEN
19
+ return fold_masks_z(ctx, op, 1);
22
20
}
23
diff --git a/scripts/make-config-poison.sh b/scripts/make-config-poison.sh
21
24
index XXXXXXX..XXXXXXX 100755
22
static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
25
--- a/scripts/make-config-poison.sh
26
+++ b/scripts/make-config-poison.sh
27
@@ -XXX,XX +XXX,XX @@ if test $# = 0; then
28
exit 0
29
fi
30
31
-# Create list of config switches that should be poisoned in common code...
32
-# but filter out CONFIG_TCG and CONFIG_USER_ONLY which are special.
33
+# Create list of config switches that should be poisoned in common code,
34
+# but filter out several which are handled manually.
35
exec sed -n \
36
-e' /CONFIG_TCG/d' \
37
-e '/CONFIG_USER_ONLY/d' \
38
+ -e '/CONFIG_SOFTMMU/d' \
39
-e '/^#define / {' \
40
-e 's///' \
41
-e 's/ .*//' \
42
--
23
--
43
2.34.1
24
2.43.0
44
45
diff view generated by jsdifflib
1
Two headers are not required for the rest of the
1
Avoid the use of the OptContext slots.
2
contents of plugin-gen.h.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.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
include/exec/plugin-gen.h | 2 --
6
tcg/optimize.c | 3 +--
8
1 file changed, 2 deletions(-)
7
1 file changed, 1 insertion(+), 2 deletions(-)
9
8
10
diff --git a/include/exec/plugin-gen.h b/include/exec/plugin-gen.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/exec/plugin-gen.h
11
--- a/tcg/optimize.c
13
+++ b/include/exec/plugin-gen.h
12
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@ static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
15
#ifndef QEMU_PLUGIN_GEN_H
14
}
16
#define QEMU_PLUGIN_GEN_H
15
17
16
/* Value is {0,-1} so all bits are repetitions of the sign. */
18
-#include "exec/cpu_ldst.h"
17
- ctx->s_mask = -1;
19
-#include "qemu/plugin.h"
18
- return false;
20
#include "tcg/tcg.h"
19
+ return fold_masks_s(ctx, op, -1);
21
20
}
22
struct DisasContextBase;
21
22
static bool fold_setcond2(OptContext *ctx, TCGOp *op)
23
--
23
--
24
2.34.1
24
2.43.0
25
26
diff view generated by jsdifflib
1
The bug was hidden because they happen to have the same values.
1
Avoid the use of the OptContext slots.
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.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
tcg/region.c | 18 +++++++++++++-----
6
tcg/optimize.c | 3 +--
7
1 file changed, 13 insertions(+), 5 deletions(-)
7
1 file changed, 1 insertion(+), 2 deletions(-)
8
8
9
diff --git a/tcg/region.c b/tcg/region.c
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/region.c
11
--- a/tcg/optimize.c
12
+++ b/tcg/region.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static int alloc_code_gen_buffer(size_t tb_size, int splitwx, Error **errp)
13
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
14
return PROT_READ | PROT_WRITE;
14
return fold_setcond(ctx, op);
15
}
16
#elif defined(_WIN32)
17
+/*
18
+ * Local source-level compatibility with Unix.
19
+ * Used by tcg_region_init below.
20
+ */
21
+#define PROT_READ 1
22
+#define PROT_WRITE 2
23
+#define PROT_EXEC 4
24
+
25
static int alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
26
{
27
void *buf;
28
@@ -XXX,XX +XXX,XX @@ static int alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
29
region.start_aligned = buf;
30
region.total_size = size;
31
32
- return PAGE_READ | PAGE_WRITE | PAGE_EXEC;
33
+ return PROT_READ | PROT_WRITE | PROT_EXEC;
34
}
35
#else
36
static int alloc_code_gen_buffer_anon(size_t size, int prot,
37
@@ -XXX,XX +XXX,XX @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus)
38
* buffer -- let that one use hugepages throughout.
39
* Work with the page protections set up with the initial mapping.
40
*/
41
- need_prot = PAGE_READ | PAGE_WRITE;
42
+ need_prot = PROT_READ | PROT_WRITE;
43
#ifndef CONFIG_TCG_INTERPRETER
44
if (tcg_splitwx_diff == 0) {
45
- need_prot |= PAGE_EXEC;
46
+ need_prot |= PROT_EXEC;
47
}
15
}
48
#endif
16
49
for (size_t i = 0, n = region.n; i < n; i++) {
17
- ctx->z_mask = 1;
50
@@ -XXX,XX +XXX,XX @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus)
18
- return false;
51
if (have_prot != need_prot) {
19
+ return fold_masks_z(ctx, op, 1);
52
int rc;
20
53
21
do_setcond_const:
54
- if (need_prot == (PAGE_READ | PAGE_WRITE | PAGE_EXEC)) {
22
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
55
+ if (need_prot == (PROT_READ | PROT_WRITE | PROT_EXEC)) {
56
rc = qemu_mprotect_rwx(start, end - start);
57
- } else if (need_prot == (PAGE_READ | PAGE_WRITE)) {
58
+ } else if (need_prot == (PROT_READ | PROT_WRITE)) {
59
rc = qemu_mprotect_rw(start, end - start);
60
} else {
61
g_assert_not_reached();
62
--
23
--
63
2.34.1
24
2.43.0
64
65
diff view generated by jsdifflib
1
This had been pulled in via exec/translator.h,
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
but the include of exec-all.h will be removed.
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
3
---
7
target/arm/tcg/translate.h | 1 +
4
tcg/optimize.c | 2 +-
8
1 file changed, 1 insertion(+)
5
1 file changed, 1 insertion(+), 1 deletion(-)
9
6
10
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
11
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/tcg/translate.h
9
--- a/tcg/optimize.c
13
+++ b/target/arm/tcg/translate.h
10
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@
11
@@ -XXX,XX +XXX,XX @@ static bool fold_cmp_vec(OptContext *ctx, TCGOp *op)
15
#include "cpu.h"
12
if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
16
#include "tcg/tcg-op.h"
13
op->args[3] = tcg_swap_cond(op->args[3]);
17
#include "tcg/tcg-op-gvec.h"
14
}
18
+#include "exec/exec-all.h"
15
- return false;
19
#include "exec/translator.h"
16
+ return finish_folding(ctx, op);
20
#include "exec/helper-gen.h"
17
}
21
#include "internals.h"
18
19
static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
22
--
20
--
23
2.34.1
21
2.43.0
24
25
diff view generated by jsdifflib
1
This had been pulled in via exec/exec-all.h, via exec/translator.h,
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
but the include of exec-all.h will be removed.
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
3
---
7
target/hexagon/translate.c | 1 +
4
tcg/optimize.c | 2 +-
8
target/loongarch/translate.c | 3 +--
5
1 file changed, 1 insertion(+), 1 deletion(-)
9
target/mips/tcg/translate.c | 1 +
10
3 files changed, 3 insertions(+), 2 deletions(-)
11
6
12
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
13
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
14
--- a/target/hexagon/translate.c
9
--- a/tcg/optimize.c
15
+++ b/target/hexagon/translate.c
10
+++ b/tcg/optimize.c
16
@@ -XXX,XX +XXX,XX @@
11
@@ -XXX,XX +XXX,XX @@ static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
17
#include "tcg/tcg-op-gvec.h"
12
if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
18
#include "exec/helper-gen.h"
13
op->args[5] = tcg_invert_cond(op->args[5]);
19
#include "exec/helper-proto.h"
14
}
20
+#include "exec/translation-block.h"
15
- return false;
21
#include "exec/cpu_ldst.h"
16
+ return finish_folding(ctx, op);
22
#include "exec/log.h"
17
}
23
#include "internal.h"
18
24
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
19
static bool fold_sextract(OptContext *ctx, TCGOp *op)
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/loongarch/translate.c
27
+++ b/target/loongarch/translate.c
28
@@ -XXX,XX +XXX,XX @@
29
#include "cpu.h"
30
#include "tcg/tcg-op.h"
31
#include "tcg/tcg-op-gvec.h"
32
-
33
+#include "exec/translation-block.h"
34
#include "exec/translator.h"
35
#include "exec/helper-proto.h"
36
#include "exec/helper-gen.h"
37
-
38
#include "exec/log.h"
39
#include "qemu/qemu-print.h"
40
#include "fpu/softfloat.h"
41
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/mips/tcg/translate.c
44
+++ b/target/mips/tcg/translate.c
45
@@ -XXX,XX +XXX,XX @@
46
#include "translate.h"
47
#include "internal.h"
48
#include "exec/helper-proto.h"
49
+#include "exec/translation-block.h"
50
#include "semihosting/semihost.h"
51
#include "trace.h"
52
#include "disas/disas.h"
53
--
20
--
54
2.34.1
21
2.43.0
55
56
diff view generated by jsdifflib
1
All uses replaced with TCGContext.addr_type.
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.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
tcg/riscv/tcg-target.c.inc | 13 +++++++------
6
tcg/optimize.c | 24 +++++++++---------------
7
1 file changed, 7 insertions(+), 6 deletions(-)
7
1 file changed, 9 insertions(+), 15 deletions(-)
8
8
9
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/riscv/tcg-target.c.inc
11
--- a/tcg/optimize.c
12
+++ b/tcg/riscv/tcg-target.c.inc
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
13
@@ -XXX,XX +XXX,XX @@ static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
14
TCGReg addr_reg, MemOpIdx oi,
14
static bool fold_sextract(OptContext *ctx, TCGOp *op)
15
bool is_ld)
16
{
15
{
17
+ TCGType addr_type = s->addr_type;
16
uint64_t z_mask, s_mask, s_mask_old;
18
TCGLabelQemuLdst *ldst = NULL;
17
+ TempOptInfo *t1 = arg_info(op->args[1]);
19
MemOp opc = get_memop(oi);
18
int pos = op->args[2];
20
TCGAtomAlign aa;
19
int len = op->args[3];
21
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
20
22
addr_adj = addr_reg;
21
- if (arg_is_const(op->args[1])) {
23
if (a_mask < s_mask) {
22
- uint64_t t;
24
addr_adj = TCG_REG_TMP0;
23
-
25
- tcg_out_opc_imm(s, TARGET_LONG_BITS == 32 ? OPC_ADDIW : OPC_ADDI,
24
- t = arg_info(op->args[1])->val;
26
+ tcg_out_opc_imm(s, addr_type == TCG_TYPE_I32 ? OPC_ADDIW : OPC_ADDI,
25
- t = sextract64(t, pos, len);
27
addr_adj, addr_reg, s_mask - a_mask);
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));
28
}
30
}
29
compare_mask = s->page_mask | a_mask;
31
30
if (compare_mask == sextreg(compare_mask, 0, 12)) {
32
- z_mask = arg_info(op->args[1])->z_mask;
31
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_TMP1, addr_adj, compare_mask);
33
- z_mask = sextract64(z_mask, pos, len);
32
} else {
34
- ctx->z_mask = z_mask;
33
- tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_TMP1, compare_mask);
35
-
34
+ tcg_out_movi(s, addr_type, TCG_REG_TMP1, compare_mask);
36
- s_mask_old = arg_info(op->args[1])->s_mask;
35
tcg_out_opc_reg(s, OPC_AND, TCG_REG_TMP1, TCG_REG_TMP1, addr_adj);
37
- s_mask = sextract64(s_mask_old, pos, len);
38
- s_mask |= MAKE_64BIT_MASK(len, 64 - len);
39
- ctx->s_mask = s_mask;
40
+ s_mask_old = t1->s_mask;
41
+ s_mask = s_mask_old >> pos;
42
+ s_mask |= -1ull << (len - 1);
43
44
if (0 && pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
45
return true;
36
}
46
}
37
47
38
/* Load the tlb comparator and the addend. */
48
- return fold_masks(ctx, op);
39
- tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP0, TCG_REG_TMP2,
49
+ z_mask = sextract64(t1->z_mask, pos, len);
40
+ tcg_out_ld(s, addr_type, TCG_REG_TMP0, TCG_REG_TMP2,
50
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
41
is_ld ? offsetof(CPUTLBEntry, addr_read)
51
}
42
: offsetof(CPUTLBEntry, addr_write));
52
43
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP2,
53
static bool fold_shift(OptContext *ctx, TCGOp *op)
44
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
45
tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP0, TCG_REG_TMP1, 0);
46
47
/* TLB Hit - translate address using addend. */
48
- if (TARGET_LONG_BITS == 64) {
49
+ if (addr_type != TCG_TYPE_I32) {
50
tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, addr_reg, TCG_REG_TMP2);
51
} else if (have_zba) {
52
tcg_out_opc_reg(s, OPC_ADD_UW, TCG_REG_TMP0, addr_reg, TCG_REG_TMP2);
53
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
54
55
if (guest_base != 0) {
56
base = TCG_REG_TMP0;
57
- if (TARGET_LONG_BITS == 64) {
58
+ if (addr_type != TCG_TYPE_I32) {
59
tcg_out_opc_reg(s, OPC_ADD, base, addr_reg, TCG_GUEST_BASE_REG);
60
} else if (have_zba) {
61
tcg_out_opc_reg(s, OPC_ADD_UW, base, addr_reg, TCG_GUEST_BASE_REG);
62
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
63
tcg_out_ext32u(s, base, addr_reg);
64
tcg_out_opc_reg(s, OPC_ADD, base, base, TCG_GUEST_BASE_REG);
65
}
66
- } else if (TARGET_LONG_BITS == 64) {
67
+ } else if (addr_type != TCG_TYPE_I32) {
68
base = addr_reg;
69
} else {
70
base = TCG_REG_TMP0;
71
--
54
--
72
2.34.1
55
2.43.0
73
74
diff view generated by jsdifflib
1
All uses replaced with TCGContext.addr_type.
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.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
tcg/s390x/tcg-target.c.inc | 9 +++++----
6
tcg/optimize.c | 27 ++++++++++++++-------------
7
1 file changed, 5 insertions(+), 4 deletions(-)
7
1 file changed, 14 insertions(+), 13 deletions(-)
8
8
9
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/s390x/tcg-target.c.inc
11
--- a/tcg/optimize.c
12
+++ b/tcg/s390x/tcg-target.c.inc
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
13
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
14
TCGReg addr_reg, MemOpIdx oi,
14
static bool fold_shift(OptContext *ctx, TCGOp *op)
15
bool is_ld)
16
{
15
{
17
+ TCGType addr_type = s->addr_type;
16
uint64_t s_mask, z_mask, sign;
18
TCGLabelQemuLdst *ldst = NULL;
17
+ TempOptInfo *t1, *t2;
19
MemOp opc = get_memop(oi);
18
20
MemOp s_bits = opc & MO_SIZE;
19
if (fold_const2(ctx, op) ||
21
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
20
fold_ix_to_i(ctx, op, 0) ||
22
tgen_andi_risbg(s, TCG_REG_R0, addr_reg, tlb_mask);
21
@@ -XXX,XX +XXX,XX @@ static bool fold_shift(OptContext *ctx, TCGOp *op)
23
} else {
22
return true;
24
tcg_out_insn(s, RX, LA, TCG_REG_R0, addr_reg, TCG_REG_NONE, a_off);
25
- tgen_andi(s, TCG_TYPE_TL, TCG_REG_R0, tlb_mask);
26
+ tgen_andi(s, addr_type, TCG_REG_R0, tlb_mask);
27
}
23
}
28
24
29
if (is_ld) {
25
- s_mask = arg_info(op->args[1])->s_mask;
30
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
26
- z_mask = arg_info(op->args[1])->z_mask;
31
} else {
27
+ t1 = arg_info(op->args[1]);
32
ofs = offsetof(CPUTLBEntry, addr_write);
28
+ t2 = arg_info(op->args[2]);
29
+ s_mask = t1->s_mask;
30
+ z_mask = t1->z_mask;
31
32
- if (arg_is_const(op->args[2])) {
33
- int sh = arg_info(op->args[2])->val;
34
-
35
- ctx->z_mask = do_constant_folding(op->opc, ctx->type, z_mask, sh);
36
+ if (ti_is_const(t2)) {
37
+ int sh = ti_const_val(t2);
38
39
+ z_mask = do_constant_folding(op->opc, ctx->type, z_mask, sh);
40
s_mask = do_constant_folding(op->opc, ctx->type, s_mask, sh);
41
42
- return fold_masks(ctx, op);
43
+ return fold_masks_zs(ctx, op, z_mask, s_mask);
33
}
44
}
34
- if (TARGET_LONG_BITS == 32) {
45
35
+ if (addr_type == TCG_TYPE_I32) {
46
switch (op->opc) {
36
tcg_out_insn(s, RX, C, TCG_REG_R0, TCG_TMP0, TCG_REG_NONE, ofs);
47
@@ -XXX,XX +XXX,XX @@ static bool fold_shift(OptContext *ctx, TCGOp *op)
37
} else {
48
* Arithmetic right shift will not reduce the number of
38
tcg_out_insn(s, RXY, CG, TCG_REG_R0, TCG_TMP0, TCG_REG_NONE, ofs);
49
* input sign repetitions.
39
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
50
*/
40
tcg_out_insn(s, RXY, LG, h->index, TCG_TMP0, TCG_REG_NONE,
51
- ctx->s_mask = s_mask;
41
offsetof(CPUTLBEntry, addend));
52
- break;
42
53
+ return fold_masks_s(ctx, op, s_mask);
43
- if (TARGET_LONG_BITS == 32) {
54
CASE_OP_32_64(shr):
44
+ if (addr_type == TCG_TYPE_I32) {
55
/*
45
tcg_out_insn(s, RRE, ALGFR, h->index, addr_reg);
56
* If the sign bit is known zero, then logical right shift
46
h->base = TCG_REG_NONE;
57
- * will not reduced the number of input sign repetitions.
47
} else {
58
+ * will not reduce the number of input sign repetitions.
48
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
59
*/
60
- sign = (s_mask & -s_mask) >> 1;
61
+ sign = -s_mask;
62
if (sign && !(z_mask & sign)) {
63
- ctx->s_mask = s_mask;
64
+ return fold_masks_s(ctx, op, s_mask);
65
}
66
break;
67
default:
68
break;
49
}
69
}
50
70
51
h->base = addr_reg;
71
- return false;
52
- if (TARGET_LONG_BITS == 32) {
72
+ return finish_folding(ctx, op);
53
+ if (addr_type == TCG_TYPE_I32) {
73
}
54
tcg_out_ext32u(s, TCG_TMP0, addr_reg);
74
55
h->base = TCG_TMP0;
75
static bool fold_sub_to_neg(OptContext *ctx, TCGOp *op)
56
}
57
--
76
--
58
2.34.1
77
2.43.0
59
60
diff view generated by jsdifflib
1
Move most includes from *translate*.c to translate.h, ensuring
1
Merge the two conditions, sign != 0 && !(z_mask & sign),
2
that we get the ordering correct. Ensure cpu.h is first.
2
by testing ~z_mask & sign. If sign == 0, the logical and
3
Use disas/disas.h instead of exec/log.h.
3
will produce false.
4
Drop otherwise unused includes.
5
4
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
7
---
9
target/arm/tcg/translate.h | 3 +++
8
tcg/optimize.c | 5 ++---
10
target/arm/tcg/translate-a64.c | 17 +++++------------
9
1 file changed, 2 insertions(+), 3 deletions(-)
11
target/arm/tcg/translate-m-nocp.c | 2 --
12
target/arm/tcg/translate-mve.c | 3 ---
13
target/arm/tcg/translate-neon.c | 3 ---
14
target/arm/tcg/translate-sme.c | 6 ------
15
target/arm/tcg/translate-sve.c | 9 ---------
16
target/arm/tcg/translate-vfp.c | 3 ---
17
target/arm/tcg/translate.c | 17 +++++------------
18
9 files changed, 13 insertions(+), 50 deletions(-)
19
10
20
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
11
diff --git a/tcg/optimize.c b/tcg/optimize.c
21
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/tcg/translate.h
13
--- a/tcg/optimize.c
23
+++ b/target/arm/tcg/translate.h
14
+++ b/tcg/optimize.c
24
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
25
#ifndef TARGET_ARM_TRANSLATE_H
16
26
#define TARGET_ARM_TRANSLATE_H
17
static bool fold_shift(OptContext *ctx, TCGOp *op)
27
18
{
28
+#include "cpu.h"
19
- uint64_t s_mask, z_mask, sign;
29
+#include "tcg/tcg-op.h"
20
+ uint64_t s_mask, z_mask;
30
+#include "tcg/tcg-op-gvec.h"
21
TempOptInfo *t1, *t2;
31
#include "exec/translator.h"
22
32
#include "exec/helper-gen.h"
23
if (fold_const2(ctx, op) ||
33
#include "internals.h"
24
@@ -XXX,XX +XXX,XX @@ static bool fold_shift(OptContext *ctx, TCGOp *op)
34
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
25
* If the sign bit is known zero, then logical right shift
35
index XXXXXXX..XXXXXXX 100644
26
* will not reduce the number of input sign repetitions.
36
--- a/target/arm/tcg/translate-a64.c
27
*/
37
+++ b/target/arm/tcg/translate-a64.c
28
- sign = -s_mask;
38
@@ -XXX,XX +XXX,XX @@
29
- if (sign && !(z_mask & sign)) {
39
*/
30
+ if (~z_mask & -s_mask) {
40
#include "qemu/osdep.h"
31
return fold_masks_s(ctx, op, s_mask);
41
32
}
42
-#include "cpu.h"
33
break;
43
-#include "exec/exec-all.h"
44
-#include "tcg/tcg-op.h"
45
-#include "tcg/tcg-op-gvec.h"
46
-#include "qemu/log.h"
47
-#include "arm_ldst.h"
48
#include "translate.h"
49
-#include "internals.h"
50
-#include "qemu/host-utils.h"
51
-#include "semihosting/semihost.h"
52
-#include "exec/log.h"
53
-#include "cpregs.h"
54
#include "translate-a64.h"
55
-#include "qemu/atomic128.h"
56
+#include "qemu/log.h"
57
+#include "disas/disas.h"
58
+#include "arm_ldst.h"
59
+#include "semihosting/semihost.h"
60
+#include "cpregs.h"
61
62
static TCGv_i64 cpu_X[32];
63
static TCGv_i64 cpu_pc;
64
diff --git a/target/arm/tcg/translate-m-nocp.c b/target/arm/tcg/translate-m-nocp.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/tcg/translate-m-nocp.c
67
+++ b/target/arm/tcg/translate-m-nocp.c
68
@@ -XXX,XX +XXX,XX @@
69
*/
70
71
#include "qemu/osdep.h"
72
-#include "tcg/tcg-op.h"
73
-#include "tcg/tcg-op-gvec.h"
74
#include "translate.h"
75
#include "translate-a32.h"
76
77
diff --git a/target/arm/tcg/translate-mve.c b/target/arm/tcg/translate-mve.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/tcg/translate-mve.c
80
+++ b/target/arm/tcg/translate-mve.c
81
@@ -XXX,XX +XXX,XX @@
82
*/
83
84
#include "qemu/osdep.h"
85
-#include "tcg/tcg-op.h"
86
-#include "tcg/tcg-op-gvec.h"
87
-#include "exec/exec-all.h"
88
#include "translate.h"
89
#include "translate-a32.h"
90
91
diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/tcg/translate-neon.c
94
+++ b/target/arm/tcg/translate-neon.c
95
@@ -XXX,XX +XXX,XX @@
96
*/
97
98
#include "qemu/osdep.h"
99
-#include "tcg/tcg-op.h"
100
-#include "tcg/tcg-op-gvec.h"
101
-#include "exec/exec-all.h"
102
#include "translate.h"
103
#include "translate-a32.h"
104
105
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/tcg/translate-sme.c
108
+++ b/target/arm/tcg/translate-sme.c
109
@@ -XXX,XX +XXX,XX @@
110
*/
111
112
#include "qemu/osdep.h"
113
-#include "cpu.h"
114
-#include "tcg/tcg-op.h"
115
-#include "tcg/tcg-op-gvec.h"
116
-#include "tcg/tcg-gvec-desc.h"
117
#include "translate.h"
118
#include "translate-a64.h"
119
-#include "fpu/softfloat.h"
120
-
121
122
/*
123
* Include the generated decoder.
124
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/target/arm/tcg/translate-sve.c
127
+++ b/target/arm/tcg/translate-sve.c
128
@@ -XXX,XX +XXX,XX @@
129
*/
130
131
#include "qemu/osdep.h"
132
-#include "cpu.h"
133
-#include "exec/exec-all.h"
134
-#include "tcg/tcg-op.h"
135
-#include "tcg/tcg-op-gvec.h"
136
-#include "tcg/tcg-gvec-desc.h"
137
-#include "qemu/log.h"
138
-#include "arm_ldst.h"
139
#include "translate.h"
140
-#include "internals.h"
141
-#include "exec/log.h"
142
#include "translate-a64.h"
143
#include "fpu/softfloat.h"
144
145
diff --git a/target/arm/tcg/translate-vfp.c b/target/arm/tcg/translate-vfp.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/tcg/translate-vfp.c
148
+++ b/target/arm/tcg/translate-vfp.c
149
@@ -XXX,XX +XXX,XX @@
150
*/
151
152
#include "qemu/osdep.h"
153
-#include "tcg/tcg-op.h"
154
-#include "tcg/tcg-op-gvec.h"
155
-#include "exec/exec-all.h"
156
#include "translate.h"
157
#include "translate-a32.h"
158
159
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/tcg/translate.c
162
+++ b/target/arm/tcg/translate.c
163
@@ -XXX,XX +XXX,XX @@
164
*/
165
#include "qemu/osdep.h"
166
167
-#include "cpu.h"
168
-#include "internals.h"
169
-#include "disas/disas.h"
170
-#include "exec/exec-all.h"
171
-#include "tcg/tcg-op.h"
172
-#include "tcg/tcg-op-gvec.h"
173
-#include "qemu/log.h"
174
-#include "qemu/bitops.h"
175
-#include "arm_ldst.h"
176
-#include "semihosting/semihost.h"
177
-#include "exec/log.h"
178
-#include "cpregs.h"
179
#include "translate.h"
180
#include "translate-a32.h"
181
+#include "qemu/log.h"
182
+#include "disas/disas.h"
183
+#include "arm_ldst.h"
184
+#include "semihosting/semihost.h"
185
+#include "cpregs.h"
186
#include "exec/helper-proto.h"
187
188
#define HELPER_H "helper.h"
189
--
34
--
190
2.34.1
35
2.43.0
191
192
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
Duplicate fold_sub_vec into fold_sub instead of calling it,
2
now that fold_sub_vec always returns true.
2
3
3
Coverity complains that perf_marker is never unmapped.
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
Fix by unmapping it in perf_exit().
5
6
Fixes: Coverity CID 1507929
7
Fixes: 5584e2dbe8c9 ("tcg: add perfmap and jitdump")
8
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
9
Message-Id: <20230605114134.1169974-1-iii@linux.ibm.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
6
---
13
accel/tcg/perf.c | 11 +++++++++--
7
tcg/optimize.c | 9 ++++++---
14
1 file changed, 9 insertions(+), 2 deletions(-)
8
1 file changed, 6 insertions(+), 3 deletions(-)
15
9
16
diff --git a/accel/tcg/perf.c b/accel/tcg/perf.c
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/accel/tcg/perf.c
12
--- a/tcg/optimize.c
19
+++ b/accel/tcg/perf.c
13
+++ b/tcg/optimize.c
20
@@ -XXX,XX +XXX,XX @@ static void write_perfmap_entry(const void *start, size_t insn,
14
@@ -XXX,XX +XXX,XX @@ static bool fold_sub_vec(OptContext *ctx, TCGOp *op)
15
fold_sub_to_neg(ctx, op)) {
16
return true;
17
}
18
- return false;
19
+ return finish_folding(ctx, op);
21
}
20
}
22
21
23
static FILE *jitdump;
22
static bool fold_sub(OptContext *ctx, TCGOp *op)
24
+static size_t perf_marker_size;
25
+static void *perf_marker = MAP_FAILED;
26
27
#define JITHEADER_MAGIC 0x4A695444
28
#define JITHEADER_VERSION 1
29
@@ -XXX,XX +XXX,XX @@ void perf_enable_jitdump(void)
30
{
23
{
31
struct jitheader header;
24
- if (fold_const2(ctx, op) || fold_sub_vec(ctx, op)) {
32
char jitdump_file[32];
25
+ if (fold_const2(ctx, op) ||
33
- void *perf_marker;
26
+ fold_xx_to_i(ctx, op, 0) ||
34
27
+ fold_xi_to_x(ctx, op, 0) ||
35
if (!use_rt_clock) {
28
+ fold_sub_to_neg(ctx, op)) {
36
warn_report("CLOCK_MONOTONIC is not available, proceeding without jitdump");
29
return true;
37
@@ -XXX,XX +XXX,XX @@ void perf_enable_jitdump(void)
38
* PERF_RECORD_MMAP or PERF_RECORD_MMAP2 event is of the form jit-%d.dump
39
* and will process it as a jitdump file.
40
*/
41
- perf_marker = mmap(NULL, qemu_real_host_page_size(), PROT_READ | PROT_EXEC,
42
+ perf_marker_size = qemu_real_host_page_size();
43
+ perf_marker = mmap(NULL, perf_marker_size, PROT_READ | PROT_EXEC,
44
MAP_PRIVATE, fileno(jitdump), 0);
45
if (perf_marker == MAP_FAILED) {
46
warn_report("Could not map %s: %s, proceeding without jitdump",
47
@@ -XXX,XX +XXX,XX @@ void perf_exit(void)
48
perfmap = NULL;
49
}
30
}
50
31
51
+ if (perf_marker != MAP_FAILED) {
32
@@ -XXX,XX +XXX,XX @@ static bool fold_sub(OptContext *ctx, TCGOp *op)
52
+ munmap(perf_marker, perf_marker_size);
33
? INDEX_op_add_i32 : INDEX_op_add_i64);
53
+ perf_marker = MAP_FAILED;
34
op->args[2] = arg_new_constant(ctx, -val);
54
+ }
35
}
55
+
36
- return false;
56
if (jitdump) {
37
+ return finish_folding(ctx, op);
57
fclose(jitdump);
38
}
58
jitdump = NULL;
39
40
static bool fold_sub2(OptContext *ctx, TCGOp *op)
59
--
41
--
60
2.34.1
42
2.43.0
diff view generated by jsdifflib
1
From this remove, it's no longer clear what this is attempting
1
Avoid the use of the OptContext slots.
2
to protect. The last time a use of this define was added to
3
the source tree, as opposed to merely moved around, was 2008.
4
There have been many cleanups since that time and this is
5
no longer required for the build to succeed.
6
2
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
5
---
10
target/ppc/cpu.h | 2 --
6
tcg/optimize.c | 16 +++++++++-------
11
target/sparc/cpu.h | 2 --
7
1 file changed, 9 insertions(+), 7 deletions(-)
12
accel/tcg/translate-all.c | 1 -
13
tcg/tcg.c | 6 ------
14
4 files changed, 11 deletions(-)
15
8
16
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
17
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
18
--- a/target/ppc/cpu.h
11
--- a/tcg/optimize.c
19
+++ b/target/ppc/cpu.h
12
+++ b/tcg/optimize.c
20
@@ -XXX,XX +XXX,XX @@ void ppc_store_msr(CPUPPCState *env, target_ulong value);
13
@@ -XXX,XX +XXX,XX @@ static bool fold_sub2(OptContext *ctx, TCGOp *op)
21
void ppc_cpu_list(void);
14
22
15
static bool fold_tcg_ld(OptContext *ctx, TCGOp *op)
23
/* Time-base and decrementer management */
16
{
24
-#ifndef NO_CPU_IO_DEFS
17
+ uint64_t z_mask = -1, s_mask = 0;
25
uint64_t cpu_ppc_load_tbl(CPUPPCState *env);
18
+
26
uint32_t cpu_ppc_load_tbu(CPUPPCState *env);
19
/* We can't do any folding with a load, but we can record bits. */
27
void cpu_ppc_store_tbu(CPUPPCState *env, uint32_t value);
20
switch (op->opc) {
28
@@ -XXX,XX +XXX,XX @@ int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb,
21
CASE_OP_32_64(ld8s):
29
hwaddr booke206_tlb_to_page_size(CPUPPCState *env,
22
- ctx->s_mask = MAKE_64BIT_MASK(8, 56);
30
ppcmas_tlb_t *tlb);
23
+ s_mask = INT8_MIN;
31
#endif
24
break;
32
-#endif
25
CASE_OP_32_64(ld8u):
33
26
- ctx->z_mask = MAKE_64BIT_MASK(0, 8);
34
void ppc_store_fpscr(CPUPPCState *env, target_ulong val);
27
+ z_mask = MAKE_64BIT_MASK(0, 8);
35
void helper_hfscr_facility_check(CPUPPCState *env, uint32_t bit,
28
break;
36
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
29
CASE_OP_32_64(ld16s):
37
index XXXXXXX..XXXXXXX 100644
30
- ctx->s_mask = MAKE_64BIT_MASK(16, 48);
38
--- a/target/sparc/cpu.h
31
+ s_mask = INT16_MIN;
39
+++ b/target/sparc/cpu.h
32
break;
40
@@ -XXX,XX +XXX,XX @@ G_NORETURN void sparc_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
33
CASE_OP_32_64(ld16u):
41
uintptr_t retaddr);
34
- ctx->z_mask = MAKE_64BIT_MASK(0, 16);
42
G_NORETURN void cpu_raise_exception_ra(CPUSPARCState *, int, uintptr_t);
35
+ z_mask = MAKE_64BIT_MASK(0, 16);
43
36
break;
44
-#ifndef NO_CPU_IO_DEFS
37
case INDEX_op_ld32s_i64:
45
/* cpu_init.c */
38
- ctx->s_mask = MAKE_64BIT_MASK(32, 32);
46
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
39
+ s_mask = INT32_MIN;
47
void sparc_cpu_list(void);
40
break;
48
@@ -XXX,XX +XXX,XX @@ static inline int tlb_compare_context(const SparcTLBEntry *tlb,
41
case INDEX_op_ld32u_i64:
49
return compare_masked(context, tlb->tag, MMU_CONTEXT_MASK);
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
}
50
}
51
51
52
-#endif
52
static bool fold_tcg_ld_memcopy(OptContext *ctx, TCGOp *op)
53
#endif
54
55
/* cpu-exec.c */
56
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/accel/tcg/translate-all.c
59
+++ b/accel/tcg/translate-all.c
60
@@ -XXX,XX +XXX,XX @@
61
62
#include "qemu/osdep.h"
63
64
-#define NO_CPU_IO_DEFS
65
#include "trace.h"
66
#include "disas/disas.h"
67
#include "exec/exec-all.h"
68
diff --git a/tcg/tcg.c b/tcg/tcg.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/tcg/tcg.c
71
+++ b/tcg/tcg.c
72
@@ -XXX,XX +XXX,XX @@
73
#include "qemu/cacheflush.h"
74
#include "qemu/cacheinfo.h"
75
#include "qemu/timer.h"
76
-
77
-/* Note: the long term plan is to reduce the dependencies on the QEMU
78
- CPU definitions. Currently they are used for qemu_ld/st
79
- instructions */
80
-#define NO_CPU_IO_DEFS
81
-
82
#include "exec/exec-all.h"
83
#include "exec/tlb-common.h"
84
#include "tcg/tcg-op-common.h"
85
--
53
--
86
2.34.1
54
2.43.0
87
88
diff view generated by jsdifflib
1
The last use was removed with 2ac01d6dafab.
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
3
Fixes: 2ac01d6dafab ("translate-all: use a binary search tree to track TBs in TBContext")
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
3
---
7
include/exec/exec-all.h | 10 ----------
4
tcg/optimize.c | 2 +-
8
1 file changed, 10 deletions(-)
5
1 file changed, 1 insertion(+), 1 deletion(-)
9
6
10
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.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/exec/exec-all.h
9
--- a/tcg/optimize.c
13
+++ b/include/exec/exec-all.h
10
+++ b/tcg/optimize.c
14
@@ -XXX,XX +XXX,XX @@ int probe_access_full(CPUArchState *env, target_ulong addr, int size,
11
@@ -XXX,XX +XXX,XX @@ static bool fold_tcg_ld_memcopy(OptContext *ctx, TCGOp *op)
15
CPUTLBEntryFull **pfull, uintptr_t retaddr);
12
TCGType type;
16
#endif
13
17
14
if (op->args[1] != tcgv_ptr_arg(tcg_env)) {
18
-/* Estimated block size for TB allocation. */
15
- return false;
19
-/* ??? The following is based on a 2015 survey of x86_64 host output.
16
+ return finish_folding(ctx, op);
20
- Better would seem to be some sort of dynamically sized TB array,
17
}
21
- adapting to the block sizes actually being produced. */
18
22
-#if defined(CONFIG_SOFTMMU)
19
type = ctx->type;
23
-#define CODE_GEN_AVG_BLOCK_SIZE 400
24
-#else
25
-#define CODE_GEN_AVG_BLOCK_SIZE 150
26
-#endif
27
-
28
/* Hide the qatomic_read to make code a little easier on the eyes */
29
static inline uint32_t tb_cflags(const TranslationBlock *tb)
30
{
31
--
20
--
32
2.34.1
21
2.43.0
33
34
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Avoid the use of the OptContext slots. Find TempOptInfo once.
2
Remove fold_masks as the function becomes unused.
2
3
3
In commit d56fea79f9 ("tcg: Move TCG_{LOW,HIGH} to tcg-internal.h")
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
4
we replaced the "_link_error" definitions with modern QEMU_ERROR()
5
attribute markup. We covered tcg-op.c but forgot to completely
6
clean tcg-op-vec.c. Do it now.
7
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-Id: <20230605175647.88395-3-philmd@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
6
---
13
tcg/tcg-op-vec.c | 11 -----------
7
tcg/optimize.c | 18 ++++++++----------
14
1 file changed, 11 deletions(-)
8
1 file changed, 8 insertions(+), 10 deletions(-)
15
9
16
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/tcg/tcg-op-vec.c
12
--- a/tcg/optimize.c
19
+++ b/tcg/tcg-op-vec.c
13
+++ b/tcg/optimize.c
20
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static bool fold_masks_s(OptContext *ctx, TCGOp *op, uint64_t s_mask)
21
#include "tcg/tcg-mo.h"
15
return fold_masks_zs(ctx, op, -1, s_mask);
22
#include "tcg-internal.h"
16
}
23
17
24
-
18
-static bool fold_masks(OptContext *ctx, TCGOp *op)
25
-/* Reduce the number of ifdefs below. This assumes that all uses of
19
-{
26
- TCGV_HIGH and TCGV_LOW are properly protected by a conditional that
20
- return fold_masks_zs(ctx, op, ctx->z_mask, ctx->s_mask);
27
- the compiler can eliminate. */
21
-}
28
-#if TCG_TARGET_REG_BITS == 64
29
-extern TCGv_i32 TCGV_LOW_link_error(TCGv_i64);
30
-extern TCGv_i32 TCGV_HIGH_link_error(TCGv_i64);
31
-#define TCGV_LOW TCGV_LOW_link_error
32
-#define TCGV_HIGH TCGV_HIGH_link_error
33
-#endif
34
-
22
-
35
/*
23
/*
36
* Vector optional opcode tracking.
24
* An "affected" mask bit is 0 if and only if the result is identical
37
* Except for the basic logical operations (and, or, xor), and
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)
29
{
30
+ uint64_t z_mask, s_mask;
31
+ TempOptInfo *t1, *t2;
32
+
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);
50
}
51
52
static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
38
--
53
--
39
2.34.1
54
2.43.0
40
41
diff view generated by jsdifflib
1
This will enable replacement of TARGET_INSN_START_WORDS in tcg.c.
1
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
2
Split out "tcg/insn-start-words.h" and use it in target/.
3
4
Reviewed-by: Anton Johansson <anjo@rev.ng>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
3
---
7
include/tcg/insn-start-words.h | 17 +++++++++++++++++
4
tcg/optimize.c | 2 +-
8
include/tcg/tcg-op.h | 8 ++++----
5
1 file changed, 1 insertion(+), 1 deletion(-)
9
include/tcg/tcg-opc.h | 6 +++---
10
include/tcg/tcg.h | 9 ++-------
11
accel/tcg/perf.c | 8 ++++++--
12
accel/tcg/translate-all.c | 20 +++++++++++++-------
13
target/i386/helper.c | 2 +-
14
target/openrisc/sys_helper.c | 2 +-
15
tcg/tcg.c | 16 +++++++++++-----
16
9 files changed, 58 insertions(+), 30 deletions(-)
17
create mode 100644 include/tcg/insn-start-words.h
18
6
19
diff --git a/include/tcg/insn-start-words.h b/include/tcg/insn-start-words.h
7
diff --git a/tcg/optimize.c b/tcg/optimize.c
20
new file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- /dev/null
23
+++ b/include/tcg/insn-start-words.h
24
@@ -XXX,XX +XXX,XX @@
25
+/* SPDX-License-Identifier: MIT */
26
+/*
27
+ * Define TARGET_INSN_START_WORDS
28
+ * Copyright (c) 2008 Fabrice Bellard
29
+ */
30
+
31
+#ifndef TARGET_INSN_START_WORDS
32
+
33
+#include "cpu.h"
34
+
35
+#ifndef TARGET_INSN_START_EXTRA_WORDS
36
+# define TARGET_INSN_START_WORDS 1
37
+#else
38
+# define TARGET_INSN_START_WORDS (1 + TARGET_INSN_START_EXTRA_WORDS)
39
+#endif
40
+
41
+#endif /* TARGET_INSN_START_WORDS */
42
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
43
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
44
--- a/include/tcg/tcg-op.h
9
--- a/tcg/optimize.c
45
+++ b/include/tcg/tcg-op.h
10
+++ b/tcg/optimize.c
46
@@ -XXX,XX +XXX,XX @@
11
@@ -XXX,XX +XXX,XX @@ static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
47
# error
12
return fold_orc(ctx, op);
48
#endif
49
50
-#if TARGET_INSN_START_WORDS == 1
51
+#ifndef TARGET_INSN_START_EXTRA_WORDS
52
static inline void tcg_gen_insn_start(target_ulong pc)
53
{
54
TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 64 / TCG_TARGET_REG_BITS);
55
tcg_set_insn_start_param(op, 0, pc);
56
}
57
-#elif TARGET_INSN_START_WORDS == 2
58
+#elif TARGET_INSN_START_EXTRA_WORDS == 1
59
static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1)
60
{
61
TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 2 * 64 / TCG_TARGET_REG_BITS);
62
tcg_set_insn_start_param(op, 0, pc);
63
tcg_set_insn_start_param(op, 1, a1);
64
}
65
-#elif TARGET_INSN_START_WORDS == 3
66
+#elif TARGET_INSN_START_EXTRA_WORDS == 2
67
static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1,
68
target_ulong a2)
69
{
70
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1,
71
tcg_set_insn_start_param(op, 2, a2);
72
}
73
#else
74
-# error "Unhandled number of operands to insn_start"
75
+#error Unhandled TARGET_INSN_START_EXTRA_WORDS value
76
#endif
77
78
#if TARGET_LONG_BITS == 32
79
diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
80
index XXXXXXX..XXXXXXX 100644
81
--- a/include/tcg/tcg-opc.h
82
+++ b/include/tcg/tcg-opc.h
83
@@ -XXX,XX +XXX,XX @@ DEF(mulsh_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulsh_i64))
84
85
#define DATA64_ARGS (TCG_TARGET_REG_BITS == 64 ? 1 : 2)
86
87
-/* QEMU specific */
88
-DEF(insn_start, 0, 0, DATA64_ARGS * TARGET_INSN_START_WORDS,
89
- TCG_OPF_NOT_PRESENT)
90
+/* There are tcg_ctx->insn_start_words here, not just one. */
91
+DEF(insn_start, 0, 0, DATA64_ARGS, TCG_OPF_NOT_PRESENT)
92
+
93
DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
94
DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
95
DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
96
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
97
index XXXXXXX..XXXXXXX 100644
98
--- a/include/tcg/tcg.h
99
+++ b/include/tcg/tcg.h
100
@@ -XXX,XX +XXX,XX @@ typedef uint64_t TCGRegSet;
101
#define TCG_TARGET_HAS_v256 0
102
#endif
103
104
-#ifndef TARGET_INSN_START_EXTRA_WORDS
105
-# define TARGET_INSN_START_WORDS 1
106
-#else
107
-# define TARGET_INSN_START_WORDS (1 + TARGET_INSN_START_EXTRA_WORDS)
108
-#endif
109
-
110
typedef enum TCGOpcode {
111
#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
112
#include "tcg/tcg-opc.h"
113
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
114
uint8_t page_bits;
115
uint8_t tlb_dyn_max_bits;
116
#endif
117
+ uint8_t insn_start_words;
118
119
TCGRegSet reserved_regs;
120
intptr_t current_frame_offset;
121
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
122
TCGTemp *reg_to_temp[TCG_TARGET_NB_REGS];
123
124
uint16_t gen_insn_end_off[TCG_MAX_INSNS];
125
- uint64_t gen_insn_data[TCG_MAX_INSNS][TARGET_INSN_START_WORDS];
126
+ uint64_t *gen_insn_data;
127
128
/* Exit to translator on overflow. */
129
sigjmp_buf jmp_trans;
130
diff --git a/accel/tcg/perf.c b/accel/tcg/perf.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/accel/tcg/perf.c
133
+++ b/accel/tcg/perf.c
134
@@ -XXX,XX +XXX,XX @@ void perf_report_code(uint64_t guest_pc, TranslationBlock *tb,
135
const void *start)
136
{
137
struct debuginfo_query *q;
138
- size_t insn;
139
+ size_t insn, start_words;
140
+ uint64_t *gen_insn_data;
141
142
if (!perfmap && !jitdump) {
143
return;
144
@@ -XXX,XX +XXX,XX @@ void perf_report_code(uint64_t guest_pc, TranslationBlock *tb,
145
debuginfo_lock();
146
147
/* Query debuginfo for each guest instruction. */
148
+ gen_insn_data = tcg_ctx->gen_insn_data;
149
+ start_words = tcg_ctx->insn_start_words;
150
+
151
for (insn = 0; insn < tb->icount; insn++) {
152
/* FIXME: This replicates the restore_state_to_opc() logic. */
153
- q[insn].address = tcg_ctx->gen_insn_data[insn][0];
154
+ q[insn].address = gen_insn_data[insn * start_words + 0];
155
if (tb_cflags(tb) & CF_PCREL) {
156
q[insn].address |= (guest_pc & TARGET_PAGE_MASK);
157
} else {
158
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/accel/tcg/translate-all.c
161
+++ b/accel/tcg/translate-all.c
162
@@ -XXX,XX +XXX,XX @@
163
#include "tb-context.h"
164
#include "internal.h"
165
#include "perf.h"
166
+#include "tcg/insn-start-words.h"
167
168
TBContext tb_ctx;
169
170
@@ -XXX,XX +XXX,XX @@ static int64_t decode_sleb128(const uint8_t **pp)
171
static int encode_search(TranslationBlock *tb, uint8_t *block)
172
{
173
uint8_t *highwater = tcg_ctx->code_gen_highwater;
174
+ uint64_t *insn_data = tcg_ctx->gen_insn_data;
175
+ uint16_t *insn_end_off = tcg_ctx->gen_insn_end_off;
176
uint8_t *p = block;
177
int i, j, n;
178
179
for (i = 0, n = tb->icount; i < n; ++i) {
180
- uint64_t prev;
181
+ uint64_t prev, curr;
182
183
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
184
if (i == 0) {
185
prev = (!(tb_cflags(tb) & CF_PCREL) && j == 0 ? tb->pc : 0);
186
} else {
187
- prev = tcg_ctx->gen_insn_data[i - 1][j];
188
+ prev = insn_data[(i - 1) * TARGET_INSN_START_WORDS + j];
189
}
190
- p = encode_sleb128(p, tcg_ctx->gen_insn_data[i][j] - prev);
191
+ curr = insn_data[i * TARGET_INSN_START_WORDS + j];
192
+ p = encode_sleb128(p, curr - prev);
193
}
194
- prev = (i == 0 ? 0 : tcg_ctx->gen_insn_end_off[i - 1]);
195
- p = encode_sleb128(p, tcg_ctx->gen_insn_end_off[i] - prev);
196
+ prev = (i == 0 ? 0 : insn_end_off[i - 1]);
197
+ curr = insn_end_off[i];
198
+ p = encode_sleb128(p, curr - prev);
199
200
/* Test for (pending) buffer overflow. The assumption is that any
201
one row beginning below the high water mark cannot overrun
202
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
203
tcg_ctx->tlb_fast_offset =
204
(int)offsetof(ArchCPU, neg.tlb.f) - (int)offsetof(ArchCPU, env);
205
#endif
206
+ tcg_ctx->insn_start_words = TARGET_INSN_START_WORDS;
207
208
tb_overflow:
209
210
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
211
fprintf(logfile, "OUT: [size=%d]\n", gen_code_size);
212
fprintf(logfile,
213
" -- guest addr 0x%016" PRIx64 " + tb prologue\n",
214
- tcg_ctx->gen_insn_data[insn][0]);
215
+ tcg_ctx->gen_insn_data[insn * TARGET_INSN_START_WORDS]);
216
chunk_start = tcg_ctx->gen_insn_end_off[insn];
217
disas(logfile, tb->tc.ptr, chunk_start);
218
219
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
220
size_t chunk_end = tcg_ctx->gen_insn_end_off[insn];
221
if (chunk_end > chunk_start) {
222
fprintf(logfile, " -- guest addr 0x%016" PRIx64 "\n",
223
- tcg_ctx->gen_insn_data[insn][0]);
224
+ tcg_ctx->gen_insn_data[insn * TARGET_INSN_START_WORDS]);
225
disas(logfile, tb->tc.ptr + chunk_start,
226
chunk_end - chunk_start);
227
chunk_start = chunk_end;
228
diff --git a/target/i386/helper.c b/target/i386/helper.c
229
index XXXXXXX..XXXXXXX 100644
230
--- a/target/i386/helper.c
231
+++ b/target/i386/helper.c
232
@@ -XXX,XX +XXX,XX @@
233
#endif
234
#include "qemu/log.h"
235
#ifdef CONFIG_TCG
236
-#include "tcg/tcg.h"
237
+#include "tcg/insn-start-words.h"
238
#endif
239
240
void cpu_sync_avx_hflag(CPUX86State *env)
241
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
242
index XXXXXXX..XXXXXXX 100644
243
--- a/target/openrisc/sys_helper.c
244
+++ b/target/openrisc/sys_helper.c
245
@@ -XXX,XX +XXX,XX @@
246
#ifndef CONFIG_USER_ONLY
247
#include "hw/boards.h"
248
#endif
249
-#include "tcg/tcg.h"
250
+#include "tcg/insn-start-words.h"
251
252
#define TO_SPR(group, number) (((group) << 11) + (number))
253
254
diff --git a/tcg/tcg.c b/tcg/tcg.c
255
index XXXXXXX..XXXXXXX 100644
256
--- a/tcg/tcg.c
257
+++ b/tcg/tcg.c
258
@@ -XXX,XX +XXX,XX @@ void tcg_func_start(TCGContext *s)
259
tcg_debug_assert(s->tlb_fast_offset < 0);
260
tcg_debug_assert(s->tlb_fast_offset >= MIN_TLB_MASK_TABLE_OFS);
261
#endif
262
+
263
+ tcg_debug_assert(s->insn_start_words > 0);
264
}
265
266
static TCGTemp *tcg_temp_alloc(TCGContext *s)
267
@@ -XXX,XX +XXX,XX @@ static void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
268
nb_oargs = 0;
269
col += ne_fprintf(f, "\n ----");
270
271
- for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
272
+ for (i = 0, k = s->insn_start_words; i < k; ++i) {
273
col += ne_fprintf(f, " %016" PRIx64,
274
tcg_get_insn_start_param(op, i));
275
}
276
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
277
#ifdef CONFIG_PROFILER
278
TCGProfile *prof = &s->prof;
279
#endif
280
- int i, num_insns;
281
+ int i, start_words, num_insns;
282
TCGOp *op;
283
284
#ifdef CONFIG_PROFILER
285
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
286
s->pool_labels = NULL;
287
#endif
288
289
+ start_words = s->insn_start_words;
290
+ s->gen_insn_data =
291
+ tcg_malloc(sizeof(uint64_t) * s->gen_tb->icount * start_words);
292
+
293
num_insns = -1;
294
QTAILQ_FOREACH(op, &s->ops, link) {
295
TCGOpcode opc = op->opc;
296
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
297
assert(s->gen_insn_end_off[num_insns] == off);
298
}
299
num_insns++;
300
- for (i = 0; i < TARGET_INSN_START_WORDS; ++i) {
301
- s->gen_insn_data[num_insns][i] =
302
+ for (i = 0; i < start_words; ++i) {
303
+ s->gen_insn_data[num_insns * start_words + i] =
304
tcg_get_insn_start_param(op, i);
305
}
306
break;
307
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
308
return -2;
309
}
13
}
310
}
14
}
311
- tcg_debug_assert(num_insns >= 0);
15
- return false;
312
+ tcg_debug_assert(num_insns + 1 == s->gen_tb->icount);
16
+ return finish_folding(ctx, op);
313
s->gen_insn_end_off[num_insns] = tcg_current_code_size(s);
17
}
314
18
315
/* Generate TB finalization at the end of block */
19
/* Propagate constants and copies, fold constant expressions. */
316
--
20
--
317
2.34.1
21
2.43.0
diff view generated by jsdifflib
1
This makes TranslationBlock agnostic to the address size of the guest.
1
All non-default cases now finish folding within each function.
2
Use vaddr for pc, since that's always a virtual address.
2
Do the same with the default case and assert it is done after.
3
Use uint64_t for cs_base, since usage varies between guests.
4
3
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
6
---
8
include/exec/exec-all.h | 4 ++--
7
tcg/optimize.c | 6 ++----
9
accel/tcg/cpu-exec.c | 2 +-
8
1 file changed, 2 insertions(+), 4 deletions(-)
10
2 files changed, 3 insertions(+), 3 deletions(-)
11
9
12
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/include/exec/exec-all.h
12
--- a/tcg/optimize.c
15
+++ b/include/exec/exec-all.h
13
+++ b/tcg/optimize.c
16
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock {
14
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
17
* Unwind information is taken as offsets from the page, to be
15
done = true;
18
* deposited into the "current" PC.
16
break;
19
*/
17
default:
20
- target_ulong pc;
18
+ done = finish_folding(&ctx, op);
21
+ vaddr pc;
19
break;
22
20
}
23
/*
21
-
24
* Target-specific data associated with the TranslationBlock, e.g.:
22
- if (!done) {
25
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock {
23
- finish_folding(&ctx, op);
26
* s390x: instruction data for EXECUTE,
24
- }
27
* sparc: the next pc of the instruction queue (for delay slots).
25
+ tcg_debug_assert(done);
28
*/
26
}
29
- target_ulong cs_base;
27
}
30
+ uint64_t cs_base;
31
32
uint32_t flags; /* flags defining in which context the code was generated */
33
uint32_t cflags; /* compile flags */
34
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/accel/tcg/cpu-exec.c
37
+++ b/accel/tcg/cpu-exec.c
38
@@ -XXX,XX +XXX,XX @@ static void log_cpu_exec(target_ulong pc, CPUState *cpu,
39
{
40
if (qemu_log_in_addr_range(pc)) {
41
qemu_log_mask(CPU_LOG_EXEC,
42
- "Trace %d: %p [" TARGET_FMT_lx
43
+ "Trace %d: %p [%08" PRIx64
44
"/" TARGET_FMT_lx "/%08x/%08x] %s\n",
45
cpu->cpu_index, tb->tc.ptr, tb->cs_base, pc,
46
tb->flags, tb->cflags, lookup_symbol(pc));
47
--
28
--
48
2.34.1
29
2.43.0
49
50
diff view generated by jsdifflib
1
This replaces of TCG_GUEST_DEFAULT_MO in tcg-op-ldst.c.
1
All mask setting is now done with parameters via fold_masks_*.
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.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 | 1 +
6
tcg/optimize.c | 13 -------------
7
accel/tcg/translate-all.c | 5 +++++
7
1 file changed, 13 deletions(-)
8
tcg/tcg-op-ldst.c | 4 +---
9
3 files changed, 7 insertions(+), 3 deletions(-)
10
8
11
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
12
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
13
--- a/include/tcg/tcg.h
11
--- a/tcg/optimize.c
14
+++ b/include/tcg/tcg.h
12
+++ b/tcg/optimize.c
15
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
13
@@ -XXX,XX +XXX,XX @@ typedef struct OptContext {
16
uint8_t tlb_dyn_max_bits;
14
QSIMPLEQ_HEAD(, MemCopyInfo) mem_free;
17
#endif
15
18
uint8_t insn_start_words;
16
/* In flight values from optimization. */
19
+ TCGBar guest_mo;
17
- uint64_t z_mask; /* mask bit is 0 iff value bit is 0 */
20
18
- uint64_t s_mask; /* mask bit is 1 if value bit matches msb */
21
TCGRegSet reserved_regs;
19
TCGType type;
22
intptr_t current_frame_offset;
20
} OptContext;
23
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
21
24
index XXXXXXX..XXXXXXX 100644
22
@@ -XXX,XX +XXX,XX @@ static bool finish_folding(OptContext *ctx, TCGOp *op)
25
--- a/accel/tcg/translate-all.c
23
for (i = 0; i < nb_oargs; i++) {
26
+++ b/accel/tcg/translate-all.c
24
TCGTemp *ts = arg_temp(op->args[i]);
27
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
25
reset_ts(ctx, ts);
28
(int)offsetof(ArchCPU, neg.tlb.f) - (int)offsetof(ArchCPU, env);
26
- /*
29
#endif
27
- * Save the corresponding known-zero/sign bits mask for the
30
tcg_ctx->insn_start_words = TARGET_INSN_START_WORDS;
28
- * first output argument (only one supported so far).
31
+#ifdef TCG_GUEST_DEFAULT_MO
29
- */
32
+ tcg_ctx->guest_mo = TCG_GUEST_DEFAULT_MO;
30
- if (i == 0) {
33
+#else
31
- ts_info(ts)->z_mask = ctx->z_mask;
34
+ tcg_ctx->guest_mo = TCG_MO_ALL;
32
- }
35
+#endif
33
}
36
34
return true;
37
tb_overflow:
35
}
38
36
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
39
diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c
37
ctx.type = TCG_TYPE_I32;
40
index XXXXXXX..XXXXXXX 100644
38
}
41
--- a/tcg/tcg-op-ldst.c
39
42
+++ b/tcg/tcg-op-ldst.c
40
- /* Assume all bits affected, no bits known zero, no sign reps. */
43
@@ -XXX,XX +XXX,XX @@ static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 v, TCGTemp *addr, MemOpIdx oi)
41
- ctx.z_mask = -1;
44
42
- ctx.s_mask = 0;
45
static void tcg_gen_req_mo(TCGBar type)
43
-
46
{
44
/*
47
-#ifdef TCG_GUEST_DEFAULT_MO
45
* Process each opcode.
48
- type &= TCG_GUEST_DEFAULT_MO;
46
* Sorted alphabetically by opcode as much as possible.
49
-#endif
50
+ type &= tcg_ctx->guest_mo;
51
type &= ~TCG_TARGET_DEFAULT_MO;
52
if (type) {
53
tcg_gen_mb(type | TCG_BAR_SC);
54
--
47
--
55
2.34.1
48
2.43.0
56
57
diff view generated by jsdifflib
1
Create tcg/tcg-op-common.h, moving everything that does not concern
1
All instances of s_mask have been converted to the new
2
TARGET_LONG_BITS or TCGv. Adjust tcg/*.c to use the new header
2
representation. We can now re-enable usage.
3
instead of tcg-op.h, in preparation for compiling tcg/ only once.
4
3
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
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-op-common.h | 996 ++++++++++++++++++++++++++++++++++
7
tcg/optimize.c | 4 ++--
9
include/tcg/tcg-op.h | 1004 +----------------------------------
8
1 file changed, 2 insertions(+), 2 deletions(-)
10
tcg/optimize.c | 2 +-
11
tcg/tcg-op-gvec.c | 2 +-
12
tcg/tcg-op-ldst.c | 2 +-
13
tcg/tcg-op-vec.c | 2 +-
14
tcg/tcg-op.c | 2 +-
15
tcg/tcg.c | 2 +-
16
tcg/tci.c | 3 +-
17
9 files changed, 1007 insertions(+), 1008 deletions(-)
18
create mode 100644 include/tcg/tcg-op-common.h
19
9
20
diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
21
new file mode 100644
22
index XXXXXXX..XXXXXXX
23
--- /dev/null
24
+++ b/include/tcg/tcg-op-common.h
25
@@ -XXX,XX +XXX,XX @@
26
+/* SPDX-License-Identifier: MIT */
27
+/*
28
+ * Target independent opcode generation functions.
29
+ *
30
+ * Copyright (c) 2008 Fabrice Bellard
31
+ */
32
+
33
+#ifndef TCG_TCG_OP_COMMON_H
34
+#define TCG_TCG_OP_COMMON_H
35
+
36
+#include "tcg/tcg.h"
37
+#include "exec/helper-proto.h"
38
+#include "exec/helper-gen.h"
39
+
40
+/* Basic output routines. Not for general consumption. */
41
+
42
+void tcg_gen_op1(TCGOpcode, TCGArg);
43
+void tcg_gen_op2(TCGOpcode, TCGArg, TCGArg);
44
+void tcg_gen_op3(TCGOpcode, TCGArg, TCGArg, TCGArg);
45
+void tcg_gen_op4(TCGOpcode, TCGArg, TCGArg, TCGArg, TCGArg);
46
+void tcg_gen_op5(TCGOpcode, TCGArg, TCGArg, TCGArg, TCGArg, TCGArg);
47
+void tcg_gen_op6(TCGOpcode, TCGArg, TCGArg, TCGArg, TCGArg, TCGArg, TCGArg);
48
+
49
+void vec_gen_2(TCGOpcode, TCGType, unsigned, TCGArg, TCGArg);
50
+void vec_gen_3(TCGOpcode, TCGType, unsigned, TCGArg, TCGArg, TCGArg);
51
+void vec_gen_4(TCGOpcode, TCGType, unsigned, TCGArg, TCGArg, TCGArg, TCGArg);
52
+
53
+static inline void tcg_gen_op1_i32(TCGOpcode opc, TCGv_i32 a1)
54
+{
55
+ tcg_gen_op1(opc, tcgv_i32_arg(a1));
56
+}
57
+
58
+static inline void tcg_gen_op1_i64(TCGOpcode opc, TCGv_i64 a1)
59
+{
60
+ tcg_gen_op1(opc, tcgv_i64_arg(a1));
61
+}
62
+
63
+static inline void tcg_gen_op1i(TCGOpcode opc, TCGArg a1)
64
+{
65
+ tcg_gen_op1(opc, a1);
66
+}
67
+
68
+static inline void tcg_gen_op2_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2)
69
+{
70
+ tcg_gen_op2(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2));
71
+}
72
+
73
+static inline void tcg_gen_op2_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2)
74
+{
75
+ tcg_gen_op2(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2));
76
+}
77
+
78
+static inline void tcg_gen_op2i_i32(TCGOpcode opc, TCGv_i32 a1, TCGArg a2)
79
+{
80
+ tcg_gen_op2(opc, tcgv_i32_arg(a1), a2);
81
+}
82
+
83
+static inline void tcg_gen_op2i_i64(TCGOpcode opc, TCGv_i64 a1, TCGArg a2)
84
+{
85
+ tcg_gen_op2(opc, tcgv_i64_arg(a1), a2);
86
+}
87
+
88
+static inline void tcg_gen_op2ii(TCGOpcode opc, TCGArg a1, TCGArg a2)
89
+{
90
+ tcg_gen_op2(opc, a1, a2);
91
+}
92
+
93
+static inline void tcg_gen_op3_i32(TCGOpcode opc, TCGv_i32 a1,
94
+ TCGv_i32 a2, TCGv_i32 a3)
95
+{
96
+ tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), tcgv_i32_arg(a3));
97
+}
98
+
99
+static inline void tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 a1,
100
+ TCGv_i64 a2, TCGv_i64 a3)
101
+{
102
+ tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), tcgv_i64_arg(a3));
103
+}
104
+
105
+static inline void tcg_gen_op3i_i32(TCGOpcode opc, TCGv_i32 a1,
106
+ TCGv_i32 a2, TCGArg a3)
107
+{
108
+ tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3);
109
+}
110
+
111
+static inline void tcg_gen_op3i_i64(TCGOpcode opc, TCGv_i64 a1,
112
+ TCGv_i64 a2, TCGArg a3)
113
+{
114
+ tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3);
115
+}
116
+
117
+static inline void tcg_gen_ldst_op_i32(TCGOpcode opc, TCGv_i32 val,
118
+ TCGv_ptr base, TCGArg offset)
119
+{
120
+ tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_ptr_arg(base), offset);
121
+}
122
+
123
+static inline void tcg_gen_ldst_op_i64(TCGOpcode opc, TCGv_i64 val,
124
+ TCGv_ptr base, TCGArg offset)
125
+{
126
+ tcg_gen_op3(opc, tcgv_i64_arg(val), tcgv_ptr_arg(base), offset);
127
+}
128
+
129
+static inline void tcg_gen_op4_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
130
+ TCGv_i32 a3, TCGv_i32 a4)
131
+{
132
+ tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
133
+ tcgv_i32_arg(a3), tcgv_i32_arg(a4));
134
+}
135
+
136
+static inline void tcg_gen_op4_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
137
+ TCGv_i64 a3, TCGv_i64 a4)
138
+{
139
+ tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
140
+ tcgv_i64_arg(a3), tcgv_i64_arg(a4));
141
+}
142
+
143
+static inline void tcg_gen_op4i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
144
+ TCGv_i32 a3, TCGArg a4)
145
+{
146
+ tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
147
+ tcgv_i32_arg(a3), a4);
148
+}
149
+
150
+static inline void tcg_gen_op4i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
151
+ TCGv_i64 a3, TCGArg a4)
152
+{
153
+ tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
154
+ tcgv_i64_arg(a3), a4);
155
+}
156
+
157
+static inline void tcg_gen_op4ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
158
+ TCGArg a3, TCGArg a4)
159
+{
160
+ tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3, a4);
161
+}
162
+
163
+static inline void tcg_gen_op4ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
164
+ TCGArg a3, TCGArg a4)
165
+{
166
+ tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3, a4);
167
+}
168
+
169
+static inline void tcg_gen_op5_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
170
+ TCGv_i32 a3, TCGv_i32 a4, TCGv_i32 a5)
171
+{
172
+ tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
173
+ tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5));
174
+}
175
+
176
+static inline void tcg_gen_op5_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
177
+ TCGv_i64 a3, TCGv_i64 a4, TCGv_i64 a5)
178
+{
179
+ tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
180
+ tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5));
181
+}
182
+
183
+static inline void tcg_gen_op5i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
184
+ TCGv_i32 a3, TCGv_i32 a4, TCGArg a5)
185
+{
186
+ tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
187
+ tcgv_i32_arg(a3), tcgv_i32_arg(a4), a5);
188
+}
189
+
190
+static inline void tcg_gen_op5i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
191
+ TCGv_i64 a3, TCGv_i64 a4, TCGArg a5)
192
+{
193
+ tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
194
+ tcgv_i64_arg(a3), tcgv_i64_arg(a4), a5);
195
+}
196
+
197
+static inline void tcg_gen_op5ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
198
+ TCGv_i32 a3, TCGArg a4, TCGArg a5)
199
+{
200
+ tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
201
+ tcgv_i32_arg(a3), a4, a5);
202
+}
203
+
204
+static inline void tcg_gen_op5ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
205
+ TCGv_i64 a3, TCGArg a4, TCGArg a5)
206
+{
207
+ tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
208
+ tcgv_i64_arg(a3), a4, a5);
209
+}
210
+
211
+static inline void tcg_gen_op6_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
212
+ TCGv_i32 a3, TCGv_i32 a4,
213
+ TCGv_i32 a5, TCGv_i32 a6)
214
+{
215
+ tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
216
+ tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5),
217
+ tcgv_i32_arg(a6));
218
+}
219
+
220
+static inline void tcg_gen_op6_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
221
+ TCGv_i64 a3, TCGv_i64 a4,
222
+ TCGv_i64 a5, TCGv_i64 a6)
223
+{
224
+ tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
225
+ tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5),
226
+ tcgv_i64_arg(a6));
227
+}
228
+
229
+static inline void tcg_gen_op6i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
230
+ TCGv_i32 a3, TCGv_i32 a4,
231
+ TCGv_i32 a5, TCGArg a6)
232
+{
233
+ tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
234
+ tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5), a6);
235
+}
236
+
237
+static inline void tcg_gen_op6i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
238
+ TCGv_i64 a3, TCGv_i64 a4,
239
+ TCGv_i64 a5, TCGArg a6)
240
+{
241
+ tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
242
+ tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5), a6);
243
+}
244
+
245
+static inline void tcg_gen_op6ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
246
+ TCGv_i32 a3, TCGv_i32 a4,
247
+ TCGArg a5, TCGArg a6)
248
+{
249
+ tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
250
+ tcgv_i32_arg(a3), tcgv_i32_arg(a4), a5, a6);
251
+}
252
+
253
+static inline void tcg_gen_op6ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
254
+ TCGv_i64 a3, TCGv_i64 a4,
255
+ TCGArg a5, TCGArg a6)
256
+{
257
+ tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
258
+ tcgv_i64_arg(a3), tcgv_i64_arg(a4), a5, a6);
259
+}
260
+
261
+
262
+/* Generic ops. */
263
+
264
+static inline void gen_set_label(TCGLabel *l)
265
+{
266
+ l->present = 1;
267
+ tcg_gen_op1(INDEX_op_set_label, label_arg(l));
268
+}
269
+
270
+void tcg_gen_br(TCGLabel *l);
271
+void tcg_gen_mb(TCGBar);
272
+
273
+/**
274
+ * tcg_gen_exit_tb() - output exit_tb TCG operation
275
+ * @tb: The TranslationBlock from which we are exiting
276
+ * @idx: Direct jump slot index, or exit request
277
+ *
278
+ * See tcg/README for more info about this TCG operation.
279
+ * See also tcg.h and the block comment above TB_EXIT_MASK.
280
+ *
281
+ * For a normal exit from the TB, back to the main loop, @tb should
282
+ * be NULL and @idx should be 0. Otherwise, @tb should be valid and
283
+ * @idx should be one of the TB_EXIT_ values.
284
+ */
285
+void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx);
286
+
287
+/**
288
+ * tcg_gen_goto_tb() - output goto_tb TCG operation
289
+ * @idx: Direct jump slot index (0 or 1)
290
+ *
291
+ * See tcg/README for more info about this TCG operation.
292
+ *
293
+ * NOTE: In softmmu emulation, direct jumps with goto_tb are only safe within
294
+ * the pages this TB resides in because we don't take care of direct jumps when
295
+ * address mapping changes, e.g. in tlb_flush(). In user mode, there's only a
296
+ * static address translation, so the destination address is always valid, TBs
297
+ * are always invalidated properly, and direct jumps are reset when mapping
298
+ * changes.
299
+ */
300
+void tcg_gen_goto_tb(unsigned idx);
301
+
302
+/**
303
+ * tcg_gen_lookup_and_goto_ptr() - look up the current TB, jump to it if valid
304
+ * @addr: Guest address of the target TB
305
+ *
306
+ * If the TB is not valid, jump to the epilogue.
307
+ *
308
+ * This operation is optional. If the TCG backend does not implement goto_ptr,
309
+ * this op is equivalent to calling tcg_gen_exit_tb() with 0 as the argument.
310
+ */
311
+void tcg_gen_lookup_and_goto_ptr(void);
312
+
313
+static inline void tcg_gen_plugin_cb_start(unsigned from, unsigned type,
314
+ unsigned wr)
315
+{
316
+ tcg_gen_op3(INDEX_op_plugin_cb_start, from, type, wr);
317
+}
318
+
319
+static inline void tcg_gen_plugin_cb_end(void)
320
+{
321
+ tcg_emit_op(INDEX_op_plugin_cb_end, 0);
322
+}
323
+
324
+/* 32 bit ops */
325
+
326
+void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg);
327
+void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
328
+void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2);
329
+void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
330
+void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
331
+void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
332
+void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
333
+void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
334
+void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
335
+void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
336
+void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
337
+void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
338
+void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
339
+void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
340
+void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
341
+void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
342
+void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
343
+void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
344
+void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
345
+void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
346
+void tcg_gen_clz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
347
+void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
348
+void tcg_gen_clzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2);
349
+void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2);
350
+void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg);
351
+void tcg_gen_ctpop_i32(TCGv_i32 a1, TCGv_i32 a2);
352
+void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
353
+void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
354
+void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
355
+void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
356
+void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
357
+ unsigned int ofs, unsigned int len);
358
+void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
359
+ unsigned int ofs, unsigned int len);
360
+void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
361
+ unsigned int ofs, unsigned int len);
362
+void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
363
+ unsigned int ofs, unsigned int len);
364
+void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
365
+ unsigned int ofs);
366
+void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *);
367
+void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *);
368
+void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
369
+ TCGv_i32 arg1, TCGv_i32 arg2);
370
+void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
371
+ TCGv_i32 arg1, int32_t arg2);
372
+void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
373
+ TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2);
374
+void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
375
+ TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh);
376
+void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
377
+ TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh);
378
+void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
379
+void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
380
+void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
381
+void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg);
382
+void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg);
383
+void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg);
384
+void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg);
385
+void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags);
386
+void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg);
387
+void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg);
388
+void tcg_gen_smin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
389
+void tcg_gen_smax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
390
+void tcg_gen_umin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
391
+void tcg_gen_umax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
392
+void tcg_gen_abs_i32(TCGv_i32, TCGv_i32);
393
+
394
+/* Replicate a value of size @vece from @in to all the lanes in @out */
395
+void tcg_gen_dup_i32(unsigned vece, TCGv_i32 out, TCGv_i32 in);
396
+
397
+static inline void tcg_gen_discard_i32(TCGv_i32 arg)
398
+{
399
+ tcg_gen_op1_i32(INDEX_op_discard, arg);
400
+}
401
+
402
+static inline void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
403
+{
404
+ if (ret != arg) {
405
+ tcg_gen_op2_i32(INDEX_op_mov_i32, ret, arg);
406
+ }
407
+}
408
+
409
+static inline void tcg_gen_ld8u_i32(TCGv_i32 ret, TCGv_ptr arg2,
410
+ tcg_target_long offset)
411
+{
412
+ tcg_gen_ldst_op_i32(INDEX_op_ld8u_i32, ret, arg2, offset);
413
+}
414
+
415
+static inline void tcg_gen_ld8s_i32(TCGv_i32 ret, TCGv_ptr arg2,
416
+ tcg_target_long offset)
417
+{
418
+ tcg_gen_ldst_op_i32(INDEX_op_ld8s_i32, ret, arg2, offset);
419
+}
420
+
421
+static inline void tcg_gen_ld16u_i32(TCGv_i32 ret, TCGv_ptr arg2,
422
+ tcg_target_long offset)
423
+{
424
+ tcg_gen_ldst_op_i32(INDEX_op_ld16u_i32, ret, arg2, offset);
425
+}
426
+
427
+static inline void tcg_gen_ld16s_i32(TCGv_i32 ret, TCGv_ptr arg2,
428
+ tcg_target_long offset)
429
+{
430
+ tcg_gen_ldst_op_i32(INDEX_op_ld16s_i32, ret, arg2, offset);
431
+}
432
+
433
+static inline void tcg_gen_ld_i32(TCGv_i32 ret, TCGv_ptr arg2,
434
+ tcg_target_long offset)
435
+{
436
+ tcg_gen_ldst_op_i32(INDEX_op_ld_i32, ret, arg2, offset);
437
+}
438
+
439
+static inline void tcg_gen_st8_i32(TCGv_i32 arg1, TCGv_ptr arg2,
440
+ tcg_target_long offset)
441
+{
442
+ tcg_gen_ldst_op_i32(INDEX_op_st8_i32, arg1, arg2, offset);
443
+}
444
+
445
+static inline void tcg_gen_st16_i32(TCGv_i32 arg1, TCGv_ptr arg2,
446
+ tcg_target_long offset)
447
+{
448
+ tcg_gen_ldst_op_i32(INDEX_op_st16_i32, arg1, arg2, offset);
449
+}
450
+
451
+static inline void tcg_gen_st_i32(TCGv_i32 arg1, TCGv_ptr arg2,
452
+ tcg_target_long offset)
453
+{
454
+ tcg_gen_ldst_op_i32(INDEX_op_st_i32, arg1, arg2, offset);
455
+}
456
+
457
+static inline void tcg_gen_add_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
458
+{
459
+ tcg_gen_op3_i32(INDEX_op_add_i32, ret, arg1, arg2);
460
+}
461
+
462
+static inline void tcg_gen_sub_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
463
+{
464
+ tcg_gen_op3_i32(INDEX_op_sub_i32, ret, arg1, arg2);
465
+}
466
+
467
+static inline void tcg_gen_and_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
468
+{
469
+ tcg_gen_op3_i32(INDEX_op_and_i32, ret, arg1, arg2);
470
+}
471
+
472
+static inline void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
473
+{
474
+ tcg_gen_op3_i32(INDEX_op_or_i32, ret, arg1, arg2);
475
+}
476
+
477
+static inline void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
478
+{
479
+ tcg_gen_op3_i32(INDEX_op_xor_i32, ret, arg1, arg2);
480
+}
481
+
482
+static inline void tcg_gen_shl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
483
+{
484
+ tcg_gen_op3_i32(INDEX_op_shl_i32, ret, arg1, arg2);
485
+}
486
+
487
+static inline void tcg_gen_shr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
488
+{
489
+ tcg_gen_op3_i32(INDEX_op_shr_i32, ret, arg1, arg2);
490
+}
491
+
492
+static inline void tcg_gen_sar_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
493
+{
494
+ tcg_gen_op3_i32(INDEX_op_sar_i32, ret, arg1, arg2);
495
+}
496
+
497
+static inline void tcg_gen_mul_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
498
+{
499
+ tcg_gen_op3_i32(INDEX_op_mul_i32, ret, arg1, arg2);
500
+}
501
+
502
+static inline void tcg_gen_neg_i32(TCGv_i32 ret, TCGv_i32 arg)
503
+{
504
+ if (TCG_TARGET_HAS_neg_i32) {
505
+ tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg);
506
+ } else {
507
+ tcg_gen_subfi_i32(ret, 0, arg);
508
+ }
509
+}
510
+
511
+static inline void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg)
512
+{
513
+ if (TCG_TARGET_HAS_not_i32) {
514
+ tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg);
515
+ } else {
516
+ tcg_gen_xori_i32(ret, arg, -1);
517
+ }
518
+}
519
+
520
+/* 64 bit ops */
521
+
522
+void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg);
523
+void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
524
+void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2);
525
+void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
526
+void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
527
+void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
528
+void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
529
+void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
530
+void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
531
+void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
532
+void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
533
+void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
534
+void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
535
+void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
536
+void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
537
+void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
538
+void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
539
+void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
540
+void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
541
+void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
542
+void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
543
+void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
544
+void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2);
545
+void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2);
546
+void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg);
547
+void tcg_gen_ctpop_i64(TCGv_i64 a1, TCGv_i64 a2);
548
+void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
549
+void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
550
+void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
551
+void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
552
+void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
553
+ unsigned int ofs, unsigned int len);
554
+void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
555
+ unsigned int ofs, unsigned int len);
556
+void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
557
+ unsigned int ofs, unsigned int len);
558
+void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
559
+ unsigned int ofs, unsigned int len);
560
+void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
561
+ unsigned int ofs);
562
+void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *);
563
+void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *);
564
+void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
565
+ TCGv_i64 arg1, TCGv_i64 arg2);
566
+void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
567
+ TCGv_i64 arg1, int64_t arg2);
568
+void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
569
+ TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2);
570
+void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
571
+ TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh);
572
+void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
573
+ TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh);
574
+void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
575
+void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
576
+void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
577
+void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg);
578
+void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg);
579
+void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg);
580
+void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg);
581
+void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg);
582
+void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg);
583
+void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg);
584
+void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags);
585
+void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags);
586
+void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg);
587
+void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg);
588
+void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg);
589
+void tcg_gen_smin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
590
+void tcg_gen_smax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
591
+void tcg_gen_umin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
592
+void tcg_gen_umax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
593
+void tcg_gen_abs_i64(TCGv_i64, TCGv_i64);
594
+
595
+/* Replicate a value of size @vece from @in to all the lanes in @out */
596
+void tcg_gen_dup_i64(unsigned vece, TCGv_i64 out, TCGv_i64 in);
597
+
598
+#if TCG_TARGET_REG_BITS == 64
599
+static inline void tcg_gen_discard_i64(TCGv_i64 arg)
600
+{
601
+ tcg_gen_op1_i64(INDEX_op_discard, arg);
602
+}
603
+
604
+static inline void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
605
+{
606
+ if (ret != arg) {
607
+ tcg_gen_op2_i64(INDEX_op_mov_i64, ret, arg);
608
+ }
609
+}
610
+
611
+static inline void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2,
612
+ tcg_target_long offset)
613
+{
614
+ tcg_gen_ldst_op_i64(INDEX_op_ld8u_i64, ret, arg2, offset);
615
+}
616
+
617
+static inline void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2,
618
+ tcg_target_long offset)
619
+{
620
+ tcg_gen_ldst_op_i64(INDEX_op_ld8s_i64, ret, arg2, offset);
621
+}
622
+
623
+static inline void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2,
624
+ tcg_target_long offset)
625
+{
626
+ tcg_gen_ldst_op_i64(INDEX_op_ld16u_i64, ret, arg2, offset);
627
+}
628
+
629
+static inline void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2,
630
+ tcg_target_long offset)
631
+{
632
+ tcg_gen_ldst_op_i64(INDEX_op_ld16s_i64, ret, arg2, offset);
633
+}
634
+
635
+static inline void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2,
636
+ tcg_target_long offset)
637
+{
638
+ tcg_gen_ldst_op_i64(INDEX_op_ld32u_i64, ret, arg2, offset);
639
+}
640
+
641
+static inline void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2,
642
+ tcg_target_long offset)
643
+{
644
+ tcg_gen_ldst_op_i64(INDEX_op_ld32s_i64, ret, arg2, offset);
645
+}
646
+
647
+static inline void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2,
648
+ tcg_target_long offset)
649
+{
650
+ tcg_gen_ldst_op_i64(INDEX_op_ld_i64, ret, arg2, offset);
651
+}
652
+
653
+static inline void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2,
654
+ tcg_target_long offset)
655
+{
656
+ tcg_gen_ldst_op_i64(INDEX_op_st8_i64, arg1, arg2, offset);
657
+}
658
+
659
+static inline void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2,
660
+ tcg_target_long offset)
661
+{
662
+ tcg_gen_ldst_op_i64(INDEX_op_st16_i64, arg1, arg2, offset);
663
+}
664
+
665
+static inline void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2,
666
+ tcg_target_long offset)
667
+{
668
+ tcg_gen_ldst_op_i64(INDEX_op_st32_i64, arg1, arg2, offset);
669
+}
670
+
671
+static inline void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2,
672
+ tcg_target_long offset)
673
+{
674
+ tcg_gen_ldst_op_i64(INDEX_op_st_i64, arg1, arg2, offset);
675
+}
676
+
677
+static inline void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
678
+{
679
+ tcg_gen_op3_i64(INDEX_op_add_i64, ret, arg1, arg2);
680
+}
681
+
682
+static inline void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
683
+{
684
+ tcg_gen_op3_i64(INDEX_op_sub_i64, ret, arg1, arg2);
685
+}
686
+
687
+static inline void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
688
+{
689
+ tcg_gen_op3_i64(INDEX_op_and_i64, ret, arg1, arg2);
690
+}
691
+
692
+static inline void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
693
+{
694
+ tcg_gen_op3_i64(INDEX_op_or_i64, ret, arg1, arg2);
695
+}
696
+
697
+static inline void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
698
+{
699
+ tcg_gen_op3_i64(INDEX_op_xor_i64, ret, arg1, arg2);
700
+}
701
+
702
+static inline void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
703
+{
704
+ tcg_gen_op3_i64(INDEX_op_shl_i64, ret, arg1, arg2);
705
+}
706
+
707
+static inline void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
708
+{
709
+ tcg_gen_op3_i64(INDEX_op_shr_i64, ret, arg1, arg2);
710
+}
711
+
712
+static inline void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
713
+{
714
+ tcg_gen_op3_i64(INDEX_op_sar_i64, ret, arg1, arg2);
715
+}
716
+
717
+static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
718
+{
719
+ tcg_gen_op3_i64(INDEX_op_mul_i64, ret, arg1, arg2);
720
+}
721
+#else /* TCG_TARGET_REG_BITS == 32 */
722
+void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset);
723
+void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset);
724
+void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset);
725
+
726
+void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
727
+void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
728
+
729
+void tcg_gen_discard_i64(TCGv_i64 arg);
730
+void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg);
731
+void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
732
+void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
733
+void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
734
+void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
735
+void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
736
+void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
737
+void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
738
+void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset);
739
+void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
740
+void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
741
+void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
742
+void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
743
+void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
744
+void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
745
+void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
746
+#endif /* TCG_TARGET_REG_BITS */
747
+
748
+static inline void tcg_gen_neg_i64(TCGv_i64 ret, TCGv_i64 arg)
749
+{
750
+ if (TCG_TARGET_HAS_neg_i64) {
751
+ tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg);
752
+ } else {
753
+ tcg_gen_subfi_i64(ret, 0, arg);
754
+ }
755
+}
756
+
757
+/* Size changing operations. */
758
+
759
+void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg);
760
+void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg);
761
+void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high);
762
+void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg);
763
+void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg);
764
+void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg);
765
+void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg);
766
+
767
+void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src);
768
+void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg);
769
+void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi);
770
+
771
+static inline void tcg_gen_concat32_i64(TCGv_i64 ret, TCGv_i64 lo, TCGv_i64 hi)
772
+{
773
+ tcg_gen_deposit_i64(ret, lo, hi, 32, 32);
774
+}
775
+
776
+/* Local load/store bit ops */
777
+
778
+void tcg_gen_qemu_ld_i32_chk(TCGv_i32, TCGTemp *, TCGArg, MemOp, TCGType);
779
+void tcg_gen_qemu_st_i32_chk(TCGv_i32, TCGTemp *, TCGArg, MemOp, TCGType);
780
+void tcg_gen_qemu_ld_i64_chk(TCGv_i64, TCGTemp *, TCGArg, MemOp, TCGType);
781
+void tcg_gen_qemu_st_i64_chk(TCGv_i64, TCGTemp *, TCGArg, MemOp, TCGType);
782
+void tcg_gen_qemu_ld_i128_chk(TCGv_i128, TCGTemp *, TCGArg, MemOp, TCGType);
783
+void tcg_gen_qemu_st_i128_chk(TCGv_i128, TCGTemp *, TCGArg, MemOp, TCGType);
784
+
785
+/* Atomic ops */
786
+
787
+void tcg_gen_atomic_cmpxchg_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32, TCGv_i32,
788
+ TCGArg, MemOp, TCGType);
789
+void tcg_gen_atomic_cmpxchg_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64, TCGv_i64,
790
+ TCGArg, MemOp, TCGType);
791
+void tcg_gen_atomic_cmpxchg_i128_chk(TCGv_i128, TCGTemp *, TCGv_i128,
792
+ TCGv_i128, TCGArg, MemOp, TCGType);
793
+
794
+void tcg_gen_nonatomic_cmpxchg_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32, TCGv_i32,
795
+ TCGArg, MemOp, TCGType);
796
+void tcg_gen_nonatomic_cmpxchg_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64, TCGv_i64,
797
+ TCGArg, MemOp, TCGType);
798
+void tcg_gen_nonatomic_cmpxchg_i128_chk(TCGv_i128, TCGTemp *, TCGv_i128,
799
+ TCGv_i128, TCGArg, MemOp, TCGType);
800
+
801
+void tcg_gen_atomic_xchg_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
802
+ TCGArg, MemOp, TCGType);
803
+void tcg_gen_atomic_xchg_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
804
+ TCGArg, MemOp, TCGType);
805
+
806
+void tcg_gen_atomic_fetch_add_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
807
+ TCGArg, MemOp, TCGType);
808
+void tcg_gen_atomic_fetch_add_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
809
+ TCGArg, MemOp, TCGType);
810
+void tcg_gen_atomic_fetch_and_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
811
+ TCGArg, MemOp, TCGType);
812
+void tcg_gen_atomic_fetch_and_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
813
+ TCGArg, MemOp, TCGType);
814
+void tcg_gen_atomic_fetch_or_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
815
+ TCGArg, MemOp, TCGType);
816
+void tcg_gen_atomic_fetch_or_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
817
+ TCGArg, MemOp, TCGType);
818
+void tcg_gen_atomic_fetch_xor_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
819
+ TCGArg, MemOp, TCGType);
820
+void tcg_gen_atomic_fetch_xor_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
821
+ TCGArg, MemOp, TCGType);
822
+void tcg_gen_atomic_fetch_smin_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
823
+ TCGArg, MemOp, TCGType);
824
+void tcg_gen_atomic_fetch_smin_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
825
+ TCGArg, MemOp, TCGType);
826
+void tcg_gen_atomic_fetch_umin_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
827
+ TCGArg, MemOp, TCGType);
828
+void tcg_gen_atomic_fetch_umin_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
829
+ TCGArg, MemOp, TCGType);
830
+void tcg_gen_atomic_fetch_smax_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
831
+ TCGArg, MemOp, TCGType);
832
+void tcg_gen_atomic_fetch_smax_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
833
+ TCGArg, MemOp, TCGType);
834
+void tcg_gen_atomic_fetch_umax_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
835
+ TCGArg, MemOp, TCGType);
836
+void tcg_gen_atomic_fetch_umax_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
837
+ TCGArg, MemOp, TCGType);
838
+
839
+void tcg_gen_atomic_add_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
840
+ TCGArg, MemOp, TCGType);
841
+void tcg_gen_atomic_add_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
842
+ TCGArg, MemOp, TCGType);
843
+void tcg_gen_atomic_and_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
844
+ TCGArg, MemOp, TCGType);
845
+void tcg_gen_atomic_and_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
846
+ TCGArg, MemOp, TCGType);
847
+void tcg_gen_atomic_or_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
848
+ TCGArg, MemOp, TCGType);
849
+void tcg_gen_atomic_or_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
850
+ TCGArg, MemOp, TCGType);
851
+void tcg_gen_atomic_xor_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
852
+ TCGArg, MemOp, TCGType);
853
+void tcg_gen_atomic_xor_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
854
+ TCGArg, MemOp, TCGType);
855
+void tcg_gen_atomic_smin_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
856
+ TCGArg, MemOp, TCGType);
857
+void tcg_gen_atomic_smin_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
858
+ TCGArg, MemOp, TCGType);
859
+void tcg_gen_atomic_umin_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
860
+ TCGArg, MemOp, TCGType);
861
+void tcg_gen_atomic_umin_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
862
+ TCGArg, MemOp, TCGType);
863
+void tcg_gen_atomic_smax_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
864
+ TCGArg, MemOp, TCGType);
865
+void tcg_gen_atomic_smax_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
866
+ TCGArg, MemOp, TCGType);
867
+void tcg_gen_atomic_umax_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
868
+ TCGArg, MemOp, TCGType);
869
+void tcg_gen_atomic_umax_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
870
+ TCGArg, MemOp, TCGType);
871
+
872
+/* Vector ops */
873
+
874
+void tcg_gen_mov_vec(TCGv_vec, TCGv_vec);
875
+void tcg_gen_dup_i32_vec(unsigned vece, TCGv_vec, TCGv_i32);
876
+void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec, TCGv_i64);
877
+void tcg_gen_dup_mem_vec(unsigned vece, TCGv_vec, TCGv_ptr, tcg_target_long);
878
+void tcg_gen_dupi_vec(unsigned vece, TCGv_vec, uint64_t);
879
+void tcg_gen_add_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
880
+void tcg_gen_sub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
881
+void tcg_gen_mul_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
882
+void tcg_gen_and_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
883
+void tcg_gen_or_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
884
+void tcg_gen_xor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
885
+void tcg_gen_andc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
886
+void tcg_gen_orc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
887
+void tcg_gen_nand_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
888
+void tcg_gen_nor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
889
+void tcg_gen_eqv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
890
+void tcg_gen_not_vec(unsigned vece, TCGv_vec r, TCGv_vec a);
891
+void tcg_gen_neg_vec(unsigned vece, TCGv_vec r, TCGv_vec a);
892
+void tcg_gen_abs_vec(unsigned vece, TCGv_vec r, TCGv_vec a);
893
+void tcg_gen_ssadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
894
+void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
895
+void tcg_gen_sssub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
896
+void tcg_gen_ussub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
897
+void tcg_gen_smin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
898
+void tcg_gen_umin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
899
+void tcg_gen_smax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
900
+void tcg_gen_umax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
901
+
902
+void tcg_gen_shli_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
903
+void tcg_gen_shri_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
904
+void tcg_gen_sari_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
905
+void tcg_gen_rotli_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
906
+void tcg_gen_rotri_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
907
+
908
+void tcg_gen_shls_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
909
+void tcg_gen_shrs_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
910
+void tcg_gen_sars_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
911
+void tcg_gen_rotls_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
912
+
913
+void tcg_gen_shlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
914
+void tcg_gen_shrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
915
+void tcg_gen_sarv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
916
+void tcg_gen_rotlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
917
+void tcg_gen_rotrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
918
+
919
+void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, TCGv_vec r,
920
+ TCGv_vec a, TCGv_vec b);
921
+
922
+void tcg_gen_bitsel_vec(unsigned vece, TCGv_vec r, TCGv_vec a,
923
+ TCGv_vec b, TCGv_vec c);
924
+void tcg_gen_cmpsel_vec(TCGCond cond, unsigned vece, TCGv_vec r,
925
+ TCGv_vec a, TCGv_vec b, TCGv_vec c, TCGv_vec d);
926
+
927
+void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset);
928
+void tcg_gen_st_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset);
929
+void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
930
+
931
+/* Host pointer ops */
932
+
933
+#if UINTPTR_MAX == UINT32_MAX
934
+# define PTR i32
935
+# define NAT TCGv_i32
936
+#else
937
+# define PTR i64
938
+# define NAT TCGv_i64
939
+#endif
940
+
941
+static inline void tcg_gen_ld_ptr(TCGv_ptr r, TCGv_ptr a, intptr_t o)
942
+{
943
+ glue(tcg_gen_ld_,PTR)((NAT)r, a, o);
944
+}
945
+
946
+static inline void tcg_gen_st_ptr(TCGv_ptr r, TCGv_ptr a, intptr_t o)
947
+{
948
+ glue(tcg_gen_st_, PTR)((NAT)r, a, o);
949
+}
950
+
951
+static inline void tcg_gen_discard_ptr(TCGv_ptr a)
952
+{
953
+ glue(tcg_gen_discard_,PTR)((NAT)a);
954
+}
955
+
956
+static inline void tcg_gen_add_ptr(TCGv_ptr r, TCGv_ptr a, TCGv_ptr b)
957
+{
958
+ glue(tcg_gen_add_,PTR)((NAT)r, (NAT)a, (NAT)b);
959
+}
960
+
961
+static inline void tcg_gen_addi_ptr(TCGv_ptr r, TCGv_ptr a, intptr_t b)
962
+{
963
+ glue(tcg_gen_addi_,PTR)((NAT)r, (NAT)a, b);
964
+}
965
+
966
+static inline void tcg_gen_mov_ptr(TCGv_ptr d, TCGv_ptr s)
967
+{
968
+ glue(tcg_gen_mov_,PTR)((NAT)d, (NAT)s);
969
+}
970
+
971
+static inline void tcg_gen_movi_ptr(TCGv_ptr d, intptr_t s)
972
+{
973
+ glue(tcg_gen_movi_,PTR)((NAT)d, s);
974
+}
975
+
976
+static inline void tcg_gen_brcondi_ptr(TCGCond cond, TCGv_ptr a,
977
+ intptr_t b, TCGLabel *label)
978
+{
979
+ glue(tcg_gen_brcondi_,PTR)(cond, (NAT)a, b, label);
980
+}
981
+
982
+static inline void tcg_gen_ext_i32_ptr(TCGv_ptr r, TCGv_i32 a)
983
+{
984
+#if UINTPTR_MAX == UINT32_MAX
985
+ tcg_gen_mov_i32((NAT)r, a);
986
+#else
987
+ tcg_gen_ext_i32_i64((NAT)r, a);
988
+#endif
989
+}
990
+
991
+static inline void tcg_gen_trunc_i64_ptr(TCGv_ptr r, TCGv_i64 a)
992
+{
993
+#if UINTPTR_MAX == UINT32_MAX
994
+ tcg_gen_extrl_i64_i32((NAT)r, a);
995
+#else
996
+ tcg_gen_mov_i64((NAT)r, a);
997
+#endif
998
+}
999
+
1000
+static inline void tcg_gen_extu_ptr_i64(TCGv_i64 r, TCGv_ptr a)
1001
+{
1002
+#if UINTPTR_MAX == UINT32_MAX
1003
+ tcg_gen_extu_i32_i64(r, (NAT)a);
1004
+#else
1005
+ tcg_gen_mov_i64(r, (NAT)a);
1006
+#endif
1007
+}
1008
+
1009
+static inline void tcg_gen_trunc_ptr_i32(TCGv_i32 r, TCGv_ptr a)
1010
+{
1011
+#if UINTPTR_MAX == UINT32_MAX
1012
+ tcg_gen_mov_i32(r, (NAT)a);
1013
+#else
1014
+ tcg_gen_extrl_i64_i32(r, (NAT)a);
1015
+#endif
1016
+}
1017
+
1018
+#undef PTR
1019
+#undef NAT
1020
+
1021
+#endif /* TCG_TCG_OP_COMMON_H */
1022
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
1023
index XXXXXXX..XXXXXXX 100644
1024
--- a/include/tcg/tcg-op.h
1025
+++ b/include/tcg/tcg-op.h
1026
@@ -XXX,XX +XXX,XX @@
1027
+/* SPDX-License-Identifier: MIT */
1028
/*
1029
- * Tiny Code Generator for QEMU
1030
+ * Target dependent opcode generation functions.
1031
*
1032
* Copyright (c) 2008 Fabrice Bellard
1033
- *
1034
- * Permission is hereby granted, free of charge, to any person obtaining a copy
1035
- * of this software and associated documentation files (the "Software"), to deal
1036
- * in the Software without restriction, including without limitation the rights
1037
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1038
- * copies of the Software, and to permit persons to whom the Software is
1039
- * furnished to do so, subject to the following conditions:
1040
- *
1041
- * The above copyright notice and this permission notice shall be included in
1042
- * all copies or substantial portions of the Software.
1043
- *
1044
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1045
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1046
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1047
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1048
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1049
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1050
- * THE SOFTWARE.
1051
*/
1052
1053
#ifndef TCG_TCG_OP_H
1054
#define TCG_TCG_OP_H
1055
1056
-#include "tcg/tcg.h"
1057
-#include "exec/helper-proto.h"
1058
-#include "exec/helper-gen.h"
1059
-
1060
-/* Basic output routines. Not for general consumption. */
1061
-
1062
-void tcg_gen_op1(TCGOpcode, TCGArg);
1063
-void tcg_gen_op2(TCGOpcode, TCGArg, TCGArg);
1064
-void tcg_gen_op3(TCGOpcode, TCGArg, TCGArg, TCGArg);
1065
-void tcg_gen_op4(TCGOpcode, TCGArg, TCGArg, TCGArg, TCGArg);
1066
-void tcg_gen_op5(TCGOpcode, TCGArg, TCGArg, TCGArg, TCGArg, TCGArg);
1067
-void tcg_gen_op6(TCGOpcode, TCGArg, TCGArg, TCGArg, TCGArg, TCGArg, TCGArg);
1068
-
1069
-void vec_gen_2(TCGOpcode, TCGType, unsigned, TCGArg, TCGArg);
1070
-void vec_gen_3(TCGOpcode, TCGType, unsigned, TCGArg, TCGArg, TCGArg);
1071
-void vec_gen_4(TCGOpcode, TCGType, unsigned, TCGArg, TCGArg, TCGArg, TCGArg);
1072
-
1073
-static inline void tcg_gen_op1_i32(TCGOpcode opc, TCGv_i32 a1)
1074
-{
1075
- tcg_gen_op1(opc, tcgv_i32_arg(a1));
1076
-}
1077
-
1078
-static inline void tcg_gen_op1_i64(TCGOpcode opc, TCGv_i64 a1)
1079
-{
1080
- tcg_gen_op1(opc, tcgv_i64_arg(a1));
1081
-}
1082
-
1083
-static inline void tcg_gen_op1i(TCGOpcode opc, TCGArg a1)
1084
-{
1085
- tcg_gen_op1(opc, a1);
1086
-}
1087
-
1088
-static inline void tcg_gen_op2_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2)
1089
-{
1090
- tcg_gen_op2(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2));
1091
-}
1092
-
1093
-static inline void tcg_gen_op2_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2)
1094
-{
1095
- tcg_gen_op2(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2));
1096
-}
1097
-
1098
-static inline void tcg_gen_op2i_i32(TCGOpcode opc, TCGv_i32 a1, TCGArg a2)
1099
-{
1100
- tcg_gen_op2(opc, tcgv_i32_arg(a1), a2);
1101
-}
1102
-
1103
-static inline void tcg_gen_op2i_i64(TCGOpcode opc, TCGv_i64 a1, TCGArg a2)
1104
-{
1105
- tcg_gen_op2(opc, tcgv_i64_arg(a1), a2);
1106
-}
1107
-
1108
-static inline void tcg_gen_op2ii(TCGOpcode opc, TCGArg a1, TCGArg a2)
1109
-{
1110
- tcg_gen_op2(opc, a1, a2);
1111
-}
1112
-
1113
-static inline void tcg_gen_op3_i32(TCGOpcode opc, TCGv_i32 a1,
1114
- TCGv_i32 a2, TCGv_i32 a3)
1115
-{
1116
- tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), tcgv_i32_arg(a3));
1117
-}
1118
-
1119
-static inline void tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 a1,
1120
- TCGv_i64 a2, TCGv_i64 a3)
1121
-{
1122
- tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), tcgv_i64_arg(a3));
1123
-}
1124
-
1125
-static inline void tcg_gen_op3i_i32(TCGOpcode opc, TCGv_i32 a1,
1126
- TCGv_i32 a2, TCGArg a3)
1127
-{
1128
- tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3);
1129
-}
1130
-
1131
-static inline void tcg_gen_op3i_i64(TCGOpcode opc, TCGv_i64 a1,
1132
- TCGv_i64 a2, TCGArg a3)
1133
-{
1134
- tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3);
1135
-}
1136
-
1137
-static inline void tcg_gen_ldst_op_i32(TCGOpcode opc, TCGv_i32 val,
1138
- TCGv_ptr base, TCGArg offset)
1139
-{
1140
- tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_ptr_arg(base), offset);
1141
-}
1142
-
1143
-static inline void tcg_gen_ldst_op_i64(TCGOpcode opc, TCGv_i64 val,
1144
- TCGv_ptr base, TCGArg offset)
1145
-{
1146
- tcg_gen_op3(opc, tcgv_i64_arg(val), tcgv_ptr_arg(base), offset);
1147
-}
1148
-
1149
-static inline void tcg_gen_op4_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1150
- TCGv_i32 a3, TCGv_i32 a4)
1151
-{
1152
- tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1153
- tcgv_i32_arg(a3), tcgv_i32_arg(a4));
1154
-}
1155
-
1156
-static inline void tcg_gen_op4_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1157
- TCGv_i64 a3, TCGv_i64 a4)
1158
-{
1159
- tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1160
- tcgv_i64_arg(a3), tcgv_i64_arg(a4));
1161
-}
1162
-
1163
-static inline void tcg_gen_op4i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1164
- TCGv_i32 a3, TCGArg a4)
1165
-{
1166
- tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1167
- tcgv_i32_arg(a3), a4);
1168
-}
1169
-
1170
-static inline void tcg_gen_op4i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1171
- TCGv_i64 a3, TCGArg a4)
1172
-{
1173
- tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1174
- tcgv_i64_arg(a3), a4);
1175
-}
1176
-
1177
-static inline void tcg_gen_op4ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1178
- TCGArg a3, TCGArg a4)
1179
-{
1180
- tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3, a4);
1181
-}
1182
-
1183
-static inline void tcg_gen_op4ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1184
- TCGArg a3, TCGArg a4)
1185
-{
1186
- tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3, a4);
1187
-}
1188
-
1189
-static inline void tcg_gen_op5_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1190
- TCGv_i32 a3, TCGv_i32 a4, TCGv_i32 a5)
1191
-{
1192
- tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1193
- tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5));
1194
-}
1195
-
1196
-static inline void tcg_gen_op5_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1197
- TCGv_i64 a3, TCGv_i64 a4, TCGv_i64 a5)
1198
-{
1199
- tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1200
- tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5));
1201
-}
1202
-
1203
-static inline void tcg_gen_op5i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1204
- TCGv_i32 a3, TCGv_i32 a4, TCGArg a5)
1205
-{
1206
- tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1207
- tcgv_i32_arg(a3), tcgv_i32_arg(a4), a5);
1208
-}
1209
-
1210
-static inline void tcg_gen_op5i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1211
- TCGv_i64 a3, TCGv_i64 a4, TCGArg a5)
1212
-{
1213
- tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1214
- tcgv_i64_arg(a3), tcgv_i64_arg(a4), a5);
1215
-}
1216
-
1217
-static inline void tcg_gen_op5ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1218
- TCGv_i32 a3, TCGArg a4, TCGArg a5)
1219
-{
1220
- tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1221
- tcgv_i32_arg(a3), a4, a5);
1222
-}
1223
-
1224
-static inline void tcg_gen_op5ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1225
- TCGv_i64 a3, TCGArg a4, TCGArg a5)
1226
-{
1227
- tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1228
- tcgv_i64_arg(a3), a4, a5);
1229
-}
1230
-
1231
-static inline void tcg_gen_op6_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1232
- TCGv_i32 a3, TCGv_i32 a4,
1233
- TCGv_i32 a5, TCGv_i32 a6)
1234
-{
1235
- tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1236
- tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5),
1237
- tcgv_i32_arg(a6));
1238
-}
1239
-
1240
-static inline void tcg_gen_op6_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1241
- TCGv_i64 a3, TCGv_i64 a4,
1242
- TCGv_i64 a5, TCGv_i64 a6)
1243
-{
1244
- tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1245
- tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5),
1246
- tcgv_i64_arg(a6));
1247
-}
1248
-
1249
-static inline void tcg_gen_op6i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1250
- TCGv_i32 a3, TCGv_i32 a4,
1251
- TCGv_i32 a5, TCGArg a6)
1252
-{
1253
- tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1254
- tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5), a6);
1255
-}
1256
-
1257
-static inline void tcg_gen_op6i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1258
- TCGv_i64 a3, TCGv_i64 a4,
1259
- TCGv_i64 a5, TCGArg a6)
1260
-{
1261
- tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1262
- tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5), a6);
1263
-}
1264
-
1265
-static inline void tcg_gen_op6ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1266
- TCGv_i32 a3, TCGv_i32 a4,
1267
- TCGArg a5, TCGArg a6)
1268
-{
1269
- tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1270
- tcgv_i32_arg(a3), tcgv_i32_arg(a4), a5, a6);
1271
-}
1272
-
1273
-static inline void tcg_gen_op6ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1274
- TCGv_i64 a3, TCGv_i64 a4,
1275
- TCGArg a5, TCGArg a6)
1276
-{
1277
- tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1278
- tcgv_i64_arg(a3), tcgv_i64_arg(a4), a5, a6);
1279
-}
1280
-
1281
-
1282
-/* Generic ops. */
1283
-
1284
-static inline void gen_set_label(TCGLabel *l)
1285
-{
1286
- l->present = 1;
1287
- tcg_gen_op1(INDEX_op_set_label, label_arg(l));
1288
-}
1289
-
1290
-void tcg_gen_br(TCGLabel *l);
1291
-void tcg_gen_mb(TCGBar);
1292
-
1293
-/* Helper calls. */
1294
-
1295
-/* 32 bit ops */
1296
-
1297
-void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg);
1298
-void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1299
-void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2);
1300
-void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1301
-void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1302
-void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1303
-void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1304
-void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1305
-void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1306
-void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1307
-void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1308
-void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1309
-void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1310
-void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1311
-void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1312
-void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1313
-void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1314
-void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1315
-void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1316
-void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1317
-void tcg_gen_clz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1318
-void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1319
-void tcg_gen_clzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2);
1320
-void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2);
1321
-void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg);
1322
-void tcg_gen_ctpop_i32(TCGv_i32 a1, TCGv_i32 a2);
1323
-void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1324
-void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1325
-void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2);
1326
-void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2);
1327
-void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
1328
- unsigned int ofs, unsigned int len);
1329
-void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
1330
- unsigned int ofs, unsigned int len);
1331
-void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
1332
- unsigned int ofs, unsigned int len);
1333
-void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
1334
- unsigned int ofs, unsigned int len);
1335
-void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
1336
- unsigned int ofs);
1337
-void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *);
1338
-void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *);
1339
-void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
1340
- TCGv_i32 arg1, TCGv_i32 arg2);
1341
-void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
1342
- TCGv_i32 arg1, int32_t arg2);
1343
-void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
1344
- TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2);
1345
-void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
1346
- TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh);
1347
-void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
1348
- TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh);
1349
-void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
1350
-void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
1351
-void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
1352
-void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg);
1353
-void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg);
1354
-void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg);
1355
-void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg);
1356
-void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags);
1357
-void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg);
1358
-void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg);
1359
-void tcg_gen_smin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
1360
-void tcg_gen_smax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
1361
-void tcg_gen_umin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
1362
-void tcg_gen_umax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
1363
-void tcg_gen_abs_i32(TCGv_i32, TCGv_i32);
1364
-
1365
-/* Replicate a value of size @vece from @in to all the lanes in @out */
1366
-void tcg_gen_dup_i32(unsigned vece, TCGv_i32 out, TCGv_i32 in);
1367
-
1368
-static inline void tcg_gen_discard_i32(TCGv_i32 arg)
1369
-{
1370
- tcg_gen_op1_i32(INDEX_op_discard, arg);
1371
-}
1372
-
1373
-static inline void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
1374
-{
1375
- if (ret != arg) {
1376
- tcg_gen_op2_i32(INDEX_op_mov_i32, ret, arg);
1377
- }
1378
-}
1379
-
1380
-static inline void tcg_gen_ld8u_i32(TCGv_i32 ret, TCGv_ptr arg2,
1381
- tcg_target_long offset)
1382
-{
1383
- tcg_gen_ldst_op_i32(INDEX_op_ld8u_i32, ret, arg2, offset);
1384
-}
1385
-
1386
-static inline void tcg_gen_ld8s_i32(TCGv_i32 ret, TCGv_ptr arg2,
1387
- tcg_target_long offset)
1388
-{
1389
- tcg_gen_ldst_op_i32(INDEX_op_ld8s_i32, ret, arg2, offset);
1390
-}
1391
-
1392
-static inline void tcg_gen_ld16u_i32(TCGv_i32 ret, TCGv_ptr arg2,
1393
- tcg_target_long offset)
1394
-{
1395
- tcg_gen_ldst_op_i32(INDEX_op_ld16u_i32, ret, arg2, offset);
1396
-}
1397
-
1398
-static inline void tcg_gen_ld16s_i32(TCGv_i32 ret, TCGv_ptr arg2,
1399
- tcg_target_long offset)
1400
-{
1401
- tcg_gen_ldst_op_i32(INDEX_op_ld16s_i32, ret, arg2, offset);
1402
-}
1403
-
1404
-static inline void tcg_gen_ld_i32(TCGv_i32 ret, TCGv_ptr arg2,
1405
- tcg_target_long offset)
1406
-{
1407
- tcg_gen_ldst_op_i32(INDEX_op_ld_i32, ret, arg2, offset);
1408
-}
1409
-
1410
-static inline void tcg_gen_st8_i32(TCGv_i32 arg1, TCGv_ptr arg2,
1411
- tcg_target_long offset)
1412
-{
1413
- tcg_gen_ldst_op_i32(INDEX_op_st8_i32, arg1, arg2, offset);
1414
-}
1415
-
1416
-static inline void tcg_gen_st16_i32(TCGv_i32 arg1, TCGv_ptr arg2,
1417
- tcg_target_long offset)
1418
-{
1419
- tcg_gen_ldst_op_i32(INDEX_op_st16_i32, arg1, arg2, offset);
1420
-}
1421
-
1422
-static inline void tcg_gen_st_i32(TCGv_i32 arg1, TCGv_ptr arg2,
1423
- tcg_target_long offset)
1424
-{
1425
- tcg_gen_ldst_op_i32(INDEX_op_st_i32, arg1, arg2, offset);
1426
-}
1427
-
1428
-static inline void tcg_gen_add_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1429
-{
1430
- tcg_gen_op3_i32(INDEX_op_add_i32, ret, arg1, arg2);
1431
-}
1432
-
1433
-static inline void tcg_gen_sub_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1434
-{
1435
- tcg_gen_op3_i32(INDEX_op_sub_i32, ret, arg1, arg2);
1436
-}
1437
-
1438
-static inline void tcg_gen_and_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1439
-{
1440
- tcg_gen_op3_i32(INDEX_op_and_i32, ret, arg1, arg2);
1441
-}
1442
-
1443
-static inline void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1444
-{
1445
- tcg_gen_op3_i32(INDEX_op_or_i32, ret, arg1, arg2);
1446
-}
1447
-
1448
-static inline void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1449
-{
1450
- tcg_gen_op3_i32(INDEX_op_xor_i32, ret, arg1, arg2);
1451
-}
1452
-
1453
-static inline void tcg_gen_shl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1454
-{
1455
- tcg_gen_op3_i32(INDEX_op_shl_i32, ret, arg1, arg2);
1456
-}
1457
-
1458
-static inline void tcg_gen_shr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1459
-{
1460
- tcg_gen_op3_i32(INDEX_op_shr_i32, ret, arg1, arg2);
1461
-}
1462
-
1463
-static inline void tcg_gen_sar_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1464
-{
1465
- tcg_gen_op3_i32(INDEX_op_sar_i32, ret, arg1, arg2);
1466
-}
1467
-
1468
-static inline void tcg_gen_mul_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1469
-{
1470
- tcg_gen_op3_i32(INDEX_op_mul_i32, ret, arg1, arg2);
1471
-}
1472
-
1473
-static inline void tcg_gen_neg_i32(TCGv_i32 ret, TCGv_i32 arg)
1474
-{
1475
- if (TCG_TARGET_HAS_neg_i32) {
1476
- tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg);
1477
- } else {
1478
- tcg_gen_subfi_i32(ret, 0, arg);
1479
- }
1480
-}
1481
-
1482
-static inline void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg)
1483
-{
1484
- if (TCG_TARGET_HAS_not_i32) {
1485
- tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg);
1486
- } else {
1487
- tcg_gen_xori_i32(ret, arg, -1);
1488
- }
1489
-}
1490
-
1491
-/* 64 bit ops */
1492
-
1493
-void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg);
1494
-void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1495
-void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2);
1496
-void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1497
-void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1498
-void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1499
-void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1500
-void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1501
-void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1502
-void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1503
-void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1504
-void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1505
-void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1506
-void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1507
-void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1508
-void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1509
-void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1510
-void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1511
-void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1512
-void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1513
-void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1514
-void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1515
-void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2);
1516
-void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2);
1517
-void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg);
1518
-void tcg_gen_ctpop_i64(TCGv_i64 a1, TCGv_i64 a2);
1519
-void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1520
-void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1521
-void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1522
-void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2);
1523
-void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
1524
- unsigned int ofs, unsigned int len);
1525
-void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
1526
- unsigned int ofs, unsigned int len);
1527
-void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
1528
- unsigned int ofs, unsigned int len);
1529
-void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
1530
- unsigned int ofs, unsigned int len);
1531
-void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
1532
- unsigned int ofs);
1533
-void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *);
1534
-void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *);
1535
-void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
1536
- TCGv_i64 arg1, TCGv_i64 arg2);
1537
-void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
1538
- TCGv_i64 arg1, int64_t arg2);
1539
-void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
1540
- TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2);
1541
-void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
1542
- TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh);
1543
-void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
1544
- TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh);
1545
-void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
1546
-void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
1547
-void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
1548
-void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg);
1549
-void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg);
1550
-void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg);
1551
-void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg);
1552
-void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg);
1553
-void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg);
1554
-void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg);
1555
-void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags);
1556
-void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags);
1557
-void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg);
1558
-void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg);
1559
-void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg);
1560
-void tcg_gen_smin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
1561
-void tcg_gen_smax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
1562
-void tcg_gen_umin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
1563
-void tcg_gen_umax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
1564
-void tcg_gen_abs_i64(TCGv_i64, TCGv_i64);
1565
-
1566
-/* Replicate a value of size @vece from @in to all the lanes in @out */
1567
-void tcg_gen_dup_i64(unsigned vece, TCGv_i64 out, TCGv_i64 in);
1568
-
1569
-#if TCG_TARGET_REG_BITS == 64
1570
-static inline void tcg_gen_discard_i64(TCGv_i64 arg)
1571
-{
1572
- tcg_gen_op1_i64(INDEX_op_discard, arg);
1573
-}
1574
-
1575
-static inline void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
1576
-{
1577
- if (ret != arg) {
1578
- tcg_gen_op2_i64(INDEX_op_mov_i64, ret, arg);
1579
- }
1580
-}
1581
-
1582
-static inline void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2,
1583
- tcg_target_long offset)
1584
-{
1585
- tcg_gen_ldst_op_i64(INDEX_op_ld8u_i64, ret, arg2, offset);
1586
-}
1587
-
1588
-static inline void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2,
1589
- tcg_target_long offset)
1590
-{
1591
- tcg_gen_ldst_op_i64(INDEX_op_ld8s_i64, ret, arg2, offset);
1592
-}
1593
-
1594
-static inline void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2,
1595
- tcg_target_long offset)
1596
-{
1597
- tcg_gen_ldst_op_i64(INDEX_op_ld16u_i64, ret, arg2, offset);
1598
-}
1599
-
1600
-static inline void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2,
1601
- tcg_target_long offset)
1602
-{
1603
- tcg_gen_ldst_op_i64(INDEX_op_ld16s_i64, ret, arg2, offset);
1604
-}
1605
-
1606
-static inline void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2,
1607
- tcg_target_long offset)
1608
-{
1609
- tcg_gen_ldst_op_i64(INDEX_op_ld32u_i64, ret, arg2, offset);
1610
-}
1611
-
1612
-static inline void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2,
1613
- tcg_target_long offset)
1614
-{
1615
- tcg_gen_ldst_op_i64(INDEX_op_ld32s_i64, ret, arg2, offset);
1616
-}
1617
-
1618
-static inline void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2,
1619
- tcg_target_long offset)
1620
-{
1621
- tcg_gen_ldst_op_i64(INDEX_op_ld_i64, ret, arg2, offset);
1622
-}
1623
-
1624
-static inline void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2,
1625
- tcg_target_long offset)
1626
-{
1627
- tcg_gen_ldst_op_i64(INDEX_op_st8_i64, arg1, arg2, offset);
1628
-}
1629
-
1630
-static inline void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2,
1631
- tcg_target_long offset)
1632
-{
1633
- tcg_gen_ldst_op_i64(INDEX_op_st16_i64, arg1, arg2, offset);
1634
-}
1635
-
1636
-static inline void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2,
1637
- tcg_target_long offset)
1638
-{
1639
- tcg_gen_ldst_op_i64(INDEX_op_st32_i64, arg1, arg2, offset);
1640
-}
1641
-
1642
-static inline void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2,
1643
- tcg_target_long offset)
1644
-{
1645
- tcg_gen_ldst_op_i64(INDEX_op_st_i64, arg1, arg2, offset);
1646
-}
1647
-
1648
-static inline void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1649
-{
1650
- tcg_gen_op3_i64(INDEX_op_add_i64, ret, arg1, arg2);
1651
-}
1652
-
1653
-static inline void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1654
-{
1655
- tcg_gen_op3_i64(INDEX_op_sub_i64, ret, arg1, arg2);
1656
-}
1657
-
1658
-static inline void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1659
-{
1660
- tcg_gen_op3_i64(INDEX_op_and_i64, ret, arg1, arg2);
1661
-}
1662
-
1663
-static inline void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1664
-{
1665
- tcg_gen_op3_i64(INDEX_op_or_i64, ret, arg1, arg2);
1666
-}
1667
-
1668
-static inline void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1669
-{
1670
- tcg_gen_op3_i64(INDEX_op_xor_i64, ret, arg1, arg2);
1671
-}
1672
-
1673
-static inline void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1674
-{
1675
- tcg_gen_op3_i64(INDEX_op_shl_i64, ret, arg1, arg2);
1676
-}
1677
-
1678
-static inline void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1679
-{
1680
- tcg_gen_op3_i64(INDEX_op_shr_i64, ret, arg1, arg2);
1681
-}
1682
-
1683
-static inline void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1684
-{
1685
- tcg_gen_op3_i64(INDEX_op_sar_i64, ret, arg1, arg2);
1686
-}
1687
-
1688
-static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1689
-{
1690
- tcg_gen_op3_i64(INDEX_op_mul_i64, ret, arg1, arg2);
1691
-}
1692
-#else /* TCG_TARGET_REG_BITS == 32 */
1693
-void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset);
1694
-void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset);
1695
-void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset);
1696
-
1697
-void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1698
-void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1699
-
1700
-void tcg_gen_discard_i64(TCGv_i64 arg);
1701
-void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg);
1702
-void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
1703
-void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
1704
-void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
1705
-void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
1706
-void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
1707
-void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
1708
-void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset);
1709
-void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset);
1710
-void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1711
-void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1712
-void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1713
-void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1714
-void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1715
-void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1716
-void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2);
1717
-#endif /* TCG_TARGET_REG_BITS */
1718
-
1719
-static inline void tcg_gen_neg_i64(TCGv_i64 ret, TCGv_i64 arg)
1720
-{
1721
- if (TCG_TARGET_HAS_neg_i64) {
1722
- tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg);
1723
- } else {
1724
- tcg_gen_subfi_i64(ret, 0, arg);
1725
- }
1726
-}
1727
-
1728
-/* Size changing operations. */
1729
-
1730
-void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg);
1731
-void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg);
1732
-void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high);
1733
-void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg);
1734
-void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg);
1735
-void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg);
1736
-void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg);
1737
-
1738
-void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src);
1739
-void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg);
1740
-void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi);
1741
-
1742
-static inline void tcg_gen_concat32_i64(TCGv_i64 ret, TCGv_i64 lo, TCGv_i64 hi)
1743
-{
1744
- tcg_gen_deposit_i64(ret, lo, hi, 32, 32);
1745
-}
1746
-
1747
-/* QEMU specific operations. */
1748
+#include "tcg/tcg-op-common.h"
1749
1750
#ifndef TARGET_LONG_BITS
1751
#error must include QEMU headers
1752
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1,
1753
# error "Unhandled number of operands to insn_start"
1754
#endif
1755
1756
-/**
1757
- * tcg_gen_exit_tb() - output exit_tb TCG operation
1758
- * @tb: The TranslationBlock from which we are exiting
1759
- * @idx: Direct jump slot index, or exit request
1760
- *
1761
- * See tcg/README for more info about this TCG operation.
1762
- * See also tcg.h and the block comment above TB_EXIT_MASK.
1763
- *
1764
- * For a normal exit from the TB, back to the main loop, @tb should
1765
- * be NULL and @idx should be 0. Otherwise, @tb should be valid and
1766
- * @idx should be one of the TB_EXIT_ values.
1767
- */
1768
-void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx);
1769
-
1770
-/**
1771
- * tcg_gen_goto_tb() - output goto_tb TCG operation
1772
- * @idx: Direct jump slot index (0 or 1)
1773
- *
1774
- * See tcg/README for more info about this TCG operation.
1775
- *
1776
- * NOTE: In softmmu emulation, direct jumps with goto_tb are only safe within
1777
- * the pages this TB resides in because we don't take care of direct jumps when
1778
- * address mapping changes, e.g. in tlb_flush(). In user mode, there's only a
1779
- * static address translation, so the destination address is always valid, TBs
1780
- * are always invalidated properly, and direct jumps are reset when mapping
1781
- * changes.
1782
- */
1783
-void tcg_gen_goto_tb(unsigned idx);
1784
-
1785
-/**
1786
- * tcg_gen_lookup_and_goto_ptr() - look up the current TB, jump to it if valid
1787
- * @addr: Guest address of the target TB
1788
- *
1789
- * If the TB is not valid, jump to the epilogue.
1790
- *
1791
- * This operation is optional. If the TCG backend does not implement goto_ptr,
1792
- * this op is equivalent to calling tcg_gen_exit_tb() with 0 as the argument.
1793
- */
1794
-void tcg_gen_lookup_and_goto_ptr(void);
1795
-
1796
-static inline void tcg_gen_plugin_cb_start(unsigned from, unsigned type,
1797
- unsigned wr)
1798
-{
1799
- tcg_gen_op3(INDEX_op_plugin_cb_start, from, type, wr);
1800
-}
1801
-
1802
-static inline void tcg_gen_plugin_cb_end(void)
1803
-{
1804
- tcg_emit_op(INDEX_op_plugin_cb_end, 0);
1805
-}
1806
-
1807
#if TARGET_LONG_BITS == 32
1808
typedef TCGv_i32 TCGv;
1809
#define tcg_temp_new() tcg_temp_new_i32()
1810
@@ -XXX,XX +XXX,XX @@ typedef TCGv_i64 TCGv;
1811
#error Unhandled TARGET_LONG_BITS value
1812
#endif
1813
1814
-void tcg_gen_qemu_ld_i32_chk(TCGv_i32, TCGTemp *, TCGArg, MemOp, TCGType);
1815
-void tcg_gen_qemu_st_i32_chk(TCGv_i32, TCGTemp *, TCGArg, MemOp, TCGType);
1816
-void tcg_gen_qemu_ld_i64_chk(TCGv_i64, TCGTemp *, TCGArg, MemOp, TCGType);
1817
-void tcg_gen_qemu_st_i64_chk(TCGv_i64, TCGTemp *, TCGArg, MemOp, TCGType);
1818
-void tcg_gen_qemu_ld_i128_chk(TCGv_i128, TCGTemp *, TCGArg, MemOp, TCGType);
1819
-void tcg_gen_qemu_st_i128_chk(TCGv_i128, TCGTemp *, TCGArg, MemOp, TCGType);
1820
-
1821
static inline void
1822
tcg_gen_qemu_ld_i32(TCGv_i32 v, TCGv a, TCGArg i, MemOp m)
1823
{
1824
@@ -XXX,XX +XXX,XX @@ tcg_gen_qemu_st_i128(TCGv_i128 v, TCGv a, TCGArg i, MemOp m)
1825
tcg_gen_qemu_st_i128_chk(v, tcgv_tl_temp(a), i, m, TCG_TYPE_TL);
1826
}
1827
1828
-void tcg_gen_atomic_cmpxchg_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32, TCGv_i32,
1829
- TCGArg, MemOp, TCGType);
1830
-void tcg_gen_atomic_cmpxchg_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64, TCGv_i64,
1831
- TCGArg, MemOp, TCGType);
1832
-void tcg_gen_atomic_cmpxchg_i128_chk(TCGv_i128, TCGTemp *, TCGv_i128,
1833
- TCGv_i128, TCGArg, MemOp, TCGType);
1834
-
1835
-void tcg_gen_nonatomic_cmpxchg_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32, TCGv_i32,
1836
- TCGArg, MemOp, TCGType);
1837
-void tcg_gen_nonatomic_cmpxchg_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64, TCGv_i64,
1838
- TCGArg, MemOp, TCGType);
1839
-void tcg_gen_nonatomic_cmpxchg_i128_chk(TCGv_i128, TCGTemp *, TCGv_i128,
1840
- TCGv_i128, TCGArg, MemOp, TCGType);
1841
-
1842
-void tcg_gen_atomic_xchg_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1843
- TCGArg, MemOp, TCGType);
1844
-void tcg_gen_atomic_xchg_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1845
- TCGArg, MemOp, TCGType);
1846
-
1847
-void tcg_gen_atomic_fetch_add_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1848
- TCGArg, MemOp, TCGType);
1849
-void tcg_gen_atomic_fetch_add_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1850
- TCGArg, MemOp, TCGType);
1851
-void tcg_gen_atomic_fetch_and_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1852
- TCGArg, MemOp, TCGType);
1853
-void tcg_gen_atomic_fetch_and_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1854
- TCGArg, MemOp, TCGType);
1855
-void tcg_gen_atomic_fetch_or_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1856
- TCGArg, MemOp, TCGType);
1857
-void tcg_gen_atomic_fetch_or_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1858
- TCGArg, MemOp, TCGType);
1859
-void tcg_gen_atomic_fetch_xor_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1860
- TCGArg, MemOp, TCGType);
1861
-void tcg_gen_atomic_fetch_xor_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1862
- TCGArg, MemOp, TCGType);
1863
-void tcg_gen_atomic_fetch_smin_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1864
- TCGArg, MemOp, TCGType);
1865
-void tcg_gen_atomic_fetch_smin_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1866
- TCGArg, MemOp, TCGType);
1867
-void tcg_gen_atomic_fetch_umin_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1868
- TCGArg, MemOp, TCGType);
1869
-void tcg_gen_atomic_fetch_umin_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1870
- TCGArg, MemOp, TCGType);
1871
-void tcg_gen_atomic_fetch_smax_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1872
- TCGArg, MemOp, TCGType);
1873
-void tcg_gen_atomic_fetch_smax_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1874
- TCGArg, MemOp, TCGType);
1875
-void tcg_gen_atomic_fetch_umax_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1876
- TCGArg, MemOp, TCGType);
1877
-void tcg_gen_atomic_fetch_umax_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1878
- TCGArg, MemOp, TCGType);
1879
-
1880
-void tcg_gen_atomic_add_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1881
- TCGArg, MemOp, TCGType);
1882
-void tcg_gen_atomic_add_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1883
- TCGArg, MemOp, TCGType);
1884
-void tcg_gen_atomic_and_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1885
- TCGArg, MemOp, TCGType);
1886
-void tcg_gen_atomic_and_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1887
- TCGArg, MemOp, TCGType);
1888
-void tcg_gen_atomic_or_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1889
- TCGArg, MemOp, TCGType);
1890
-void tcg_gen_atomic_or_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1891
- TCGArg, MemOp, TCGType);
1892
-void tcg_gen_atomic_xor_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1893
- TCGArg, MemOp, TCGType);
1894
-void tcg_gen_atomic_xor_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1895
- TCGArg, MemOp, TCGType);
1896
-void tcg_gen_atomic_smin_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1897
- TCGArg, MemOp, TCGType);
1898
-void tcg_gen_atomic_smin_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1899
- TCGArg, MemOp, TCGType);
1900
-void tcg_gen_atomic_umin_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1901
- TCGArg, MemOp, TCGType);
1902
-void tcg_gen_atomic_umin_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1903
- TCGArg, MemOp, TCGType);
1904
-void tcg_gen_atomic_smax_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1905
- TCGArg, MemOp, TCGType);
1906
-void tcg_gen_atomic_smax_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1907
- TCGArg, MemOp, TCGType);
1908
-void tcg_gen_atomic_umax_fetch_i32_chk(TCGv_i32, TCGTemp *, TCGv_i32,
1909
- TCGArg, MemOp, TCGType);
1910
-void tcg_gen_atomic_umax_fetch_i64_chk(TCGv_i64, TCGTemp *, TCGv_i64,
1911
- TCGArg, MemOp, TCGType);
1912
-
1913
#define DEF_ATOMIC2(N, S) \
1914
static inline void N##_##S(TCGv_##S r, TCGv a, TCGv_##S v, \
1915
TCGArg i, MemOp m) \
1916
@@ -XXX,XX +XXX,XX @@ DEF_ATOMIC2(tcg_gen_atomic_umax_fetch, i64)
1917
#undef DEF_ATOMIC2
1918
#undef DEF_ATOMIC3
1919
1920
-void tcg_gen_mov_vec(TCGv_vec, TCGv_vec);
1921
-void tcg_gen_dup_i32_vec(unsigned vece, TCGv_vec, TCGv_i32);
1922
-void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec, TCGv_i64);
1923
-void tcg_gen_dup_mem_vec(unsigned vece, TCGv_vec, TCGv_ptr, tcg_target_long);
1924
-void tcg_gen_dupi_vec(unsigned vece, TCGv_vec, uint64_t);
1925
-void tcg_gen_add_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1926
-void tcg_gen_sub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1927
-void tcg_gen_mul_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1928
-void tcg_gen_and_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1929
-void tcg_gen_or_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1930
-void tcg_gen_xor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1931
-void tcg_gen_andc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1932
-void tcg_gen_orc_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1933
-void tcg_gen_nand_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1934
-void tcg_gen_nor_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1935
-void tcg_gen_eqv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1936
-void tcg_gen_not_vec(unsigned vece, TCGv_vec r, TCGv_vec a);
1937
-void tcg_gen_neg_vec(unsigned vece, TCGv_vec r, TCGv_vec a);
1938
-void tcg_gen_abs_vec(unsigned vece, TCGv_vec r, TCGv_vec a);
1939
-void tcg_gen_ssadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1940
-void tcg_gen_usadd_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1941
-void tcg_gen_sssub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1942
-void tcg_gen_ussub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1943
-void tcg_gen_smin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1944
-void tcg_gen_umin_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1945
-void tcg_gen_smax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1946
-void tcg_gen_umax_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b);
1947
-
1948
-void tcg_gen_shli_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
1949
-void tcg_gen_shri_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
1950
-void tcg_gen_sari_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
1951
-void tcg_gen_rotli_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
1952
-void tcg_gen_rotri_vec(unsigned vece, TCGv_vec r, TCGv_vec a, int64_t i);
1953
-
1954
-void tcg_gen_shls_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
1955
-void tcg_gen_shrs_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
1956
-void tcg_gen_sars_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
1957
-void tcg_gen_rotls_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_i32 s);
1958
-
1959
-void tcg_gen_shlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
1960
-void tcg_gen_shrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
1961
-void tcg_gen_sarv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
1962
-void tcg_gen_rotlv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
1963
-void tcg_gen_rotrv_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec s);
1964
-
1965
-void tcg_gen_cmp_vec(TCGCond cond, unsigned vece, TCGv_vec r,
1966
- TCGv_vec a, TCGv_vec b);
1967
-
1968
-void tcg_gen_bitsel_vec(unsigned vece, TCGv_vec r, TCGv_vec a,
1969
- TCGv_vec b, TCGv_vec c);
1970
-void tcg_gen_cmpsel_vec(TCGCond cond, unsigned vece, TCGv_vec r,
1971
- TCGv_vec a, TCGv_vec b, TCGv_vec c, TCGv_vec d);
1972
-
1973
-void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset);
1974
-void tcg_gen_st_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset);
1975
-void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
1976
-
1977
#if TARGET_LONG_BITS == 64
1978
#define tcg_gen_movi_tl tcg_gen_movi_i64
1979
#define tcg_gen_mov_tl tcg_gen_mov_i64
1980
@@ -XXX,XX +XXX,XX @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
1981
: (VECE) == MO_32 ? 0x00000001ul * (uint32_t)(C) \
1982
: (qemu_build_not_reached_always(), 0)) \
1983
: (target_long)dup_const(VECE, C))
1984
-#endif
1985
-
1986
-#if UINTPTR_MAX == UINT32_MAX
1987
-# define PTR i32
1988
-# define NAT TCGv_i32
1989
-#else
1990
-# define PTR i64
1991
-# define NAT TCGv_i64
1992
-#endif
1993
-
1994
-static inline void tcg_gen_ld_ptr(TCGv_ptr r, TCGv_ptr a, intptr_t o)
1995
-{
1996
- glue(tcg_gen_ld_,PTR)((NAT)r, a, o);
1997
-}
1998
-
1999
-static inline void tcg_gen_st_ptr(TCGv_ptr r, TCGv_ptr a, intptr_t o)
2000
-{
2001
- glue(tcg_gen_st_, PTR)((NAT)r, a, o);
2002
-}
2003
-
2004
-static inline void tcg_gen_discard_ptr(TCGv_ptr a)
2005
-{
2006
- glue(tcg_gen_discard_,PTR)((NAT)a);
2007
-}
2008
-
2009
-static inline void tcg_gen_add_ptr(TCGv_ptr r, TCGv_ptr a, TCGv_ptr b)
2010
-{
2011
- glue(tcg_gen_add_,PTR)((NAT)r, (NAT)a, (NAT)b);
2012
-}
2013
-
2014
-static inline void tcg_gen_addi_ptr(TCGv_ptr r, TCGv_ptr a, intptr_t b)
2015
-{
2016
- glue(tcg_gen_addi_,PTR)((NAT)r, (NAT)a, b);
2017
-}
2018
-
2019
-static inline void tcg_gen_mov_ptr(TCGv_ptr d, TCGv_ptr s)
2020
-{
2021
- glue(tcg_gen_mov_,PTR)((NAT)d, (NAT)s);
2022
-}
2023
-
2024
-static inline void tcg_gen_movi_ptr(TCGv_ptr d, intptr_t s)
2025
-{
2026
- glue(tcg_gen_movi_,PTR)((NAT)d, s);
2027
-}
2028
-
2029
-static inline void tcg_gen_brcondi_ptr(TCGCond cond, TCGv_ptr a,
2030
- intptr_t b, TCGLabel *label)
2031
-{
2032
- glue(tcg_gen_brcondi_,PTR)(cond, (NAT)a, b, label);
2033
-}
2034
-
2035
-static inline void tcg_gen_ext_i32_ptr(TCGv_ptr r, TCGv_i32 a)
2036
-{
2037
-#if UINTPTR_MAX == UINT32_MAX
2038
- tcg_gen_mov_i32((NAT)r, a);
2039
-#else
2040
- tcg_gen_ext_i32_i64((NAT)r, a);
2041
-#endif
2042
-}
2043
-
2044
-static inline void tcg_gen_trunc_i64_ptr(TCGv_ptr r, TCGv_i64 a)
2045
-{
2046
-#if UINTPTR_MAX == UINT32_MAX
2047
- tcg_gen_extrl_i64_i32((NAT)r, a);
2048
-#else
2049
- tcg_gen_mov_i64((NAT)r, a);
2050
-#endif
2051
-}
2052
-
2053
-static inline void tcg_gen_extu_ptr_i64(TCGv_i64 r, TCGv_ptr a)
2054
-{
2055
-#if UINTPTR_MAX == UINT32_MAX
2056
- tcg_gen_extu_i32_i64(r, (NAT)a);
2057
-#else
2058
- tcg_gen_mov_i64(r, (NAT)a);
2059
-#endif
2060
-}
2061
-
2062
-static inline void tcg_gen_trunc_ptr_i32(TCGv_i32 r, TCGv_ptr a)
2063
-{
2064
-#if UINTPTR_MAX == UINT32_MAX
2065
- tcg_gen_mov_i32(r, (NAT)a);
2066
-#else
2067
- tcg_gen_extrl_i64_i32(r, (NAT)a);
2068
-#endif
2069
-}
2070
-
2071
-#undef PTR
2072
-#undef NAT
2073
2074
+#endif /* TARGET_LONG_BITS == 64 */
2075
#endif /* TCG_TCG_OP_H */
2076
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
2077
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
2078
--- a/tcg/optimize.c
12
--- a/tcg/optimize.c
2079
+++ b/tcg/optimize.c
13
+++ b/tcg/optimize.c
2080
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
2081
15
g_assert_not_reached();
2082
#include "qemu/osdep.h"
16
}
2083
#include "qemu/int128.h"
17
2084
-#include "tcg/tcg-op.h"
18
- if (0 && !type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
2085
+#include "tcg/tcg-op-common.h"
19
+ if (!type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
2086
#include "tcg-internal.h"
20
return true;
2087
21
}
2088
#define CASE_OP_32_64(x) \
22
2089
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
23
@@ -XXX,XX +XXX,XX @@ static bool fold_sextract(OptContext *ctx, TCGOp *op)
2090
index XXXXXXX..XXXXXXX 100644
24
s_mask = s_mask_old >> pos;
2091
--- a/tcg/tcg-op-gvec.c
25
s_mask |= -1ull << (len - 1);
2092
+++ b/tcg/tcg-op-gvec.c
26
2093
@@ -XXX,XX +XXX,XX @@
27
- if (0 && pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
2094
#include "qemu/osdep.h"
28
+ if (pos == 0 && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
2095
#include "tcg/tcg.h"
29
return true;
2096
#include "tcg/tcg-temp-internal.h"
30
}
2097
-#include "tcg/tcg-op.h"
2098
+#include "tcg/tcg-op-common.h"
2099
#include "tcg/tcg-op-gvec.h"
2100
#include "tcg/tcg-gvec-desc.h"
2101
2102
diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c
2103
index XXXXXXX..XXXXXXX 100644
2104
--- a/tcg/tcg-op-ldst.c
2105
+++ b/tcg/tcg-op-ldst.c
2106
@@ -XXX,XX +XXX,XX @@
2107
#include "exec/exec-all.h"
2108
#include "tcg/tcg.h"
2109
#include "tcg/tcg-temp-internal.h"
2110
-#include "tcg/tcg-op.h"
2111
+#include "tcg/tcg-op-common.h"
2112
#include "tcg/tcg-mo.h"
2113
#include "exec/plugin-gen.h"
2114
#include "tcg-internal.h"
2115
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
2116
index XXXXXXX..XXXXXXX 100644
2117
--- a/tcg/tcg-op-vec.c
2118
+++ b/tcg/tcg-op-vec.c
2119
@@ -XXX,XX +XXX,XX @@
2120
#include "qemu/osdep.h"
2121
#include "tcg/tcg.h"
2122
#include "tcg/tcg-temp-internal.h"
2123
-#include "tcg/tcg-op.h"
2124
+#include "tcg/tcg-op-common.h"
2125
#include "tcg/tcg-mo.h"
2126
#include "tcg-internal.h"
2127
2128
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
2129
index XXXXXXX..XXXXXXX 100644
2130
--- a/tcg/tcg-op.c
2131
+++ b/tcg/tcg-op.c
2132
@@ -XXX,XX +XXX,XX @@
2133
#include "exec/exec-all.h"
2134
#include "tcg/tcg.h"
2135
#include "tcg/tcg-temp-internal.h"
2136
-#include "tcg/tcg-op.h"
2137
+#include "tcg/tcg-op-common.h"
2138
#include "exec/plugin-gen.h"
2139
#include "tcg-internal.h"
2140
2141
diff --git a/tcg/tcg.c b/tcg/tcg.c
2142
index XXXXXXX..XXXXXXX 100644
2143
--- a/tcg/tcg.c
2144
+++ b/tcg/tcg.c
2145
@@ -XXX,XX +XXX,XX @@
2146
2147
#include "exec/exec-all.h"
2148
#include "exec/tlb-common.h"
2149
-#include "tcg/tcg-op.h"
2150
+#include "tcg/tcg-op-common.h"
2151
2152
#if UINTPTR_MAX == UINT32_MAX
2153
# define ELF_CLASS ELFCLASS32
2154
diff --git a/tcg/tci.c b/tcg/tci.c
2155
index XXXXXXX..XXXXXXX 100644
2156
--- a/tcg/tci.c
2157
+++ b/tcg/tci.c
2158
@@ -XXX,XX +XXX,XX @@
2159
*/
2160
2161
#include "qemu/osdep.h"
2162
-#include "exec/cpu_ldst.h"
2163
-#include "tcg/tcg-op.h"
2164
+#include "tcg/tcg.h"
2165
#include "tcg/tcg-ldst.h"
2166
#include <ffi.h>
2167
31
2168
--
32
--
2169
2.34.1
33
2.43.0
2170
2171
diff view generated by jsdifflib
1
Reduce the header to only bswap.h and cpu_ldst.h.
1
The big comment just above says functions should be sorted.
2
Move exec/translate-all.h to translator.c.
2
Add forward declarations as needed.
3
Reduce tcg.h and tcg-op.h to tcg-op-common.h.
4
Remove otherwise unused headers.
5
3
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
6
---
9
include/exec/translator.h | 6 +-----
7
tcg/optimize.c | 114 +++++++++++++++++++++++++------------------------
10
accel/tcg/translator.c | 8 +++-----
8
1 file changed, 59 insertions(+), 55 deletions(-)
11
2 files changed, 4 insertions(+), 10 deletions(-)
12
9
13
diff --git a/include/exec/translator.h b/include/exec/translator.h
10
diff --git a/tcg/optimize.c b/tcg/optimize.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/include/exec/translator.h
12
--- a/tcg/optimize.c
16
+++ b/include/exec/translator.h
13
+++ b/tcg/optimize.c
17
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static bool fold_xx_to_x(OptContext *ctx, TCGOp *op)
18
* member in your target-specific DisasContext.
15
* 3) those that produce information about the result value.
19
*/
16
*/
20
17
18
+static bool fold_or(OptContext *ctx, TCGOp *op);
19
+static bool fold_orc(OptContext *ctx, TCGOp *op);
20
+static bool fold_xor(OptContext *ctx, TCGOp *op);
21
+
22
static bool fold_add(OptContext *ctx, TCGOp *op)
23
{
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);
27
}
28
29
+static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
30
+{
31
+ /* If true and false values are the same, eliminate the cmp. */
32
+ if (args_are_copies(op->args[2], op->args[3])) {
33
+ return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[2]);
34
+ }
35
+
36
+ if (arg_is_const(op->args[2]) && arg_is_const(op->args[3])) {
37
+ uint64_t tv = arg_info(op->args[2])->val;
38
+ uint64_t fv = arg_info(op->args[3])->val;
39
+
40
+ if (tv == -1 && fv == 0) {
41
+ return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]);
42
+ }
43
+ if (tv == 0 && fv == -1) {
44
+ if (TCG_TARGET_HAS_not_vec) {
45
+ op->opc = INDEX_op_not_vec;
46
+ return fold_not(ctx, op);
47
+ } else {
48
+ op->opc = INDEX_op_xor_vec;
49
+ op->args[2] = arg_new_constant(ctx, -1);
50
+ return fold_xor(ctx, op);
51
+ }
52
+ }
53
+ }
54
+ if (arg_is_const(op->args[2])) {
55
+ uint64_t tv = arg_info(op->args[2])->val;
56
+ if (tv == -1) {
57
+ op->opc = INDEX_op_or_vec;
58
+ op->args[2] = op->args[3];
59
+ return fold_or(ctx, op);
60
+ }
61
+ if (tv == 0 && TCG_TARGET_HAS_andc_vec) {
62
+ op->opc = INDEX_op_andc_vec;
63
+ op->args[2] = op->args[1];
64
+ op->args[1] = op->args[3];
65
+ return fold_andc(ctx, op);
66
+ }
67
+ }
68
+ if (arg_is_const(op->args[3])) {
69
+ uint64_t fv = arg_info(op->args[3])->val;
70
+ if (fv == 0) {
71
+ op->opc = INDEX_op_and_vec;
72
+ return fold_and(ctx, op);
73
+ }
74
+ if (fv == -1 && TCG_TARGET_HAS_orc_vec) {
75
+ op->opc = INDEX_op_orc_vec;
76
+ op->args[2] = op->args[1];
77
+ op->args[1] = op->args[3];
78
+ return fold_orc(ctx, op);
79
+ }
80
+ }
81
+ return finish_folding(ctx, op);
82
+}
83
+
84
static bool fold_brcond(OptContext *ctx, TCGOp *op)
85
{
86
int i = do_constant_folding_cond1(ctx, op, NO_DEST, &op->args[0],
87
@@ -XXX,XX +XXX,XX @@ static bool fold_xor(OptContext *ctx, TCGOp *op)
88
return fold_masks_zs(ctx, op, z_mask, s_mask);
89
}
90
91
-static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op)
92
-{
93
- /* If true and false values are the same, eliminate the cmp. */
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
- }
21
-
97
-
22
#include "qemu/bswap.h"
98
- if (arg_is_const(op->args[2]) && arg_is_const(op->args[3])) {
23
-#include "exec/exec-all.h"
99
- uint64_t tv = arg_info(op->args[2])->val;
24
-#include "exec/cpu_ldst.h"
100
- uint64_t fv = arg_info(op->args[3])->val;
25
-#include "exec/translate-all.h"
26
-#include "tcg/tcg.h"
27
+#include "exec/cpu_ldst.h"    /* for abi_ptr */
28
29
/**
30
* gen_intermediate_code
31
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/accel/tcg/translator.c
34
+++ b/accel/tcg/translator.c
35
@@ -XXX,XX +XXX,XX @@
36
*/
37
38
#include "qemu/osdep.h"
39
+#include "qemu/log.h"
40
#include "qemu/error-report.h"
41
-#include "tcg/tcg.h"
42
-#include "tcg/tcg-op.h"
43
#include "exec/exec-all.h"
44
-#include "exec/log.h"
45
#include "exec/translator.h"
46
+#include "exec/translate-all.h"
47
#include "exec/plugin-gen.h"
48
-#include "exec/replay-core.h"
49
-
101
-
50
+#include "tcg/tcg-op-common.h"
102
- if (tv == -1 && fv == 0) {
51
103
- return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]);
52
static void gen_io_start(void)
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)
53
{
148
{
54
--
149
--
55
2.34.1
150
2.43.0
56
57
diff view generated by jsdifflib
1
The only usage of gen_tb_start and gen_tb_end are here.
1
The big comment just above says functions should be sorted.
2
Move the static icount_start_insn variable into a local
3
within translator_loop. Simplify the two subroutines
4
by passing in the existing local cflags variable.
5
2
6
Leave only the declaration of gen_io_start in gen-icount.h.
3
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
5
---
11
include/exec/gen-icount.h | 79 +------------------------------------
6
tcg/optimize.c | 60 +++++++++++++++++++++++++-------------------------
12
accel/tcg/translator.c | 83 ++++++++++++++++++++++++++++++++++++++-
7
1 file changed, 30 insertions(+), 30 deletions(-)
13
2 files changed, 82 insertions(+), 80 deletions(-)
14
8
15
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
16
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
17
--- a/include/exec/gen-icount.h
11
--- a/tcg/optimize.c
18
+++ b/include/exec/gen-icount.h
12
+++ b/tcg/optimize.c
19
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@ static bool fold_call(OptContext *ctx, TCGOp *op)
20
#ifndef GEN_ICOUNT_H
14
return true;
21
#define GEN_ICOUNT_H
15
}
22
16
23
-#include "exec/exec-all.h"
17
+static bool fold_cmp_vec(OptContext *ctx, TCGOp *op)
24
-
18
+{
25
-/* Helpers for instruction counting code generation. */
19
+ /* Canonicalize the comparison to put immediate second. */
26
-
20
+ if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
27
-static TCGOp *icount_start_insn;
21
+ op->args[3] = tcg_swap_cond(op->args[3]);
28
-
22
+ }
29
-static inline void gen_io_start(void)
23
+ return finish_folding(ctx, op);
24
+}
25
+
26
+static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
27
+{
28
+ /* If true and false values are the same, eliminate the cmp. */
29
+ if (args_are_copies(op->args[3], op->args[4])) {
30
+ return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[3]);
31
+ }
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
+ }
37
+ /*
38
+ * Canonicalize the "false" input reg to match the destination,
39
+ * so that the tcg backend can implement "move if true".
40
+ */
41
+ if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
42
+ op->args[5] = tcg_invert_cond(op->args[5]);
43
+ }
44
+ return finish_folding(ctx, op);
45
+}
46
+
47
static bool fold_count_zeros(OptContext *ctx, TCGOp *op)
48
{
49
uint64_t z_mask, s_mask;
50
@@ -XXX,XX +XXX,XX @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
51
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
52
}
53
54
-static bool fold_cmp_vec(OptContext *ctx, TCGOp *op)
30
-{
55
-{
31
- tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
56
- /* Canonicalize the comparison to put immediate second. */
32
- offsetof(ArchCPU, parent_obj.can_do_io) -
57
- if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
33
- offsetof(ArchCPU, env));
58
- op->args[3] = tcg_swap_cond(op->args[3]);
59
- }
60
- return finish_folding(ctx, op);
34
-}
61
-}
35
-
62
-
36
-static inline void gen_tb_start(const TranslationBlock *tb)
63
-static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
37
-{
64
-{
38
- TCGv_i32 count = tcg_temp_new_i32();
65
- /* If true and false values are the same, eliminate the cmp. */
39
-
66
- if (args_are_copies(op->args[3], op->args[4])) {
40
- tcg_gen_ld_i32(count, cpu_env,
67
- return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[3]);
41
- offsetof(ArchCPU, neg.icount_decr.u32) -
42
- offsetof(ArchCPU, env));
43
-
44
- if (tb_cflags(tb) & CF_USE_ICOUNT) {
45
- /*
46
- * We emit a sub with a dummy immediate argument. Keep the insn index
47
- * of the sub so that we later (when we know the actual insn count)
48
- * can update the argument with the actual insn count.
49
- */
50
- tcg_gen_sub_i32(count, count, tcg_constant_i32(0));
51
- icount_start_insn = tcg_last_op();
52
- }
68
- }
53
-
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
- }
54
- /*
74
- /*
55
- * Emit the check against icount_decr.u32 to see if we should exit
75
- * Canonicalize the "false" input reg to match the destination,
56
- * unless we suppress the check with CF_NOIRQ. If we are using
76
- * so that the tcg backend can implement "move if true".
57
- * icount and have suppressed interruption the higher level code
58
- * should have ensured we don't run more instructions than the
59
- * budget.
60
- */
77
- */
61
- if (tb_cflags(tb) & CF_NOIRQ) {
78
- if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
62
- tcg_ctx->exitreq_label = NULL;
79
- op->args[5] = tcg_invert_cond(op->args[5]);
63
- } else {
64
- tcg_ctx->exitreq_label = gen_new_label();
65
- tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label);
66
- }
80
- }
67
-
81
- return finish_folding(ctx, op);
68
- if (tb_cflags(tb) & CF_USE_ICOUNT) {
69
- tcg_gen_st16_i32(count, cpu_env,
70
- offsetof(ArchCPU, neg.icount_decr.u16.low) -
71
- offsetof(ArchCPU, env));
72
- /*
73
- * cpu->can_do_io is cleared automatically here at the beginning of
74
- * each translation block. The cost is minimal and only paid for
75
- * -icount, plus it would be very easy to forget doing it in the
76
- * translator. Doing it here means we don't need a gen_io_end() to
77
- * go with gen_io_start().
78
- */
79
- tcg_gen_st_i32(tcg_constant_i32(0), cpu_env,
80
- offsetof(ArchCPU, parent_obj.can_do_io) -
81
- offsetof(ArchCPU, env));
82
- }
83
-}
82
-}
84
-
83
-
85
-static inline void gen_tb_end(const TranslationBlock *tb, int num_insns)
84
static bool fold_sextract(OptContext *ctx, TCGOp *op)
86
-{
87
- if (tb_cflags(tb) & CF_USE_ICOUNT) {
88
- /*
89
- * Update the num_insn immediate parameter now that we know
90
- * the actual insn count.
91
- */
92
- tcg_set_insn_param(icount_start_insn, 2,
93
- tcgv_i32_arg(tcg_constant_i32(num_insns)));
94
- }
95
-
96
- if (tcg_ctx->exitreq_label) {
97
- gen_set_label(tcg_ctx->exitreq_label);
98
- tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED);
99
- }
100
-}
101
+void gen_io_start(void);
102
103
#endif
104
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/accel/tcg/translator.c
107
+++ b/accel/tcg/translator.c
108
@@ -XXX,XX +XXX,XX @@
109
#include "exec/plugin-gen.h"
110
#include "exec/replay-core.h"
111
112
+
113
+void gen_io_start(void)
114
+{
115
+ tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
116
+ offsetof(ArchCPU, parent_obj.can_do_io) -
117
+ offsetof(ArchCPU, env));
118
+}
119
+
120
+static TCGOp *gen_tb_start(uint32_t cflags)
121
+{
122
+ TCGv_i32 count = tcg_temp_new_i32();
123
+ TCGOp *icount_start_insn = NULL;
124
+
125
+ tcg_gen_ld_i32(count, cpu_env,
126
+ offsetof(ArchCPU, neg.icount_decr.u32) -
127
+ offsetof(ArchCPU, env));
128
+
129
+ if (cflags & CF_USE_ICOUNT) {
130
+ /*
131
+ * We emit a sub with a dummy immediate argument. Keep the insn index
132
+ * of the sub so that we later (when we know the actual insn count)
133
+ * can update the argument with the actual insn count.
134
+ */
135
+ tcg_gen_sub_i32(count, count, tcg_constant_i32(0));
136
+ icount_start_insn = tcg_last_op();
137
+ }
138
+
139
+ /*
140
+ * Emit the check against icount_decr.u32 to see if we should exit
141
+ * unless we suppress the check with CF_NOIRQ. If we are using
142
+ * icount and have suppressed interruption the higher level code
143
+ * should have ensured we don't run more instructions than the
144
+ * budget.
145
+ */
146
+ if (cflags & CF_NOIRQ) {
147
+ tcg_ctx->exitreq_label = NULL;
148
+ } else {
149
+ tcg_ctx->exitreq_label = gen_new_label();
150
+ tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label);
151
+ }
152
+
153
+ if (cflags & CF_USE_ICOUNT) {
154
+ tcg_gen_st16_i32(count, cpu_env,
155
+ offsetof(ArchCPU, neg.icount_decr.u16.low) -
156
+ offsetof(ArchCPU, env));
157
+ /*
158
+ * cpu->can_do_io is cleared automatically here at the beginning of
159
+ * each translation block. The cost is minimal and only paid for
160
+ * -icount, plus it would be very easy to forget doing it in the
161
+ * translator. Doing it here means we don't need a gen_io_end() to
162
+ * go with gen_io_start().
163
+ */
164
+ tcg_gen_st_i32(tcg_constant_i32(0), cpu_env,
165
+ offsetof(ArchCPU, parent_obj.can_do_io) -
166
+ offsetof(ArchCPU, env));
167
+ }
168
+
169
+ return icount_start_insn;
170
+}
171
+
172
+static void gen_tb_end(const TranslationBlock *tb, uint32_t cflags,
173
+ TCGOp *icount_start_insn, int num_insns)
174
+{
175
+ if (cflags & CF_USE_ICOUNT) {
176
+ /*
177
+ * Update the num_insn immediate parameter now that we know
178
+ * the actual insn count.
179
+ */
180
+ tcg_set_insn_param(icount_start_insn, 2,
181
+ tcgv_i32_arg(tcg_constant_i32(num_insns)));
182
+ }
183
+
184
+ if (tcg_ctx->exitreq_label) {
185
+ gen_set_label(tcg_ctx->exitreq_label);
186
+ tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED);
187
+ }
188
+}
189
+
190
bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest)
191
{
85
{
192
/* Suppress goto_tb if requested. */
86
uint64_t z_mask, s_mask, s_mask_old;
193
@@ -XXX,XX +XXX,XX @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
194
const TranslatorOps *ops, DisasContextBase *db)
195
{
196
uint32_t cflags = tb_cflags(tb);
197
+ TCGOp *icount_start_insn;
198
bool plugin_enabled;
199
200
/* Initialize DisasContext */
201
@@ -XXX,XX +XXX,XX @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
202
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
203
204
/* Start translating. */
205
- gen_tb_start(db->tb);
206
+ icount_start_insn = gen_tb_start(cflags);
207
ops->tb_start(db, cpu);
208
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
209
210
@@ -XXX,XX +XXX,XX @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
211
212
/* Emit code to exit the TB, as indicated by db->is_jmp. */
213
ops->tb_stop(db, cpu);
214
- gen_tb_end(db->tb, db->num_insns);
215
+ gen_tb_end(tb, cflags, icount_start_insn, db->num_insns);
216
217
if (plugin_enabled) {
218
plugin_gen_tb_end(cpu);
219
--
87
--
220
2.34.1
88
2.43.0
221
222
diff view generated by jsdifflib
1
This will be required outside of tcg-internal.h soon.
1
We currently have a flag, float_muladd_halve_result, to scale
2
the result by 2**-1. Extend this to handle arbitrary scaling.
2
3
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
---
6
include/tcg/helper-info.h | 59 +++++++++++++++++++++++++++++++++++++++
7
include/fpu/softfloat.h | 6 ++++
7
tcg/tcg-internal.h | 47 +------------------------------
8
fpu/softfloat.c | 58 ++++++++++++++++++++++-----------------
8
2 files changed, 60 insertions(+), 46 deletions(-)
9
fpu/softfloat-parts.c.inc | 7 +++--
9
create mode 100644 include/tcg/helper-info.h
10
3 files changed, 44 insertions(+), 27 deletions(-)
10
11
11
diff --git a/include/tcg/helper-info.h b/include/tcg/helper-info.h
12
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
12
new file mode 100644
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX
14
--- a/include/fpu/softfloat.h
14
--- /dev/null
15
+++ b/include/fpu/softfloat.h
15
+++ b/include/tcg/helper-info.h
16
@@ -XXX,XX +XXX,XX @@ float16 float16_add(float16, float16, float_status *status);
16
@@ -XXX,XX +XXX,XX @@
17
float16 float16_sub(float16, float16, float_status *status);
17
+/*
18
float16 float16_mul(float16, float16, float_status *status);
18
+ * TCG Helper Infomation Structure
19
float16 float16_muladd(float16, float16, float16, int, float_status *status);
19
+ *
20
+float16 float16_muladd_scalbn(float16, float16, float16,
20
+ * Copyright (c) 2023 Linaro Ltd
21
+ int, int, float_status *status);
21
+ *
22
float16 float16_div(float16, float16, float_status *status);
22
+ * SPDX-License-Identifier: GPL-2.0-or-later
23
float16 float16_scalbn(float16, int, float_status *status);
23
+ */
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
+}
24
+
100
+
25
+#ifndef TCG_HELPER_INFO_H
101
+float32 QEMU_SOFTFLOAT_ATTR
26
+#define TCG_HELPER_INFO_H
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++) {
27
+
182
+
28
+#ifdef CONFIG_TCG_INTERPRETER
183
float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status);
29
+#include <ffi.h>
184
- rp = *parts_muladd(&tp, &xnp, &rp, 0, status);
30
+#endif
185
+ rp = *parts_muladd_scalbn(&tp, &xnp, &rp, 0, 0, status);
31
+
186
xnp = *parts_mul(&xnp, &xp, status);
32
+/*
187
}
33
+ * Describe the calling convention of a given argument type.
188
34
+ */
189
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
35
+typedef enum {
36
+ TCG_CALL_RET_NORMAL, /* by registers */
37
+ TCG_CALL_RET_BY_REF, /* for i128, by reference */
38
+ TCG_CALL_RET_BY_VEC, /* for i128, by vector register */
39
+} TCGCallReturnKind;
40
+
41
+typedef enum {
42
+ TCG_CALL_ARG_NORMAL, /* by registers (continuing onto stack) */
43
+ TCG_CALL_ARG_EVEN, /* like normal, but skipping odd slots */
44
+ TCG_CALL_ARG_EXTEND, /* for i32, as a sign/zero-extended i64 */
45
+ TCG_CALL_ARG_EXTEND_U, /* ... as a zero-extended i64 */
46
+ TCG_CALL_ARG_EXTEND_S, /* ... as a sign-extended i64 */
47
+ TCG_CALL_ARG_BY_REF, /* for i128, by reference, first */
48
+ TCG_CALL_ARG_BY_REF_N, /* ... by reference, subsequent */
49
+} TCGCallArgumentKind;
50
+
51
+typedef struct TCGCallArgumentLoc {
52
+ TCGCallArgumentKind kind : 8;
53
+ unsigned arg_slot : 8;
54
+ unsigned ref_slot : 8;
55
+ unsigned arg_idx : 4;
56
+ unsigned tmp_subindex : 2;
57
+} TCGCallArgumentLoc;
58
+
59
+typedef struct TCGHelperInfo {
60
+ void *func;
61
+ const char *name;
62
+#ifdef CONFIG_TCG_INTERPRETER
63
+ ffi_cif *cif;
64
+#endif
65
+ unsigned typemask : 32;
66
+ unsigned flags : 8;
67
+ unsigned nr_in : 8;
68
+ unsigned nr_out : 8;
69
+ TCGCallReturnKind out_kind : 8;
70
+
71
+ /* Maximum physical arguments are constrained by TCG_TYPE_I128. */
72
+ TCGCallArgumentLoc in[MAX_CALL_IARGS * (128 / TCG_TARGET_REG_BITS)];
73
+} TCGHelperInfo;
74
+
75
+#endif /* TCG_HELPER_INFO_H */
76
diff --git a/tcg/tcg-internal.h b/tcg/tcg-internal.h
77
index XXXXXXX..XXXXXXX 100644
190
index XXXXXXX..XXXXXXX 100644
78
--- a/tcg/tcg-internal.h
191
--- a/fpu/softfloat-parts.c.inc
79
+++ b/tcg/tcg-internal.h
192
+++ b/fpu/softfloat-parts.c.inc
80
@@ -XXX,XX +XXX,XX @@
193
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b,
81
#ifndef TCG_INTERNAL_H
194
* Requires A and C extracted into a double-sized structure to provide the
82
#define TCG_INTERNAL_H
195
* extra space for the widening multiply.
83
196
*/
84
-#ifdef CONFIG_TCG_INTERPRETER
197
-static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
85
-#include <ffi.h>
198
- FloatPartsN *c, int flags, float_status *s)
86
-#endif
199
+static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
87
+#include "tcg/helper-info.h"
200
+ FloatPartsN *c, int scale,
88
201
+ int flags, float_status *s)
89
#define TCG_HIGHWATER 1024
202
{
90
203
int ab_mask, abc_mask;
91
-/*
204
FloatPartsW p_widen, c_widen;
92
- * Describe the calling convention of a given argument type.
205
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
93
- */
206
a->exp = p_widen.exp;
94
-typedef enum {
207
95
- TCG_CALL_RET_NORMAL, /* by registers */
208
return_normal:
96
- TCG_CALL_RET_BY_REF, /* for i128, by reference */
209
+ /* TODO: Replace all use of float_muladd_halve_result with scale. */
97
- TCG_CALL_RET_BY_VEC, /* for i128, by vector register */
210
if (flags & float_muladd_halve_result) {
98
-} TCGCallReturnKind;
211
a->exp -= 1;
99
-
212
}
100
-typedef enum {
213
+ a->exp += scale;
101
- TCG_CALL_ARG_NORMAL, /* by registers (continuing onto stack) */
214
finish_sign:
102
- TCG_CALL_ARG_EVEN, /* like normal, but skipping odd slots */
215
if (flags & float_muladd_negate_result) {
103
- TCG_CALL_ARG_EXTEND, /* for i32, as a sign/zero-extended i64 */
216
a->sign ^= 1;
104
- TCG_CALL_ARG_EXTEND_U, /* ... as a zero-extended i64 */
105
- TCG_CALL_ARG_EXTEND_S, /* ... as a sign-extended i64 */
106
- TCG_CALL_ARG_BY_REF, /* for i128, by reference, first */
107
- TCG_CALL_ARG_BY_REF_N, /* ... by reference, subsequent */
108
-} TCGCallArgumentKind;
109
-
110
-typedef struct TCGCallArgumentLoc {
111
- TCGCallArgumentKind kind : 8;
112
- unsigned arg_slot : 8;
113
- unsigned ref_slot : 8;
114
- unsigned arg_idx : 4;
115
- unsigned tmp_subindex : 2;
116
-} TCGCallArgumentLoc;
117
-
118
-typedef struct TCGHelperInfo {
119
- void *func;
120
- const char *name;
121
-#ifdef CONFIG_TCG_INTERPRETER
122
- ffi_cif *cif;
123
-#endif
124
- unsigned typemask : 32;
125
- unsigned flags : 8;
126
- unsigned nr_in : 8;
127
- unsigned nr_out : 8;
128
- TCGCallReturnKind out_kind : 8;
129
-
130
- /* Maximum physical arguments are constrained by TCG_TYPE_I128. */
131
- TCGCallArgumentLoc in[MAX_CALL_IARGS * (128 / TCG_TARGET_REG_BITS)];
132
-} TCGHelperInfo;
133
-
134
extern TCGContext tcg_init_ctx;
135
extern TCGContext **tcg_ctxs;
136
extern unsigned int tcg_cur_ctxs;
137
--
217
--
138
2.34.1
218
2.43.0
139
219
140
220
diff view generated by jsdifflib
1
Since the change to CPUArchState, we have a common typedef
1
Use the scalbn interface instead of float_muladd_halve_result.
2
that can always be used.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@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
include/exec/helper-head.h | 6 +++---
6
target/arm/tcg/helper-a64.c | 6 +++---
8
1 file changed, 3 insertions(+), 3 deletions(-)
7
1 file changed, 3 insertions(+), 3 deletions(-)
9
8
10
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
9
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
11
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
12
--- a/include/exec/helper-head.h
11
--- a/target/arm/tcg/helper-a64.c
13
+++ b/include/exec/helper-head.h
12
+++ b/target/arm/tcg/helper-a64.c
14
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrtsf_f16)(uint32_t a, uint32_t b, float_status *fpst)
15
#define dh_alias_f64 i64
14
(float16_is_infinity(b) && float16_is_zero(a))) {
16
#define dh_alias_ptr ptr
15
return float16_one_point_five;
17
#define dh_alias_cptr ptr
16
}
18
+#define dh_alias_env ptr
17
- return float16_muladd(a, b, float16_three, float_muladd_halve_result, fpst);
19
#define dh_alias_void void
18
+ return float16_muladd_scalbn(a, b, float16_three, -1, 0, fpst);
20
#define dh_alias_noreturn noreturn
19
}
21
#define dh_alias(t) glue(dh_alias_, t)
20
22
@@ -XXX,XX +XXX,XX @@
21
float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, float_status *fpst)
23
#define dh_ctype_f64 float64
22
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, float_status *fpst)
24
#define dh_ctype_ptr void *
23
(float32_is_infinity(b) && float32_is_zero(a))) {
25
#define dh_ctype_cptr const void *
24
return float32_one_point_five;
26
+#define dh_ctype_env CPUArchState *
25
}
27
#define dh_ctype_void void
26
- return float32_muladd(a, b, float32_three, float_muladd_halve_result, fpst);
28
#define dh_ctype_noreturn G_NORETURN void
27
+ return float32_muladd_scalbn(a, b, float32_three, -1, 0, fpst);
29
#define dh_ctype(t) dh_ctype_##t
28
}
30
@@ -XXX,XX +XXX,XX @@
29
31
# endif
30
float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, float_status *fpst)
32
# endif
31
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrtsf_f64)(float64 a, float64 b, float_status *fpst)
33
# define dh_ctype_tl target_ulong
32
(float64_is_infinity(b) && float64_is_zero(a))) {
34
-# define dh_alias_env ptr
33
return float64_one_point_five;
35
-# define dh_ctype_env CPUArchState *
34
}
36
-# define dh_typecode_env dh_typecode_ptr
35
- return float64_muladd(a, b, float64_three, float_muladd_halve_result, fpst);
37
#endif
36
+ return float64_muladd_scalbn(a, b, float64_three, -1, 0, fpst);
38
37
}
39
/* We can't use glue() here because it falls foul of C preprocessor
38
40
@@ -XXX,XX +XXX,XX @@
39
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
41
#define dh_typecode_f32 dh_typecode_i32
42
#define dh_typecode_f64 dh_typecode_i64
43
#define dh_typecode_cptr dh_typecode_ptr
44
+#define dh_typecode_env dh_typecode_ptr
45
#define dh_typecode(t) dh_typecode_##t
46
47
#define dh_callflag_i32 0
48
--
40
--
49
2.34.1
41
2.43.0
50
42
51
43
diff view generated by jsdifflib
1
This had been included via tcg-op-common.h via tcg-op.h,
1
Use the scalbn interface instead of float_muladd_halve_result.
2
but that is going away. In idef-parser.y, shuffle some
3
tcg related includes into a more logical order.
4
2
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
5
---
8
target/hexagon/genptr.c | 1 +
6
target/sparc/helper.h | 4 +-
9
target/hexagon/translate.c | 1 +
7
target/sparc/fop_helper.c | 8 ++--
10
target/hexagon/idef-parser/idef-parser.y | 3 ++-
8
target/sparc/translate.c | 80 +++++++++++++++++++++++----------------
11
3 files changed, 4 insertions(+), 1 deletion(-)
9
3 files changed, 54 insertions(+), 38 deletions(-)
12
10
13
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
11
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/hexagon/genptr.c
13
--- a/target/sparc/helper.h
16
+++ b/target/hexagon/genptr.c
14
+++ b/target/sparc/helper.h
17
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
18
#include "internal.h"
16
DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_WG, f64, env, f64, f64)
19
#include "tcg/tcg-op.h"
17
DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
20
#include "tcg/tcg-op-gvec.h"
18
DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_WG, f64, env, f64, f64)
21
+#include "exec/helper-gen.h"
19
-DEF_HELPER_FLAGS_5(fmaddd, TCG_CALL_NO_WG, f64, env, f64, f64, f64, i32)
22
#include "insn.h"
20
+DEF_HELPER_FLAGS_6(fmaddd, TCG_CALL_NO_WG, f64, env, f64, f64, f64, s32, i32)
23
#include "opcodes.h"
21
DEF_HELPER_FLAGS_3(fnaddd, TCG_CALL_NO_WG, f64, env, f64, f64)
24
#include "translate.h"
22
DEF_HELPER_FLAGS_3(fnmuld, TCG_CALL_NO_WG, f64, env, f64, f64)
25
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
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
26
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
27
--- a/target/hexagon/translate.c
35
--- a/target/sparc/fop_helper.c
28
+++ b/target/hexagon/translate.c
36
+++ b/target/sparc/fop_helper.c
29
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
30
#include "cpu.h"
38
}
31
#include "tcg/tcg-op.h"
39
32
#include "tcg/tcg-op-gvec.h"
40
float32 helper_fmadds(CPUSPARCState *env, float32 s1,
33
+#include "exec/helper-gen.h"
41
- float32 s2, float32 s3, uint32_t op)
34
#include "exec/cpu_ldst.h"
42
+ float32 s2, float32 s3, int32_t sc, uint32_t op)
35
#include "exec/log.h"
43
{
36
#include "internal.h"
44
- float32 ret = float32_muladd(s1, s2, s3, op, &env->fp_status);
37
diff --git a/target/hexagon/idef-parser/idef-parser.y b/target/hexagon/idef-parser/idef-parser.y
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
38
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
39
--- a/target/hexagon/idef-parser/idef-parser.y
61
--- a/target/sparc/translate.c
40
+++ b/target/hexagon/idef-parser/idef-parser.y
62
+++ b/target/sparc/translate.c
41
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
63
@@ -XXX,XX +XXX,XX @@ static void gen_op_fabsq(TCGv_i128 dst, TCGv_i128 src)
42
fputs("#include \"qemu/log.h\"\n", output_file);
64
43
fputs("#include \"cpu.h\"\n", output_file);
65
static void gen_op_fmadds(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2, TCGv_i32 s3)
44
fputs("#include \"internal.h\"\n", output_file);
66
{
45
+ fputs("#include \"tcg/tcg.h\"\n", output_file);
67
- gen_helper_fmadds(d, tcg_env, s1, s2, s3, tcg_constant_i32(0));
46
fputs("#include \"tcg/tcg-op.h\"\n", output_file);
68
+ TCGv_i32 z = tcg_constant_i32(0);
47
+ fputs("#include \"exec/helper-gen.h\"\n", output_file);
69
+ gen_helper_fmadds(d, tcg_env, s1, s2, s3, z, z);
48
fputs("#include \"insn.h\"\n", output_file);
70
}
49
fputs("#include \"opcodes.h\"\n", output_file);
71
50
fputs("#include \"translate.h\"\n", output_file);
72
static void gen_op_fmaddd(TCGv_i64 d, TCGv_i64 s1, TCGv_i64 s2, TCGv_i64 s3)
51
fputs("#define QEMU_GENERATE\n", output_file);
73
{
52
fputs("#include \"genptr.h\"\n", output_file);
74
- gen_helper_fmaddd(d, tcg_env, s1, s2, s3, tcg_constant_i32(0));
53
- fputs("#include \"tcg/tcg.h\"\n", output_file);
75
+ TCGv_i32 z = tcg_constant_i32(0);
54
fputs("#include \"macros.h\"\n", output_file);
76
+ gen_helper_fmaddd(d, tcg_env, s1, s2, s3, z, z);
55
fprintf(output_file, "#include \"%s\"\n", argv[ARG_INDEX_EMITTER_H]);
77
}
56
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)
57
--
205
--
58
2.34.1
206
2.43.0
59
207
60
208
diff view generated by jsdifflib
1
This had been included via tcg-op-common.h via tcg-op.h,
1
All uses have been convered to float*_muladd_scalbn.
2
but that is going away.
3
4
It is needed for inlines within translator.h, so we might as well
5
do it there and not individually in each translator c file.
6
2
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
5
---
10
target/arm/tcg/translate.h | 1 +
6
include/fpu/softfloat.h | 3 ---
11
target/arm/tcg/translate-a64.c | 2 --
7
fpu/softfloat.c | 6 ------
12
target/arm/tcg/translate-sme.c | 1 -
8
fpu/softfloat-parts.c.inc | 4 ----
13
target/arm/tcg/translate-sve.c | 2 --
9
3 files changed, 13 deletions(-)
14
target/arm/tcg/translate.c | 2 --
15
5 files changed, 1 insertion(+), 7 deletions(-)
16
10
17
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
11
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/tcg/translate.h
13
--- a/include/fpu/softfloat.h
20
+++ b/target/arm/tcg/translate.h
14
+++ b/include/fpu/softfloat.h
21
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status);
22
#define TARGET_ARM_TRANSLATE_H
16
| Using these differs from negating an input or output before calling
23
17
| the muladd function in that this means that a NaN doesn't have its
24
#include "exec/translator.h"
18
| sign bit inverted before it is propagated.
25
+#include "exec/helper-gen.h"
19
-| We also support halving the result before rounding, as a special
26
#include "internals.h"
20
-| case to support the ARM fused-sqrt-step instruction FRSQRTS.
27
21
*----------------------------------------------------------------------------*/
28
22
enum {
29
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
23
float_muladd_negate_c = 1,
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
30
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/tcg/translate-a64.c
32
--- a/fpu/softfloat.c
32
+++ b/target/arm/tcg/translate-a64.c
33
+++ b/fpu/softfloat.c
33
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
34
#include "qemu/host-utils.h"
35
if (unlikely(!can_use_fpu(s))) {
35
#include "semihosting/semihost.h"
36
goto soft;
36
#include "exec/gen-icount.h"
37
}
37
-#include "exec/helper-proto.h"
38
- if (unlikely(flags & float_muladd_halve_result)) {
38
-#include "exec/helper-gen.h"
39
- goto soft;
39
#include "exec/log.h"
40
- }
40
#include "cpregs.h"
41
41
#include "translate-a64.h"
42
float32_input_flush3(&ua.s, &ub.s, &uc.s, s);
42
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
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
43
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/tcg/translate-sme.c
56
--- a/fpu/softfloat-parts.c.inc
45
+++ b/target/arm/tcg/translate-sme.c
57
+++ b/fpu/softfloat-parts.c.inc
46
@@ -XXX,XX +XXX,XX @@
58
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
47
#include "tcg/tcg-op-gvec.h"
59
a->exp = p_widen.exp;
48
#include "tcg/tcg-gvec-desc.h"
60
49
#include "translate.h"
61
return_normal:
50
-#include "exec/helper-gen.h"
62
- /* TODO: Replace all use of float_muladd_halve_result with scale. */
51
#include "translate-a64.h"
63
- if (flags & float_muladd_halve_result) {
52
#include "fpu/softfloat.h"
64
- a->exp -= 1;
53
65
- }
54
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
66
a->exp += scale;
55
index XXXXXXX..XXXXXXX 100644
67
finish_sign:
56
--- a/target/arm/tcg/translate-sve.c
68
if (flags & float_muladd_negate_result) {
57
+++ b/target/arm/tcg/translate-sve.c
58
@@ -XXX,XX +XXX,XX @@
59
#include "arm_ldst.h"
60
#include "translate.h"
61
#include "internals.h"
62
-#include "exec/helper-proto.h"
63
-#include "exec/helper-gen.h"
64
#include "exec/log.h"
65
#include "translate-a64.h"
66
#include "fpu/softfloat.h"
67
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/tcg/translate.c
70
+++ b/target/arm/tcg/translate.c
71
@@ -XXX,XX +XXX,XX @@
72
#include "qemu/bitops.h"
73
#include "arm_ldst.h"
74
#include "semihosting/semihost.h"
75
-#include "exec/helper-proto.h"
76
-#include "exec/helper-gen.h"
77
#include "exec/log.h"
78
#include "cpregs.h"
79
80
--
69
--
81
2.34.1
70
2.43.0
82
71
83
72
diff view generated by jsdifflib
1
This is used by exactly one host in extraordinary circumstances.
1
This rounding mode is used by Hexagon.
2
This means that translator.h need not include plugin-gen.h;
3
translator.c already includes plugin-gen.h.
4
2
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
4
---
8
include/exec/translator.h | 8 +-------
5
include/fpu/softfloat-types.h | 2 ++
9
accel/tcg/translator.c | 5 +++++
6
fpu/softfloat-parts.c.inc | 3 +++
10
2 files changed, 6 insertions(+), 7 deletions(-)
7
2 files changed, 5 insertions(+)
11
8
12
diff --git a/include/exec/translator.h b/include/exec/translator.h
9
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
13
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
14
--- a/include/exec/translator.h
11
--- a/include/fpu/softfloat-types.h
15
+++ b/include/exec/translator.h
12
+++ b/include/fpu/softfloat-types.h
16
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
17
#include "qemu/bswap.h"
14
float_round_to_odd = 5,
18
#include "exec/exec-all.h"
15
/* Not an IEEE rounding mode: round to closest odd, overflow to inf */
19
#include "exec/cpu_ldst.h"
16
float_round_to_odd_inf = 6,
20
-#include "exec/plugin-gen.h"
17
+ /* Not an IEEE rounding mode: round to nearest even, overflow to max */
21
#include "exec/translate-all.h"
18
+ float_round_nearest_even_max = 7,
22
#include "tcg/tcg.h"
19
} FloatRoundMode;
23
24
@@ -XXX,XX +XXX,XX @@ translator_ldq_swap(CPUArchState *env, DisasContextBase *db,
25
* re-synthesised for s390x "ex"). It ensures we update other areas of
26
* the translator with details of the executed instruction.
27
*/
28
-
29
-static inline void translator_fake_ldb(uint8_t insn8, abi_ptr pc)
30
-{
31
- plugin_insn_append(pc, &insn8, sizeof(insn8));
32
-}
33
-
34
+void translator_fake_ldb(uint8_t insn8, abi_ptr pc);
35
20
36
/*
21
/*
37
* Return whether addr is on the same page as where disassembly started.
22
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
38
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
39
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
40
--- a/accel/tcg/translator.c
24
--- a/fpu/softfloat-parts.c.inc
41
+++ b/accel/tcg/translator.c
25
+++ b/fpu/softfloat-parts.c.inc
42
@@ -XXX,XX +XXX,XX @@ uint64_t translator_ldq(CPUArchState *env, DisasContextBase *db, abi_ptr pc)
26
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
43
plugin_insn_append(pc, &plug, sizeof(ret));
27
int exp, flags = 0;
44
return ret;
28
45
}
29
switch (s->float_rounding_mode) {
46
+
30
+ case float_round_nearest_even_max:
47
+void translator_fake_ldb(uint8_t insn8, abi_ptr pc)
31
+ overflow_norm = true;
48
+{
32
+ /* fall through */
49
+ plugin_insn_append(pc, &insn8, sizeof(insn8));
33
case float_round_nearest_even:
50
+}
34
if (N > 64 && frac_lsb == 0) {
35
inc = ((p->frac_hi & 1) || (p->frac_lo & round_mask) != frac_lsbm1
51
--
36
--
52
2.34.1
37
2.43.0
53
54
diff view generated by jsdifflib
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Certain Hexagon instructions suppress changes to the result
2
when the product of fma() is a true zero.
3
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
5
---
4
include/exec/helper-head.h | 18 +++---------------
6
include/fpu/softfloat.h | 5 +++++
5
1 file changed, 3 insertions(+), 15 deletions(-)
7
fpu/softfloat.c | 3 +++
8
fpu/softfloat-parts.c.inc | 4 +++-
9
3 files changed, 11 insertions(+), 1 deletion(-)
6
10
7
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
11
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
8
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
9
--- a/include/exec/helper-head.h
13
--- a/include/fpu/softfloat.h
10
+++ b/include/exec/helper-head.h
14
+++ b/include/fpu/softfloat.h
11
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status);
12
-/* Helper file for declaring TCG helper functions.
16
| Using these differs from negating an input or output before calling
13
- Used by other helper files.
17
| the muladd function in that this means that a NaN doesn't have its
14
-
18
| sign bit inverted before it is propagated.
15
- Targets should use DEF_HELPER_N and DEF_HELPER_FLAGS_N to declare helper
19
+|
16
- functions. Names should be specified without the helper_ prefix, and
20
+| With float_muladd_suppress_add_product_zero, if A or B is zero
17
- the return and argument types specified. 3 basic types are understood
21
+| such that the product is a true zero, then return C without addition.
18
- (i32, i64 and ptr). Additional aliases are provided for convenience and
22
+| This preserves the sign of C when C is +/- 0. Used for Hexagon.
19
- to match the types used by the C helper implementation.
23
*----------------------------------------------------------------------------*/
20
-
24
enum {
21
- The target helper.h should be included in all files that use/define
25
float_muladd_negate_c = 1,
22
- helper functions. THis will ensure that function prototypes are
26
float_muladd_negate_product = 2,
23
- consistent. In addition it should be included an extra two times for
27
float_muladd_negate_result = 4,
24
- helper.c, defining:
28
+ float_muladd_suppress_add_product_zero = 8,
25
- GEN_HELPER 1 to produce op generation functions (gen_helper_*)
29
};
26
- GEN_HELPER 2 to do runtime registration helper functions.
30
27
+/*
31
/*----------------------------------------------------------------------------
28
+ * Helper file for declaring TCG helper functions.
32
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
29
+ * Used by other helper files.
33
index XXXXXXX..XXXXXXX 100644
30
*/
34
--- a/fpu/softfloat.c
31
35
+++ b/fpu/softfloat.c
32
#ifndef EXEC_HELPER_HEAD_H
36
@@ -XXX,XX +XXX,XX @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
37
if (unlikely(!can_use_fpu(s))) {
38
goto soft;
39
}
40
+ if (unlikely(flags & float_muladd_suppress_add_product_zero)) {
41
+ goto soft;
42
+ }
43
44
float32_input_flush3(&ua.s, &ub.s, &uc.s, s);
45
if (unlikely(!f32_is_zon3(ua, ub, uc))) {
46
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
47
index XXXXXXX..XXXXXXX 100644
48
--- a/fpu/softfloat-parts.c.inc
49
+++ b/fpu/softfloat-parts.c.inc
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
51
goto return_normal;
52
}
53
if (c->cls == float_class_zero) {
54
- if (a->sign != c->sign) {
55
+ if (flags & float_muladd_suppress_add_product_zero) {
56
+ a->sign = c->sign;
57
+ } else if (a->sign != c->sign) {
58
goto return_sub_zero;
59
}
60
goto return_zero;
33
--
61
--
34
2.34.1
62
2.43.0
35
36
diff view generated by jsdifflib
1
These two items are the last uses of TARGET_LONG_BITS within tcg.h,
1
There are no special cases for this instruction.
2
and are more in common with the other "_tl" definitions within that file.
2
Remove internal_mpyf as unused.
3
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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-op.h | 15 ++++++++++++++-
7
target/hexagon/fma_emu.h | 1 -
8
include/tcg/tcg.h | 19 -------------------
8
target/hexagon/fma_emu.c | 8 --------
9
target/mips/tcg/translate.h | 1 +
9
target/hexagon/op_helper.c | 2 +-
10
3 files changed, 15 insertions(+), 20 deletions(-)
10
3 files changed, 1 insertion(+), 10 deletions(-)
11
11
12
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
12
diff --git a/target/hexagon/fma_emu.h b/target/hexagon/fma_emu.h
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/tcg/tcg-op.h
14
--- a/target/hexagon/fma_emu.h
15
+++ b/include/tcg/tcg-op.h
15
+++ b/target/hexagon/fma_emu.h
16
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_plugin_cb_end(void)
16
@@ -XXX,XX +XXX,XX @@ int32_t float32_getexp(float32 f32);
17
float32 infinite_float32(uint8_t sign);
18
float32 internal_fmafx(float32 a, float32 b, float32 c,
19
int scale, float_status *fp_status);
20
-float32 internal_mpyf(float32 a, float32 b, float_status *fp_status);
21
float64 internal_mpyhh(float64 a, float64 b,
22
unsigned long long int accumulated,
23
float_status *fp_status);
24
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/hexagon/fma_emu.c
27
+++ b/target/hexagon/fma_emu.c
28
@@ -XXX,XX +XXX,XX @@ float32 internal_fmafx(float32 a, float32 b, float32 c, int scale,
29
return accum_round_float32(result, fp_status);
17
}
30
}
18
31
19
#if TARGET_LONG_BITS == 32
32
-float32 internal_mpyf(float32 a, float32 b, float_status *fp_status)
20
+typedef TCGv_i32 TCGv;
33
-{
21
#define tcg_temp_new() tcg_temp_new_i32()
34
- if (float32_is_zero(a) || float32_is_zero(b)) {
22
#define tcg_global_mem_new tcg_global_mem_new_i32
35
- return float32_mul(a, b, fp_status);
23
#define tcg_temp_free tcg_temp_free_i32
36
- }
24
#define tcgv_tl_temp tcgv_i32_temp
37
- return internal_fmafx(a, b, float32_zero, 0, fp_status);
25
#define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i32
38
-}
26
#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32
39
-
27
-#else
40
float64 internal_mpyhh(float64 a, float64 b,
28
+#elif TARGET_LONG_BITS == 64
41
unsigned long long int accumulated,
29
+typedef TCGv_i64 TCGv;
42
float_status *fp_status)
30
#define tcg_temp_new() tcg_temp_new_i64()
43
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
31
#define tcg_global_mem_new tcg_global_mem_new_i64
32
#define tcg_temp_free tcg_temp_free_i64
33
#define tcgv_tl_temp tcgv_i64_temp
34
#define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i64
35
#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i64
36
+#else
37
+#error Unhandled TARGET_LONG_BITS value
38
#endif
39
40
void tcg_gen_qemu_ld_i32_chk(TCGv_i32, TCGTemp *, TCGArg, MemOp, TCGType);
41
@@ -XXX,XX +XXX,XX @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
42
#define tcg_gen_atomic_umax_fetch_tl tcg_gen_atomic_umax_fetch_i64
43
#define tcg_gen_dup_tl_vec tcg_gen_dup_i64_vec
44
#define tcg_gen_dup_tl tcg_gen_dup_i64
45
+#define dup_const_tl dup_const
46
#else
47
#define tcg_gen_movi_tl tcg_gen_movi_i32
48
#define tcg_gen_mov_tl tcg_gen_mov_i32
49
@@ -XXX,XX +XXX,XX @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
50
#define tcg_gen_atomic_umax_fetch_tl tcg_gen_atomic_umax_fetch_i32
51
#define tcg_gen_dup_tl_vec tcg_gen_dup_i32_vec
52
#define tcg_gen_dup_tl tcg_gen_dup_i32
53
+
54
+#define dup_const_tl(VECE, C) \
55
+ (__builtin_constant_p(VECE) \
56
+ ? ( (VECE) == MO_8 ? 0x01010101ul * (uint8_t)(C) \
57
+ : (VECE) == MO_16 ? 0x00010001ul * (uint16_t)(C) \
58
+ : (VECE) == MO_32 ? 0x00000001ul * (uint32_t)(C) \
59
+ : (qemu_build_not_reached_always(), 0)) \
60
+ : (target_long)dup_const(VECE, C))
61
#endif
62
63
#if UINTPTR_MAX == UINT32_MAX
64
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
65
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
66
--- a/include/tcg/tcg.h
45
--- a/target/hexagon/op_helper.c
67
+++ b/include/tcg/tcg.h
46
+++ b/target/hexagon/op_helper.c
68
@@ -XXX,XX +XXX,XX @@ typedef struct TCGv_i128_d *TCGv_i128;
47
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sfmpy)(CPUHexagonState *env, float32 RsV, float32 RtV)
69
typedef struct TCGv_ptr_d *TCGv_ptr;
48
{
70
typedef struct TCGv_vec_d *TCGv_vec;
49
float32 RdV;
71
typedef TCGv_ptr TCGv_env;
50
arch_fpop_start(env);
72
-#if TARGET_LONG_BITS == 32
51
- RdV = internal_mpyf(RsV, RtV, &env->fp_status);
73
-#define TCGv TCGv_i32
52
+ RdV = float32_mul(RsV, RtV, &env->fp_status);
74
-#elif TARGET_LONG_BITS == 64
53
arch_fpop_end(env);
75
-#define TCGv TCGv_i64
54
return RdV;
76
-#else
55
}
77
-#error Unhandled TARGET_LONG_BITS value
78
-#endif
79
80
/* call flags */
81
/* Helper does not read globals (either directly or through an exception). It
82
@@ -XXX,XX +XXX,XX @@ uint64_t dup_const(unsigned vece, uint64_t c);
83
: (qemu_build_not_reached_always(), 0)) \
84
: dup_const(VECE, C))
85
86
-#if TARGET_LONG_BITS == 64
87
-# define dup_const_tl dup_const
88
-#else
89
-# define dup_const_tl(VECE, C) \
90
- (__builtin_constant_p(VECE) \
91
- ? ( (VECE) == MO_8 ? 0x01010101ul * (uint8_t)(C) \
92
- : (VECE) == MO_16 ? 0x00010001ul * (uint16_t)(C) \
93
- : (VECE) == MO_32 ? 0x00000001ul * (uint32_t)(C) \
94
- : (qemu_build_not_reached_always(), 0)) \
95
- : (target_long)dup_const(VECE, C))
96
-#endif
97
-
98
#ifdef CONFIG_DEBUG_TCG
99
void tcg_assert_listed_vecop(TCGOpcode);
100
#else
101
diff --git a/target/mips/tcg/translate.h b/target/mips/tcg/translate.h
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/mips/tcg/translate.h
104
+++ b/target/mips/tcg/translate.h
105
@@ -XXX,XX +XXX,XX @@
106
107
#include "qemu/log.h"
108
#include "exec/translator.h"
109
+#include "tcg/tcg-op.h"
110
111
#define MIPS_DEBUG_DISAS 0
112
113
--
56
--
114
2.34.1
57
2.43.0
115
116
diff view generated by jsdifflib
1
Move a use of TARGET_LONG_BITS out of tcg/tcg.h.
1
There are no special cases for this instruction.
2
Include the new file only where required.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
5
---
7
include/exec/cpu_ldst.h | 3 +--
6
target/hexagon/op_helper.c | 2 +-
8
include/tcg/oversized-guest.h | 23 +++++++++++++++++++++++
7
1 file changed, 1 insertion(+), 1 deletion(-)
9
include/tcg/tcg.h | 9 ---------
10
accel/tcg/cputlb.c | 1 +
11
accel/tcg/tcg-all.c | 1 +
12
target/arm/ptw.c | 1 +
13
target/riscv/cpu_helper.c | 1 +
14
7 files changed, 28 insertions(+), 11 deletions(-)
15
create mode 100644 include/tcg/oversized-guest.h
16
8
17
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
9
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
18
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/cpu_ldst.h
11
--- a/target/hexagon/op_helper.c
20
+++ b/include/exec/cpu_ldst.h
12
+++ b/target/hexagon/op_helper.c
21
@@ -XXX,XX +XXX,XX @@ static inline void clear_helper_retaddr(void)
13
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffma)(CPUHexagonState *env, float32 RxV,
22
14
float32 RsV, float32 RtV)
23
#else
24
25
-/* Needed for TCG_OVERSIZED_GUEST */
26
-#include "tcg/tcg.h"
27
+#include "tcg/oversized-guest.h"
28
29
static inline target_ulong tlb_read_idx(const CPUTLBEntry *entry,
30
MMUAccessType access_type)
31
diff --git a/include/tcg/oversized-guest.h b/include/tcg/oversized-guest.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/tcg/oversized-guest.h
36
@@ -XXX,XX +XXX,XX @@
37
+/* SPDX-License-Identifier: MIT */
38
+/*
39
+ * Define TCG_OVERSIZED_GUEST
40
+ * Copyright (c) 2008 Fabrice Bellard
41
+ */
42
+
43
+#ifndef EXEC_TCG_OVERSIZED_GUEST_H
44
+#define EXEC_TCG_OVERSIZED_GUEST_H
45
+
46
+#include "tcg-target-reg-bits.h"
47
+#include "cpu-param.h"
48
+
49
+/*
50
+ * Oversized TCG guests make things like MTTCG hard
51
+ * as we can't use atomics for cputlb updates.
52
+ */
53
+#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
54
+#define TCG_OVERSIZED_GUEST 1
55
+#else
56
+#define TCG_OVERSIZED_GUEST 0
57
+#endif
58
+
59
+#endif
60
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/include/tcg/tcg.h
63
+++ b/include/tcg/tcg.h
64
@@ -XXX,XX +XXX,XX @@ typedef uint64_t tcg_target_ulong;
65
#error unsupported
66
#endif
67
68
-/* Oversized TCG guests make things like MTTCG hard
69
- * as we can't use atomics for cputlb updates.
70
- */
71
-#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
72
-#define TCG_OVERSIZED_GUEST 1
73
-#else
74
-#define TCG_OVERSIZED_GUEST 0
75
-#endif
76
-
77
#if TCG_TARGET_NB_REGS <= 32
78
typedef uint32_t TCGRegSet;
79
#elif TCG_TARGET_NB_REGS <= 64
80
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/accel/tcg/cputlb.c
83
+++ b/accel/tcg/cputlb.c
84
@@ -XXX,XX +XXX,XX @@
85
#include "qemu/plugin-memory.h"
86
#endif
87
#include "tcg/tcg-ldst.h"
88
+#include "tcg/oversized-guest.h"
89
#include "exec/helper-proto.h"
90
91
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
92
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/accel/tcg/tcg-all.c
95
+++ b/accel/tcg/tcg-all.c
96
@@ -XXX,XX +XXX,XX @@
97
#include "exec/replay-core.h"
98
#include "sysemu/cpu-timers.h"
99
#include "tcg/tcg.h"
100
+#include "tcg/oversized-guest.h"
101
#include "qapi/error.h"
102
#include "qemu/error-report.h"
103
#include "qemu/accel.h"
104
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/ptw.c
107
+++ b/target/arm/ptw.c
108
@@ -XXX,XX +XXX,XX @@
109
#include "cpu.h"
110
#include "internals.h"
111
#include "idau.h"
112
+#include "tcg/oversized-guest.h"
113
114
115
typedef struct S1Translate {
116
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/riscv/cpu_helper.c
119
+++ b/target/riscv/cpu_helper.c
120
@@ -XXX,XX +XXX,XX @@
121
#include "sysemu/cpu-timers.h"
122
#include "cpu_bits.h"
123
#include "debug.h"
124
+#include "tcg/oversized-guest.h"
125
126
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
127
{
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
}
128
--
22
--
129
2.34.1
23
2.43.0
130
131
diff view generated by jsdifflib
1
Often, the only thing we need to know about the TCG host
1
There are no special cases for this instruction. Since hexagon
2
is the register size.
2
always uses default-nan mode, explicitly negating the first
3
input is unnecessary. Use float_muladd_negate_product instead.
3
4
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
---
7
include/tcg/tcg.h | 12 +-----------
8
target/hexagon/op_helper.c | 5 ++---
8
tcg/aarch64/tcg-target-reg-bits.h | 12 ++++++++++++
9
1 file changed, 2 insertions(+), 3 deletions(-)
9
tcg/arm/tcg-target-reg-bits.h | 12 ++++++++++++
10
tcg/i386/tcg-target-reg-bits.h | 16 ++++++++++++++++
11
tcg/i386/tcg-target.h | 2 --
12
tcg/loongarch64/tcg-target-reg-bits.h | 21 +++++++++++++++++++++
13
tcg/loongarch64/tcg-target.h | 11 -----------
14
tcg/mips/tcg-target-reg-bits.h | 18 ++++++++++++++++++
15
tcg/mips/tcg-target.h | 8 --------
16
tcg/ppc/tcg-target-reg-bits.h | 16 ++++++++++++++++
17
tcg/ppc/tcg-target.h | 5 -----
18
tcg/riscv/tcg-target-reg-bits.h | 19 +++++++++++++++++++
19
tcg/riscv/tcg-target.h | 9 ---------
20
tcg/s390x/tcg-target-reg-bits.h | 17 +++++++++++++++++
21
tcg/sparc64/tcg-target-reg-bits.h | 12 ++++++++++++
22
tcg/tci/tcg-target-reg-bits.h | 18 ++++++++++++++++++
23
tcg/tci/tcg-target.h | 8 --------
24
tcg/s390x/tcg-target.c.inc | 5 -----
25
18 files changed, 162 insertions(+), 59 deletions(-)
26
create mode 100644 tcg/aarch64/tcg-target-reg-bits.h
27
create mode 100644 tcg/arm/tcg-target-reg-bits.h
28
create mode 100644 tcg/i386/tcg-target-reg-bits.h
29
create mode 100644 tcg/loongarch64/tcg-target-reg-bits.h
30
create mode 100644 tcg/mips/tcg-target-reg-bits.h
31
create mode 100644 tcg/ppc/tcg-target-reg-bits.h
32
create mode 100644 tcg/riscv/tcg-target-reg-bits.h
33
create mode 100644 tcg/s390x/tcg-target-reg-bits.h
34
create mode 100644 tcg/sparc64/tcg-target-reg-bits.h
35
create mode 100644 tcg/tci/tcg-target-reg-bits.h
36
10
37
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
11
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
38
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
39
--- a/include/tcg/tcg.h
13
--- a/target/hexagon/op_helper.c
40
+++ b/include/tcg/tcg.h
14
+++ b/target/hexagon/op_helper.c
41
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
42
#include "qemu/plugin.h"
16
float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV,
43
#include "qemu/queue.h"
17
float32 RsV, float32 RtV)
44
#include "tcg/tcg-mo.h"
18
{
45
+#include "tcg-target-reg-bits.h"
19
- float32 neg_RsV;
46
#include "tcg-target.h"
20
arch_fpop_start(env);
47
#include "tcg/tcg-cond.h"
21
- neg_RsV = float32_set_sign(RsV, float32_is_neg(RsV) ? 0 : 1);
48
#include "tcg/debug-assert.h"
22
- RxV = internal_fmafx(neg_RsV, RtV, RxV, 0, &env->fp_status);
49
@@ -XXX,XX +XXX,XX @@
23
+ RxV = float32_muladd(RsV, RtV, RxV, float_muladd_negate_product,
50
#define CPU_TEMP_BUF_NLONGS 128
24
+ &env->fp_status);
51
#define TCG_STATIC_FRAME_SIZE (CPU_TEMP_BUF_NLONGS * sizeof(long))
25
arch_fpop_end(env);
52
26
return RxV;
53
-/* Default target word size to pointer size. */
27
}
54
-#ifndef TCG_TARGET_REG_BITS
55
-# if UINTPTR_MAX == UINT32_MAX
56
-# define TCG_TARGET_REG_BITS 32
57
-# elif UINTPTR_MAX == UINT64_MAX
58
-# define TCG_TARGET_REG_BITS 64
59
-# else
60
-# error Unknown pointer size for tcg target
61
-# endif
62
-#endif
63
-
64
#if TCG_TARGET_REG_BITS == 32
65
typedef int32_t tcg_target_long;
66
typedef uint32_t tcg_target_ulong;
67
diff --git a/tcg/aarch64/tcg-target-reg-bits.h b/tcg/aarch64/tcg-target-reg-bits.h
68
new file mode 100644
69
index XXXXXXX..XXXXXXX
70
--- /dev/null
71
+++ b/tcg/aarch64/tcg-target-reg-bits.h
72
@@ -XXX,XX +XXX,XX @@
73
+/* SPDX-License-Identifier: GPL-2.0-or-later */
74
+/*
75
+ * Define target-specific register size
76
+ * Copyright (c) 2023 Linaro
77
+ */
78
+
79
+#ifndef TCG_TARGET_REG_BITS_H
80
+#define TCG_TARGET_REG_BITS_H
81
+
82
+#define TCG_TARGET_REG_BITS 64
83
+
84
+#endif
85
diff --git a/tcg/arm/tcg-target-reg-bits.h b/tcg/arm/tcg-target-reg-bits.h
86
new file mode 100644
87
index XXXXXXX..XXXXXXX
88
--- /dev/null
89
+++ b/tcg/arm/tcg-target-reg-bits.h
90
@@ -XXX,XX +XXX,XX @@
91
+/* SPDX-License-Identifier: MIT */
92
+/*
93
+ * Define target-specific register size
94
+ * Copyright (c) 2023 Linaro
95
+ */
96
+
97
+#ifndef TCG_TARGET_REG_BITS_H
98
+#define TCG_TARGET_REG_BITS_H
99
+
100
+#define TCG_TARGET_REG_BITS 32
101
+
102
+#endif
103
diff --git a/tcg/i386/tcg-target-reg-bits.h b/tcg/i386/tcg-target-reg-bits.h
104
new file mode 100644
105
index XXXXXXX..XXXXXXX
106
--- /dev/null
107
+++ b/tcg/i386/tcg-target-reg-bits.h
108
@@ -XXX,XX +XXX,XX @@
109
+/* SPDX-License-Identifier: MIT */
110
+/*
111
+ * Define target-specific register size
112
+ * Copyright (c) 2008 Fabrice Bellard
113
+ */
114
+
115
+#ifndef TCG_TARGET_REG_BITS_H
116
+#define TCG_TARGET_REG_BITS_H
117
+
118
+#ifdef __x86_64__
119
+# define TCG_TARGET_REG_BITS 64
120
+#else
121
+# define TCG_TARGET_REG_BITS 32
122
+#endif
123
+
124
+#endif
125
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
126
index XXXXXXX..XXXXXXX 100644
127
--- a/tcg/i386/tcg-target.h
128
+++ b/tcg/i386/tcg-target.h
129
@@ -XXX,XX +XXX,XX @@
130
#define TCG_TARGET_INSN_UNIT_SIZE 1
131
132
#ifdef __x86_64__
133
-# define TCG_TARGET_REG_BITS 64
134
# define TCG_TARGET_NB_REGS 32
135
# define MAX_CODE_GEN_BUFFER_SIZE (2 * GiB)
136
#else
137
-# define TCG_TARGET_REG_BITS 32
138
# define TCG_TARGET_NB_REGS 24
139
# define MAX_CODE_GEN_BUFFER_SIZE UINT32_MAX
140
#endif
141
diff --git a/tcg/loongarch64/tcg-target-reg-bits.h b/tcg/loongarch64/tcg-target-reg-bits.h
142
new file mode 100644
143
index XXXXXXX..XXXXXXX
144
--- /dev/null
145
+++ b/tcg/loongarch64/tcg-target-reg-bits.h
146
@@ -XXX,XX +XXX,XX @@
147
+/* SPDX-License-Identifier: MIT */
148
+/*
149
+ * Define target-specific register size
150
+ * Copyright (c) 2021 WANG Xuerui <git@xen0n.name>
151
+ */
152
+
153
+#ifndef TCG_TARGET_REG_BITS_H
154
+#define TCG_TARGET_REG_BITS_H
155
+
156
+/*
157
+ * Loongson removed the (incomplete) 32-bit support from kernel and toolchain
158
+ * for the initial upstreaming of this architecture, so don't bother and just
159
+ * support the LP64* ABI for now.
160
+ */
161
+#if defined(__loongarch64)
162
+# define TCG_TARGET_REG_BITS 64
163
+#else
164
+# error unsupported LoongArch register size
165
+#endif
166
+
167
+#endif
168
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
169
index XXXXXXX..XXXXXXX 100644
170
--- a/tcg/loongarch64/tcg-target.h
171
+++ b/tcg/loongarch64/tcg-target.h
172
@@ -XXX,XX +XXX,XX @@
173
#ifndef LOONGARCH_TCG_TARGET_H
174
#define LOONGARCH_TCG_TARGET_H
175
176
-/*
177
- * Loongson removed the (incomplete) 32-bit support from kernel and toolchain
178
- * for the initial upstreaming of this architecture, so don't bother and just
179
- * support the LP64* ABI for now.
180
- */
181
-#if defined(__loongarch64)
182
-# define TCG_TARGET_REG_BITS 64
183
-#else
184
-# error unsupported LoongArch register size
185
-#endif
186
-
187
#define TCG_TARGET_INSN_UNIT_SIZE 4
188
#define TCG_TARGET_NB_REGS 32
189
190
diff --git a/tcg/mips/tcg-target-reg-bits.h b/tcg/mips/tcg-target-reg-bits.h
191
new file mode 100644
192
index XXXXXXX..XXXXXXX
193
--- /dev/null
194
+++ b/tcg/mips/tcg-target-reg-bits.h
195
@@ -XXX,XX +XXX,XX @@
196
+/* SPDX-License-Identifier: MIT */
197
+/*
198
+ * Define target-specific register size
199
+ * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
200
+ */
201
+
202
+#ifndef TCG_TARGET_REG_BITS_H
203
+#define TCG_TARGET_REG_BITS_H
204
+
205
+#if _MIPS_SIM == _ABIO32
206
+# define TCG_TARGET_REG_BITS 32
207
+#elif _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
208
+# define TCG_TARGET_REG_BITS 64
209
+#else
210
+# error "Unknown ABI"
211
+#endif
212
+
213
+#endif
214
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
215
index XXXXXXX..XXXXXXX 100644
216
--- a/tcg/mips/tcg-target.h
217
+++ b/tcg/mips/tcg-target.h
218
@@ -XXX,XX +XXX,XX @@
219
#ifndef MIPS_TCG_TARGET_H
220
#define MIPS_TCG_TARGET_H
221
222
-#if _MIPS_SIM == _ABIO32
223
-# define TCG_TARGET_REG_BITS 32
224
-#elif _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
225
-# define TCG_TARGET_REG_BITS 64
226
-#else
227
-# error "Unknown ABI"
228
-#endif
229
-
230
#define TCG_TARGET_INSN_UNIT_SIZE 4
231
#define TCG_TARGET_NB_REGS 32
232
233
diff --git a/tcg/ppc/tcg-target-reg-bits.h b/tcg/ppc/tcg-target-reg-bits.h
234
new file mode 100644
235
index XXXXXXX..XXXXXXX
236
--- /dev/null
237
+++ b/tcg/ppc/tcg-target-reg-bits.h
238
@@ -XXX,XX +XXX,XX @@
239
+/* SPDX-License-Identifier: MIT */
240
+/*
241
+ * Define target-specific register size
242
+ * Copyright (c) 2008 Fabrice Bellard
243
+ */
244
+
245
+#ifndef TCG_TARGET_REG_BITS_H
246
+#define TCG_TARGET_REG_BITS_H
247
+
248
+#ifdef _ARCH_PPC64
249
+# define TCG_TARGET_REG_BITS 64
250
+#else
251
+# define TCG_TARGET_REG_BITS 32
252
+#endif
253
+
254
+#endif
255
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
256
index XXXXXXX..XXXXXXX 100644
257
--- a/tcg/ppc/tcg-target.h
258
+++ b/tcg/ppc/tcg-target.h
259
@@ -XXX,XX +XXX,XX @@
260
#ifndef PPC_TCG_TARGET_H
261
#define PPC_TCG_TARGET_H
262
263
-#ifdef _ARCH_PPC64
264
-# define TCG_TARGET_REG_BITS 64
265
-#else
266
-# define TCG_TARGET_REG_BITS 32
267
-#endif
268
#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
269
270
#define TCG_TARGET_NB_REGS 64
271
diff --git a/tcg/riscv/tcg-target-reg-bits.h b/tcg/riscv/tcg-target-reg-bits.h
272
new file mode 100644
273
index XXXXXXX..XXXXXXX
274
--- /dev/null
275
+++ b/tcg/riscv/tcg-target-reg-bits.h
276
@@ -XXX,XX +XXX,XX @@
277
+/* SPDX-License-Identifier: MIT */
278
+/*
279
+ * Define target-specific register size
280
+ * Copyright (c) 2018 SiFive, Inc
281
+ */
282
+
283
+#ifndef TCG_TARGET_REG_BITS_H
284
+#define TCG_TARGET_REG_BITS_H
285
+
286
+/*
287
+ * We don't support oversize guests.
288
+ * Since we will only build tcg once, this in turn requires a 64-bit host.
289
+ */
290
+#if __riscv_xlen != 64
291
+#error "unsupported code generation mode"
292
+#endif
293
+#define TCG_TARGET_REG_BITS 64
294
+
295
+#endif
296
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
297
index XXXXXXX..XXXXXXX 100644
298
--- a/tcg/riscv/tcg-target.h
299
+++ b/tcg/riscv/tcg-target.h
300
@@ -XXX,XX +XXX,XX @@
301
#ifndef RISCV_TCG_TARGET_H
302
#define RISCV_TCG_TARGET_H
303
304
-/*
305
- * We don't support oversize guests.
306
- * Since we will only build tcg once, this in turn requires a 64-bit host.
307
- */
308
-#if __riscv_xlen != 64
309
-#error "unsupported code generation mode"
310
-#endif
311
-#define TCG_TARGET_REG_BITS 64
312
-
313
#define TCG_TARGET_INSN_UNIT_SIZE 4
314
#define TCG_TARGET_NB_REGS 32
315
#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
316
diff --git a/tcg/s390x/tcg-target-reg-bits.h b/tcg/s390x/tcg-target-reg-bits.h
317
new file mode 100644
318
index XXXXXXX..XXXXXXX
319
--- /dev/null
320
+++ b/tcg/s390x/tcg-target-reg-bits.h
321
@@ -XXX,XX +XXX,XX @@
322
+/* SPDX-License-Identifier: MIT */
323
+/*
324
+ * Define target-specific register size
325
+ * Copyright (c) 2009 Ulrich Hecht <uli@suse.de>
326
+ */
327
+
328
+#ifndef TCG_TARGET_REG_BITS_H
329
+#define TCG_TARGET_REG_BITS_H
330
+
331
+/* We only support generating code for 64-bit mode. */
332
+#if UINTPTR_MAX == UINT64_MAX
333
+# define TCG_TARGET_REG_BITS 64
334
+#else
335
+# error "unsupported code generation mode"
336
+#endif
337
+
338
+#endif
339
diff --git a/tcg/sparc64/tcg-target-reg-bits.h b/tcg/sparc64/tcg-target-reg-bits.h
340
new file mode 100644
341
index XXXXXXX..XXXXXXX
342
--- /dev/null
343
+++ b/tcg/sparc64/tcg-target-reg-bits.h
344
@@ -XXX,XX +XXX,XX @@
345
+/* SPDX-License-Identifier: MIT */
346
+/*
347
+ * Define target-specific register size
348
+ * Copyright (c) 2023 Linaro
349
+ */
350
+
351
+#ifndef TCG_TARGET_REG_BITS_H
352
+#define TCG_TARGET_REG_BITS_H
353
+
354
+#define TCG_TARGET_REG_BITS 64
355
+
356
+#endif
357
diff --git a/tcg/tci/tcg-target-reg-bits.h b/tcg/tci/tcg-target-reg-bits.h
358
new file mode 100644
359
index XXXXXXX..XXXXXXX
360
--- /dev/null
361
+++ b/tcg/tci/tcg-target-reg-bits.h
362
@@ -XXX,XX +XXX,XX @@
363
+/* SPDX-License-Identifier: MIT */
364
+/*
365
+ * Define target-specific register size
366
+ * Copyright (c) 2009, 2011 Stefan Weil
367
+ */
368
+
369
+#ifndef TCG_TARGET_REG_BITS_H
370
+#define TCG_TARGET_REG_BITS_H
371
+
372
+#if UINTPTR_MAX == UINT32_MAX
373
+# define TCG_TARGET_REG_BITS 32
374
+#elif UINTPTR_MAX == UINT64_MAX
375
+# define TCG_TARGET_REG_BITS 64
376
+#else
377
+# error Unknown pointer size for tci target
378
+#endif
379
+
380
+#endif
381
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
382
index XXXXXXX..XXXXXXX 100644
383
--- a/tcg/tci/tcg-target.h
384
+++ b/tcg/tci/tcg-target.h
385
@@ -XXX,XX +XXX,XX @@
386
#define TCG_TARGET_INSN_UNIT_SIZE 4
387
#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
388
389
-#if UINTPTR_MAX == UINT32_MAX
390
-# define TCG_TARGET_REG_BITS 32
391
-#elif UINTPTR_MAX == UINT64_MAX
392
-# define TCG_TARGET_REG_BITS 64
393
-#else
394
-# error Unknown pointer size for tci target
395
-#endif
396
-
397
/* Optional instructions. */
398
399
#define TCG_TARGET_HAS_bswap16_i32 1
400
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
401
index XXXXXXX..XXXXXXX 100644
402
--- a/tcg/s390x/tcg-target.c.inc
403
+++ b/tcg/s390x/tcg-target.c.inc
404
@@ -XXX,XX +XXX,XX @@
405
* THE SOFTWARE.
406
*/
407
408
-/* We only support generating code for 64-bit mode. */
409
-#if TCG_TARGET_REG_BITS != 64
410
-#error "unsupported code generation mode"
411
-#endif
412
-
413
#include "../tcg-ldst.c.inc"
414
#include "../tcg-pool.c.inc"
415
#include "elf.h"
416
--
28
--
417
2.34.1
29
2.43.0
418
419
diff view generated by jsdifflib
1
This had been pulled in from exec/cpu_ldst.h, via exec/exec-all.h,
1
This instruction has a special case that 0 * x + c returns c
2
but the include of tcg.h will be removed.
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.
3
5
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
8
---
7
accel/tcg/monitor.c | 1 +
9
target/hexagon/op_helper.c | 11 +++--------
8
accel/tcg/tcg-accel-ops-mttcg.c | 2 +-
10
1 file changed, 3 insertions(+), 8 deletions(-)
9
accel/tcg/tcg-accel-ops-rr.c | 2 +-
10
target/i386/helper.c | 3 +++
11
target/openrisc/sys_helper.c | 1 +
12
5 files changed, 7 insertions(+), 2 deletions(-)
13
11
14
diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c
12
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/accel/tcg/monitor.c
14
--- a/target/hexagon/op_helper.c
17
+++ b/accel/tcg/monitor.c
15
+++ b/target/hexagon/op_helper.c
18
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static float32 check_nan(float32 dst, float32 x, float_status *fp_status)
19
#include "sysemu/cpus.h"
17
float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
20
#include "sysemu/cpu-timers.h"
18
float32 RsV, float32 RtV, float32 PuV)
21
#include "sysemu/tcg.h"
22
+#include "tcg/tcg.h"
23
#include "internal.h"
24
25
26
diff --git a/accel/tcg/tcg-accel-ops-mttcg.c b/accel/tcg/tcg-accel-ops-mttcg.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/accel/tcg/tcg-accel-ops-mttcg.c
29
+++ b/accel/tcg/tcg-accel-ops-mttcg.c
30
@@ -XXX,XX +XXX,XX @@
31
#include "qemu/guest-random.h"
32
#include "exec/exec-all.h"
33
#include "hw/boards.h"
34
-
35
+#include "tcg/tcg.h"
36
#include "tcg-accel-ops.h"
37
#include "tcg-accel-ops-mttcg.h"
38
39
diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/accel/tcg/tcg-accel-ops-rr.c
42
+++ b/accel/tcg/tcg-accel-ops-rr.c
43
@@ -XXX,XX +XXX,XX @@
44
#include "qemu/notify.h"
45
#include "qemu/guest-random.h"
46
#include "exec/exec-all.h"
47
-
48
+#include "tcg/tcg.h"
49
#include "tcg-accel-ops.h"
50
#include "tcg-accel-ops-rr.h"
51
#include "tcg-accel-ops-icount.h"
52
diff --git a/target/i386/helper.c b/target/i386/helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/i386/helper.c
55
+++ b/target/i386/helper.c
56
@@ -XXX,XX +XXX,XX @@
57
#include "monitor/monitor.h"
58
#endif
59
#include "qemu/log.h"
60
+#ifdef CONFIG_TCG
61
+#include "tcg/tcg.h"
62
+#endif
63
64
void cpu_sync_avx_hflag(CPUX86State *env)
65
{
19
{
66
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
20
- size4s_t tmp;
67
index XXXXXXX..XXXXXXX 100644
21
arch_fpop_start(env);
68
--- a/target/openrisc/sys_helper.c
22
- RxV = check_nan(RxV, RxV, &env->fp_status);
69
+++ b/target/openrisc/sys_helper.c
23
- RxV = check_nan(RxV, RsV, &env->fp_status);
70
@@ -XXX,XX +XXX,XX @@
24
- RxV = check_nan(RxV, RtV, &env->fp_status);
71
#ifndef CONFIG_USER_ONLY
25
- tmp = internal_fmafx(RsV, RtV, RxV, fSXTN(8, 64, PuV), &env->fp_status);
72
#include "hw/boards.h"
26
- if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
73
#endif
27
- RxV = tmp;
74
+#include "tcg/tcg.h"
28
- }
75
29
+ RxV = float32_muladd_scalbn(RsV, RtV, RxV, fSXTN(8, 64, PuV),
76
#define TO_SPR(group, number) (((group) << 11) + (number))
30
+ float_muladd_suppress_add_product_zero,
77
31
+ &env->fp_status);
32
arch_fpop_end(env);
33
return RxV;
34
}
78
--
35
--
79
2.34.1
36
2.43.0
80
81
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
There are multiple special cases for this instruction.
2
(1) The saturate to normal maximum instead of overflow to infinity is
3
handled by the new float_round_nearest_even_max rounding mode.
4
(2) The 0 * n + c special case is handled by the new
5
float_muladd_suppress_add_product_zero flag.
6
(3) The Inf - Inf -> 0 special case can be detected after the fact
7
by examining float_flag_invalid_isi.
2
8
3
Now that gen_icount_io_start() is a simple wrapper to
9
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
4
translator_io_start(), inline it.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-Id: <20230602095439.48102-1-philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
---
11
target/ppc/translate.c | 63 ++++++++++++--------------
12
target/hexagon/op_helper.c | 105 +++++++++----------------------------
12
target/ppc/power8-pmu-regs.c.inc | 10 ++--
13
1 file changed, 26 insertions(+), 79 deletions(-)
13
target/ppc/translate/branch-impl.c.inc | 2 +-
14
3 files changed, 35 insertions(+), 40 deletions(-)
15
14
16
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
15
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/ppc/translate.c
17
--- a/target/hexagon/op_helper.c
19
+++ b/target/ppc/translate.c
18
+++ b/target/hexagon/op_helper.c
20
@@ -XXX,XX +XXX,XX @@ static void gen_exception_nip(DisasContext *ctx, uint32_t excp,
19
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffma)(CPUHexagonState *env, float32 RxV,
21
ctx->base.is_jmp = DISAS_NORETURN;
20
return RxV;
22
}
21
}
23
22
24
-static void gen_icount_io_start(DisasContext *ctx)
23
-static bool is_zero_prod(float32 a, float32 b)
25
-{
24
-{
26
- translator_io_start(&ctx->base);
25
- return ((float32_is_zero(a) && is_finite(b)) ||
26
- (float32_is_zero(b) && is_finite(a)));
27
-}
27
-}
28
-
28
-
29
#if !defined(CONFIG_USER_ONLY)
29
-static float32 check_nan(float32 dst, float32 x, float_status *fp_status)
30
static void gen_ppc_maybe_interrupt(DisasContext *ctx)
30
-{
31
- float32 ret = dst;
32
- if (float32_is_any_nan(x)) {
33
- if (extract32(x, 22, 1) == 0) {
34
- float_raise(float_flag_invalid, fp_status);
35
- }
36
- ret = make_float32(0xffffffff); /* nan */
37
- }
38
- return ret;
39
-}
40
-
41
float32 HELPER(sffma_sc)(CPUHexagonState *env, float32 RxV,
42
float32 RsV, float32 RtV, float32 PuV)
31
{
43
{
32
- gen_icount_io_start(ctx);
44
@@ -XXX,XX +XXX,XX @@ float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV,
33
+ translator_io_start(&ctx->base);
45
return RxV;
34
gen_helper_ppc_maybe_interrupt(cpu_env);
35
}
46
}
36
#endif
47
37
@@ -XXX,XX +XXX,XX @@ void spr_write_ureg(DisasContext *ctx, int sprn, int gprn)
48
-static bool is_inf_prod(int32_t a, int32_t b)
38
#if !defined(CONFIG_USER_ONLY)
49
+static float32 do_sffma_lib(CPUHexagonState *env, float32 RxV,
39
void spr_read_decr(DisasContext *ctx, int gprn, int sprn)
50
+ float32 RsV, float32 RtV, int negate)
40
{
51
{
41
- gen_icount_io_start(ctx);
52
- return (float32_is_infinity(a) && float32_is_infinity(b)) ||
42
+ translator_io_start(&ctx->base);
53
- (float32_is_infinity(a) && is_finite(b) && !float32_is_zero(b)) ||
43
gen_helper_load_decr(cpu_gpr[gprn], cpu_env);
54
- (float32_is_infinity(b) && is_finite(a) && !float32_is_zero(a));
55
+ int flags;
56
+
57
+ arch_fpop_start(env);
58
+
59
+ set_float_rounding_mode(float_round_nearest_even_max, &env->fp_status);
60
+ RxV = float32_muladd(RsV, RtV, RxV,
61
+ negate | float_muladd_suppress_add_product_zero,
62
+ &env->fp_status);
63
+
64
+ flags = get_float_exception_flags(&env->fp_status);
65
+ if (flags) {
66
+ /* Flags are suppressed by this instruction. */
67
+ set_float_exception_flags(0, &env->fp_status);
68
+
69
+ /* Return 0 for Inf - Inf. */
70
+ if (flags & float_flag_invalid_isi) {
71
+ RxV = 0;
72
+ }
73
+ }
74
+
75
+ arch_fpop_end(env);
76
+ return RxV;
44
}
77
}
45
78
46
void spr_write_decr(DisasContext *ctx, int sprn, int gprn)
79
float32 HELPER(sffma_lib)(CPUHexagonState *env, float32 RxV,
80
float32 RsV, float32 RtV)
47
{
81
{
48
- gen_icount_io_start(ctx);
82
- bool infinp;
49
+ translator_io_start(&ctx->base);
83
- bool infminusinf;
50
gen_helper_store_decr(cpu_env, cpu_gpr[gprn]);
84
- float32 tmp;
85
-
86
- arch_fpop_start(env);
87
- set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
88
- infminusinf = float32_is_infinity(RxV) &&
89
- is_inf_prod(RsV, RtV) &&
90
- (fGETBIT(31, RsV ^ RxV ^ RtV) != 0);
91
- infinp = float32_is_infinity(RxV) ||
92
- float32_is_infinity(RtV) ||
93
- float32_is_infinity(RsV);
94
- RxV = check_nan(RxV, RxV, &env->fp_status);
95
- RxV = check_nan(RxV, RsV, &env->fp_status);
96
- RxV = check_nan(RxV, RtV, &env->fp_status);
97
- tmp = internal_fmafx(RsV, RtV, RxV, 0, &env->fp_status);
98
- if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
99
- RxV = tmp;
100
- }
101
- set_float_exception_flags(0, &env->fp_status);
102
- if (float32_is_infinity(RxV) && !infinp) {
103
- RxV = RxV - 1;
104
- }
105
- if (infminusinf) {
106
- RxV = 0;
107
- }
108
- arch_fpop_end(env);
109
- return RxV;
110
+ return do_sffma_lib(env, RxV, RsV, RtV, 0);
51
}
111
}
52
#endif
112
53
@@ -XXX,XX +XXX,XX @@ void spr_write_decr(DisasContext *ctx, int sprn, int gprn)
113
float32 HELPER(sffms_lib)(CPUHexagonState *env, float32 RxV,
54
/* Time base */
114
float32 RsV, float32 RtV)
55
void spr_read_tbl(DisasContext *ctx, int gprn, int sprn)
56
{
115
{
57
- gen_icount_io_start(ctx);
116
- bool infinp;
58
+ translator_io_start(&ctx->base);
117
- bool infminusinf;
59
gen_helper_load_tbl(cpu_gpr[gprn], cpu_env);
118
- float32 tmp;
119
-
120
- arch_fpop_start(env);
121
- set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
122
- infminusinf = float32_is_infinity(RxV) &&
123
- is_inf_prod(RsV, RtV) &&
124
- (fGETBIT(31, RsV ^ RxV ^ RtV) == 0);
125
- infinp = float32_is_infinity(RxV) ||
126
- float32_is_infinity(RtV) ||
127
- float32_is_infinity(RsV);
128
- RxV = check_nan(RxV, RxV, &env->fp_status);
129
- RxV = check_nan(RxV, RsV, &env->fp_status);
130
- RxV = check_nan(RxV, RtV, &env->fp_status);
131
- float32 minus_RsV = float32_sub(float32_zero, RsV, &env->fp_status);
132
- tmp = internal_fmafx(minus_RsV, RtV, RxV, 0, &env->fp_status);
133
- if (!(float32_is_zero(RxV) && is_zero_prod(RsV, RtV))) {
134
- RxV = tmp;
135
- }
136
- set_float_exception_flags(0, &env->fp_status);
137
- if (float32_is_infinity(RxV) && !infinp) {
138
- RxV = RxV - 1;
139
- }
140
- if (infminusinf) {
141
- RxV = 0;
142
- }
143
- arch_fpop_end(env);
144
- return RxV;
145
+ return do_sffma_lib(env, RxV, RsV, RtV, float_muladd_negate_product);
60
}
146
}
61
147
62
void spr_read_tbu(DisasContext *ctx, int gprn, int sprn)
148
float64 HELPER(dfmpyfix)(CPUHexagonState *env, float64 RssV, float64 RttV)
63
{
64
- gen_icount_io_start(ctx);
65
+ translator_io_start(&ctx->base);
66
gen_helper_load_tbu(cpu_gpr[gprn], cpu_env);
67
}
68
69
@@ -XXX,XX +XXX,XX @@ void spr_read_atbu(DisasContext *ctx, int gprn, int sprn)
70
#if !defined(CONFIG_USER_ONLY)
71
void spr_write_tbl(DisasContext *ctx, int sprn, int gprn)
72
{
73
- gen_icount_io_start(ctx);
74
+ translator_io_start(&ctx->base);
75
gen_helper_store_tbl(cpu_env, cpu_gpr[gprn]);
76
}
77
78
void spr_write_tbu(DisasContext *ctx, int sprn, int gprn)
79
{
80
- gen_icount_io_start(ctx);
81
+ translator_io_start(&ctx->base);
82
gen_helper_store_tbu(cpu_env, cpu_gpr[gprn]);
83
}
84
85
@@ -XXX,XX +XXX,XX @@ void spr_write_atbu(DisasContext *ctx, int sprn, int gprn)
86
#if defined(TARGET_PPC64)
87
void spr_read_purr(DisasContext *ctx, int gprn, int sprn)
88
{
89
- gen_icount_io_start(ctx);
90
+ translator_io_start(&ctx->base);
91
gen_helper_load_purr(cpu_gpr[gprn], cpu_env);
92
}
93
94
void spr_write_purr(DisasContext *ctx, int sprn, int gprn)
95
{
96
- gen_icount_io_start(ctx);
97
+ translator_io_start(&ctx->base);
98
gen_helper_store_purr(cpu_env, cpu_gpr[gprn]);
99
}
100
101
/* HDECR */
102
void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn)
103
{
104
- gen_icount_io_start(ctx);
105
+ translator_io_start(&ctx->base);
106
gen_helper_load_hdecr(cpu_gpr[gprn], cpu_env);
107
}
108
109
void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
110
{
111
- gen_icount_io_start(ctx);
112
+ translator_io_start(&ctx->base);
113
gen_helper_store_hdecr(cpu_env, cpu_gpr[gprn]);
114
}
115
116
void spr_read_vtb(DisasContext *ctx, int gprn, int sprn)
117
{
118
- gen_icount_io_start(ctx);
119
+ translator_io_start(&ctx->base);
120
gen_helper_load_vtb(cpu_gpr[gprn], cpu_env);
121
}
122
123
void spr_write_vtb(DisasContext *ctx, int sprn, int gprn)
124
{
125
- gen_icount_io_start(ctx);
126
+ translator_io_start(&ctx->base);
127
gen_helper_store_vtb(cpu_env, cpu_gpr[gprn]);
128
}
129
130
void spr_write_tbu40(DisasContext *ctx, int sprn, int gprn)
131
{
132
- gen_icount_io_start(ctx);
133
+ translator_io_start(&ctx->base);
134
gen_helper_store_tbu40(cpu_env, cpu_gpr[gprn]);
135
}
136
137
@@ -XXX,XX +XXX,XX @@ void spr_write_dpdes(DisasContext *ctx, int sprn, int gprn)
138
#if !defined(CONFIG_USER_ONLY)
139
void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn)
140
{
141
- gen_icount_io_start(ctx);
142
+ translator_io_start(&ctx->base);
143
gen_helper_load_40x_pit(cpu_gpr[gprn], cpu_env);
144
}
145
146
void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn)
147
{
148
- gen_icount_io_start(ctx);
149
+ translator_io_start(&ctx->base);
150
gen_helper_store_40x_pit(cpu_env, cpu_gpr[gprn]);
151
}
152
153
void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn)
154
{
155
- gen_icount_io_start(ctx);
156
+ translator_io_start(&ctx->base);
157
gen_store_spr(sprn, cpu_gpr[gprn]);
158
gen_helper_store_40x_dbcr0(cpu_env, cpu_gpr[gprn]);
159
/* We must stop translation as we may have rebooted */
160
@@ -XXX,XX +XXX,XX @@ void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn)
161
162
void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn)
163
{
164
- gen_icount_io_start(ctx);
165
+ translator_io_start(&ctx->base);
166
gen_helper_store_40x_sler(cpu_env, cpu_gpr[gprn]);
167
}
168
169
void spr_write_40x_tcr(DisasContext *ctx, int sprn, int gprn)
170
{
171
- gen_icount_io_start(ctx);
172
+ translator_io_start(&ctx->base);
173
gen_helper_store_40x_tcr(cpu_env, cpu_gpr[gprn]);
174
}
175
176
void spr_write_40x_tsr(DisasContext *ctx, int sprn, int gprn)
177
{
178
- gen_icount_io_start(ctx);
179
+ translator_io_start(&ctx->base);
180
gen_helper_store_40x_tsr(cpu_env, cpu_gpr[gprn]);
181
}
182
183
@@ -XXX,XX +XXX,XX @@ void spr_write_40x_pid(DisasContext *ctx, int sprn, int gprn)
184
185
void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn)
186
{
187
- gen_icount_io_start(ctx);
188
+ translator_io_start(&ctx->base);
189
gen_helper_store_booke_tcr(cpu_env, cpu_gpr[gprn]);
190
}
191
192
void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn)
193
{
194
- gen_icount_io_start(ctx);
195
+ translator_io_start(&ctx->base);
196
gen_helper_store_booke_tsr(cpu_env, cpu_gpr[gprn]);
197
}
198
#endif
199
@@ -XXX,XX +XXX,XX @@ static void gen_darn(DisasContext *ctx)
200
if (l > 2) {
201
tcg_gen_movi_i64(cpu_gpr[rD(ctx->opcode)], -1);
202
} else {
203
- gen_icount_io_start(ctx);
204
+ translator_io_start(&ctx->base);
205
if (l == 0) {
206
gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
207
} else {
208
@@ -XXX,XX +XXX,XX @@ static void pmu_count_insns(DisasContext *ctx)
209
* running with icount and we do not handle it beforehand,
210
* the helper can trigger a 'bad icount read'.
211
*/
212
- gen_icount_io_start(ctx);
213
+ translator_io_start(&ctx->base);
214
215
/* Avoid helper calls when only PMC5-6 are enabled. */
216
if (!ctx->pmc_other) {
217
@@ -XXX,XX +XXX,XX @@ static void gen_rfi(DisasContext *ctx)
218
}
219
/* Restore CPU state */
220
CHK_SV(ctx);
221
- gen_icount_io_start(ctx);
222
+ translator_io_start(&ctx->base);
223
gen_update_cfar(ctx, ctx->cia);
224
gen_helper_rfi(cpu_env);
225
ctx->base.is_jmp = DISAS_EXIT;
226
@@ -XXX,XX +XXX,XX @@ static void gen_rfid(DisasContext *ctx)
227
#else
228
/* Restore CPU state */
229
CHK_SV(ctx);
230
- gen_icount_io_start(ctx);
231
+ translator_io_start(&ctx->base);
232
gen_update_cfar(ctx, ctx->cia);
233
gen_helper_rfid(cpu_env);
234
ctx->base.is_jmp = DISAS_EXIT;
235
@@ -XXX,XX +XXX,XX @@ static void gen_rfscv(DisasContext *ctx)
236
#else
237
/* Restore CPU state */
238
CHK_SV(ctx);
239
- gen_icount_io_start(ctx);
240
+ translator_io_start(&ctx->base);
241
gen_update_cfar(ctx, ctx->cia);
242
gen_helper_rfscv(cpu_env);
243
ctx->base.is_jmp = DISAS_EXIT;
244
@@ -XXX,XX +XXX,XX @@ static void gen_mtmsrd(DisasContext *ctx)
245
t0 = tcg_temp_new();
246
t1 = tcg_temp_new();
247
248
- gen_icount_io_start(ctx);
249
+ translator_io_start(&ctx->base);
250
251
if (ctx->opcode & 0x00010000) {
252
/* L=1 form only updates EE and RI */
253
@@ -XXX,XX +XXX,XX @@ static void gen_mtmsr(DisasContext *ctx)
254
t0 = tcg_temp_new();
255
t1 = tcg_temp_new();
256
257
- gen_icount_io_start(ctx);
258
+ translator_io_start(&ctx->base);
259
if (ctx->opcode & 0x00010000) {
260
/* L=1 form only updates EE and RI */
261
mask &= (1ULL << MSR_RI) | (1ULL << MSR_EE);
262
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
263
index XXXXXXX..XXXXXXX 100644
264
--- a/target/ppc/power8-pmu-regs.c.inc
265
+++ b/target/ppc/power8-pmu-regs.c.inc
266
@@ -XXX,XX +XXX,XX @@ static void write_MMCR0_common(DisasContext *ctx, TCGv val)
267
/*
268
* helper_store_mmcr0 will make clock based operations that
269
* will cause 'bad icount read' errors if we do not execute
270
- * gen_icount_io_start() beforehand.
271
+ * translator_io_start() beforehand.
272
*/
273
- gen_icount_io_start(ctx);
274
+ translator_io_start(&ctx->base);
275
gen_helper_store_mmcr0(cpu_env, val);
276
277
/*
278
@@ -XXX,XX +XXX,XX @@ void spr_read_PMC(DisasContext *ctx, int gprn, int sprn)
279
{
280
TCGv_i32 t_sprn = tcg_constant_i32(sprn);
281
282
- gen_icount_io_start(ctx);
283
+ translator_io_start(&ctx->base);
284
gen_helper_read_pmc(cpu_gpr[gprn], cpu_env, t_sprn);
285
}
286
287
@@ -XXX,XX +XXX,XX @@ void spr_write_PMC(DisasContext *ctx, int sprn, int gprn)
288
{
289
TCGv_i32 t_sprn = tcg_constant_i32(sprn);
290
291
- gen_icount_io_start(ctx);
292
+ translator_io_start(&ctx->base);
293
gen_helper_store_pmc(cpu_env, t_sprn, cpu_gpr[gprn]);
294
}
295
296
@@ -XXX,XX +XXX,XX @@ void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn)
297
298
void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn)
299
{
300
- gen_icount_io_start(ctx);
301
+ translator_io_start(&ctx->base);
302
gen_helper_store_mmcr1(cpu_env, cpu_gpr[gprn]);
303
}
304
#else
305
diff --git a/target/ppc/translate/branch-impl.c.inc b/target/ppc/translate/branch-impl.c.inc
306
index XXXXXXX..XXXXXXX 100644
307
--- a/target/ppc/translate/branch-impl.c.inc
308
+++ b/target/ppc/translate/branch-impl.c.inc
309
@@ -XXX,XX +XXX,XX @@ static bool trans_RFEBB(DisasContext *ctx, arg_XL_s *arg)
310
{
311
REQUIRE_INSNS_FLAGS2(ctx, ISA207S);
312
313
- gen_icount_io_start(ctx);
314
+ translator_io_start(&ctx->base);
315
gen_update_cfar(ctx, ctx->cia);
316
gen_helper_rfebb(cpu_env, cpu_gpr[arg->s]);
317
318
--
149
--
319
2.34.1
150
2.43.0
320
321
diff view generated by jsdifflib
1
This had been pulled in from tcg/tcg.h, via exec/cpu_ldst.h,
1
The function is now unused.
2
via exec/exec-all.h, but the include of tcg.h will be removed.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
5
---
7
target/avr/cpu.c | 1 +
6
target/hexagon/fma_emu.h | 2 -
8
target/rx/cpu.c | 1 +
7
target/hexagon/fma_emu.c | 171 ---------------------------------------
9
target/rx/op_helper.c | 1 +
8
2 files changed, 173 deletions(-)
10
target/tricore/cpu.c | 1 +
11
4 files changed, 4 insertions(+)
12
9
13
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
10
diff --git a/target/hexagon/fma_emu.h b/target/hexagon/fma_emu.h
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/target/avr/cpu.c
12
--- a/target/hexagon/fma_emu.h
16
+++ b/target/avr/cpu.c
13
+++ b/target/hexagon/fma_emu.h
17
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float32_getexp_raw(float32 f32)
18
#include "exec/exec-all.h"
15
}
19
#include "cpu.h"
16
int32_t float32_getexp(float32 f32);
20
#include "disas/dis-asm.h"
17
float32 infinite_float32(uint8_t sign);
21
+#include "tcg/debug-assert.h"
18
-float32 internal_fmafx(float32 a, float32 b, float32 c,
22
19
- int scale, float_status *fp_status);
23
static void avr_cpu_set_pc(CPUState *cs, vaddr value)
20
float64 internal_mpyhh(float64 a, float64 b,
21
unsigned long long int accumulated,
22
float_status *fp_status);
23
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/hexagon/fma_emu.c
26
+++ b/target/hexagon/fma_emu.c
27
@@ -XXX,XX +XXX,XX @@ int32_t float64_getexp(float64 f64)
28
return -1;
29
}
30
31
-static uint64_t float32_getmant(float32 f32)
32
-{
33
- Float a = { .i = f32 };
34
- if (float32_is_normal(f32)) {
35
- return a.mant | 1ULL << 23;
36
- }
37
- if (float32_is_zero(f32)) {
38
- return 0;
39
- }
40
- if (float32_is_denormal(f32)) {
41
- return a.mant;
42
- }
43
- return ~0ULL;
44
-}
45
-
46
int32_t float32_getexp(float32 f32)
24
{
47
{
25
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
48
Float a = { .i = f32 };
26
index XXXXXXX..XXXXXXX 100644
49
@@ -XXX,XX +XXX,XX @@ float32 infinite_float32(uint8_t sign)
27
--- a/target/rx/cpu.c
50
}
28
+++ b/target/rx/cpu.c
51
29
@@ -XXX,XX +XXX,XX @@
52
/* Return a maximum finite value with the requested sign */
30
#include "exec/exec-all.h"
53
-static float32 maxfinite_float32(uint8_t sign)
31
#include "hw/loader.h"
54
-{
32
#include "fpu/softfloat.h"
55
- if (sign) {
33
+#include "tcg/debug-assert.h"
56
- return make_float32(SF_MINUS_MAXF);
34
57
- } else {
35
static void rx_cpu_set_pc(CPUState *cs, vaddr value)
58
- return make_float32(SF_MAXF);
36
{
59
- }
37
diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
60
-}
38
index XXXXXXX..XXXXXXX 100644
61
-
39
--- a/target/rx/op_helper.c
62
-/* Return a zero value with requested sign */
40
+++ b/target/rx/op_helper.c
63
-static float32 zero_float32(uint8_t sign)
41
@@ -XXX,XX +XXX,XX @@
64
-{
42
#include "exec/helper-proto.h"
65
- if (sign) {
43
#include "exec/cpu_ldst.h"
66
- return make_float32(0x80000000);
44
#include "fpu/softfloat.h"
67
- } else {
45
+#include "tcg/debug-assert.h"
68
- return float32_zero;
46
69
- }
47
static inline G_NORETURN
70
-}
48
void raise_exception(CPURXState *env, int index,
71
-
49
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
72
#define GEN_XF_ROUND(SUFFIX, MANTBITS, INF_EXP, INTERNAL_TYPE) \
50
index XXXXXXX..XXXXXXX 100644
73
static SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \
51
--- a/target/tricore/cpu.c
74
{ \
52
+++ b/target/tricore/cpu.c
75
@@ -XXX,XX +XXX,XX @@ static SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \
53
@@ -XXX,XX +XXX,XX @@
76
}
54
#include "cpu.h"
77
55
#include "exec/exec-all.h"
78
GEN_XF_ROUND(float64, DF_MANTBITS, DF_INF_EXP, Double)
56
#include "qemu/error-report.h"
79
-GEN_XF_ROUND(float32, SF_MANTBITS, SF_INF_EXP, Float)
57
+#include "tcg/debug-assert.h"
80
-
58
81
-static bool is_inf_prod(float64 a, float64 b)
59
static inline void set_feature(CPUTriCoreState *env, int feature)
82
-{
60
{
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,
61
--
219
--
62
2.34.1
220
2.43.0
63
64
diff view generated by jsdifflib
1
The symbol is always defined, even if to 0. We wanted to test for
1
This massive macro is now only used once.
2
TCG_OVERSIZED_GUEST == 0.
2
Expand it for use only by float64.
3
3
4
This fixed, the #error is reached while building arm-softmmu, because
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
5
TCG_OVERSIZED_GUEST is not true (nor supposed to be true) for arm32
6
guest on a 32-bit host. But that's ok, because this feature doesn't
7
apply to arm32. Add an #ifdef for TARGET_AARCH64.
8
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
6
---
12
target/arm/ptw.c | 7 ++++++-
7
target/hexagon/fma_emu.c | 255 +++++++++++++++++++--------------------
13
1 file changed, 6 insertions(+), 1 deletion(-)
8
1 file changed, 127 insertions(+), 128 deletions(-)
14
9
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/ptw.c
12
--- a/target/hexagon/fma_emu.c
18
+++ b/target/arm/ptw.c
13
+++ b/target/hexagon/fma_emu.c
19
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
14
@@ -XXX,XX +XXX,XX @@ float32 infinite_float32(uint8_t sign)
20
uint64_t new_val, S1Translate *ptw,
21
ARMMMUFaultInfo *fi)
22
{
23
+#ifdef TARGET_AARCH64
24
uint64_t cur_val;
25
void *host = ptw->out_host;
26
27
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
28
* we know that TCG_OVERSIZED_GUEST is set, which means that we are
29
* running in round-robin mode and could only race with dma i/o.
30
*/
31
-#ifndef TCG_OVERSIZED_GUEST
32
+#if !TCG_OVERSIZED_GUEST
33
# error "Unexpected configuration"
34
#endif
35
bool locked = qemu_mutex_iothread_locked();
36
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
37
#endif
38
39
return cur_val;
40
+#else
41
+ /* AArch32 does not have FEAT_HADFS. */
42
+ g_assert_not_reached();
43
+#endif
44
}
15
}
45
16
46
static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
17
/* Return a maximum finite value with the requested sign */
18
-#define GEN_XF_ROUND(SUFFIX, MANTBITS, INF_EXP, INTERNAL_TYPE) \
19
-static SUFFIX accum_round_##SUFFIX(Accum a, float_status * fp_status) \
20
-{ \
21
- if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0) \
22
- && ((a.guard | a.round | a.sticky) == 0)) { \
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;
271
}
272
273
-GEN_XF_ROUND(float64, DF_MANTBITS, DF_INF_EXP, Double)
274
-
275
float64 internal_mpyhh(float64 a, float64 b,
276
unsigned long long int accumulated,
277
float_status *fp_status)
47
--
278
--
48
2.34.1
279
2.43.0
49
50
diff view generated by jsdifflib
1
Removes the only use of TARGET_LONG_BITS from tcg.h, which is to be
1
This structure, with bitfields, is incorrect for big-endian.
2
target independent. Move the symbol to a define in tcg-op.h, which
2
Use the existing float32_getexp_raw which uses extract32.
3
will continue to be target dependent. Rather than complicate matters
4
for the use in tb_gen_code(), expand the definition there.
5
3
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
6
---
9
include/tcg/tcg-op.h | 8 ++++++++
7
target/hexagon/fma_emu.c | 16 +++-------------
10
include/tcg/tcg.h | 7 -------
8
1 file changed, 3 insertions(+), 13 deletions(-)
11
accel/tcg/translate-all.c | 2 +-
12
3 files changed, 9 insertions(+), 8 deletions(-)
13
9
14
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/include/tcg/tcg-op.h
12
--- a/target/hexagon/fma_emu.c
17
+++ b/include/tcg/tcg-op.h
13
+++ b/target/hexagon/fma_emu.c
18
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_concat32_i64(TCGv_i64 ret, TCGv_i64 lo, TCGv_i64 hi)
14
@@ -XXX,XX +XXX,XX @@ typedef union {
19
#error must include QEMU headers
15
};
20
#endif
16
} Double;
21
17
22
+#if TARGET_LONG_BITS == 32
18
-typedef union {
23
+# define TCG_TYPE_TL TCG_TYPE_I32
19
- float f;
24
+#elif TARGET_LONG_BITS == 64
20
- uint32_t i;
25
+# define TCG_TYPE_TL TCG_TYPE_I64
21
- struct {
26
+#else
22
- uint32_t mant:23;
27
+# error
23
- uint32_t exp:8;
28
+#endif
24
- uint32_t sign:1;
29
+
25
- };
30
#if TARGET_INSN_START_WORDS == 1
26
-} Float;
31
static inline void tcg_gen_insn_start(target_ulong pc)
27
-
28
static uint64_t float64_getmant(float64 f64)
32
{
29
{
33
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
30
Double a = { .i = f64 };
34
index XXXXXXX..XXXXXXX 100644
31
@@ -XXX,XX +XXX,XX @@ int32_t float64_getexp(float64 f64)
35
--- a/include/tcg/tcg.h
32
36
+++ b/include/tcg/tcg.h
33
int32_t float32_getexp(float32 f32)
37
@@ -XXX,XX +XXX,XX @@ typedef enum TCGType {
34
{
38
#else
35
- Float a = { .i = f32 };
39
TCG_TYPE_PTR = TCG_TYPE_I64,
36
+ int exp = float32_getexp_raw(f32);
40
#endif
37
if (float32_is_normal(f32)) {
41
-
38
- return a.exp;
42
- /* An alias for the size of the target "long", aka register. */
39
+ return exp;
43
-#if TARGET_LONG_BITS == 64
40
}
44
- TCG_TYPE_TL = TCG_TYPE_I64,
41
if (float32_is_denormal(f32)) {
45
-#else
42
- return a.exp + 1;
46
- TCG_TYPE_TL = TCG_TYPE_I32,
43
+ return exp + 1;
47
-#endif
44
}
48
} TCGType;
45
return -1;
49
46
}
50
/**
51
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/accel/tcg/translate-all.c
54
+++ b/accel/tcg/translate-all.c
55
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
56
tb_set_page_addr0(tb, phys_pc);
57
tb_set_page_addr1(tb, -1);
58
tcg_ctx->gen_tb = tb;
59
- tcg_ctx->addr_type = TCG_TYPE_TL;
60
+ tcg_ctx->addr_type = TARGET_LONG_BITS == 32 ? TCG_TYPE_I32 : TCG_TYPE_I64;
61
#ifdef CONFIG_SOFTMMU
62
tcg_ctx->page_bits = TARGET_PAGE_BITS;
63
tcg_ctx->page_mask = TARGET_PAGE_MASK;
64
--
47
--
65
2.34.1
48
2.43.0
66
67
diff view generated by jsdifflib
1
This had been pulled in from tcg/tcg.h, via exec/cpu_ldst.h,
1
This structure, with bitfields, is incorrect for big-endian.
2
via exec/exec-all.h, but the include of tcg.h will be removed.
2
Use extract64 and deposit64 instead.
3
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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
target/avr/helper.c | 1 +
7
target/hexagon/fma_emu.c | 46 ++++++++++++++--------------------------
8
1 file changed, 1 insertion(+)
8
1 file changed, 16 insertions(+), 30 deletions(-)
9
9
10
diff --git a/target/avr/helper.c b/target/avr/helper.c
10
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
11
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/avr/helper.c
12
--- a/target/hexagon/fma_emu.c
13
+++ b/target/avr/helper.c
13
+++ b/target/hexagon/fma_emu.c
14
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@
15
15
16
#include "qemu/osdep.h"
16
#define WAY_BIG_EXP 4096
17
#include "qemu/log.h"
17
18
+#include "qemu/error-report.h"
18
-typedef union {
19
#include "cpu.h"
19
- double f;
20
#include "hw/core/tcg-cpu-ops.h"
20
- uint64_t i;
21
#include "exec/exec-all.h"
21
- struct {
22
- uint64_t mant:52;
23
- uint64_t exp:11;
24
- uint64_t sign:1;
25
- };
26
-} Double;
27
-
28
static uint64_t float64_getmant(float64 f64)
29
{
30
- Double a = { .i = f64 };
31
+ uint64_t mant = extract64(f64, 0, 52);
32
if (float64_is_normal(f64)) {
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;
44
}
45
46
int32_t float64_getexp(float64 f64)
47
{
48
- Double a = { .i = f64 };
49
+ int exp = extract64(f64, 52, 11);
50
if (float64_is_normal(f64)) {
51
- return a.exp;
52
+ return exp;
53
}
54
if (float64_is_denormal(f64)) {
55
- return a.exp + 1;
56
+ return exp + 1;
57
}
58
return -1;
59
}
60
@@ -XXX,XX +XXX,XX @@ float32 infinite_float32(uint8_t sign)
61
/* Return a maximum finite value with the requested sign */
62
static float64 accum_round_float64(Accum a, float_status *fp_status)
63
{
64
+ uint64_t ret;
65
+
66
if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0)
67
&& ((a.guard | a.round | a.sticky) == 0)) {
68
/* result zero */
69
@@ -XXX,XX +XXX,XX @@ static float64 accum_round_float64(Accum a, float_status *fp_status)
70
}
71
}
72
/* Underflow? */
73
- if (int128_getlo(a.mant) & (1ULL << DF_MANTBITS)) {
74
+ ret = int128_getlo(a.mant);
75
+ if (ret & (1ULL << DF_MANTBITS)) {
76
/* Leading one means: No, we're normal. So, we should be done... */
77
- Double ret;
78
- ret.i = 0;
79
- ret.sign = a.sign;
80
- ret.exp = a.exp;
81
- ret.mant = int128_getlo(a.mant);
82
- return ret.i;
83
+ ret = deposit64(ret, 52, 11, a.exp);
84
+ } else {
85
+ assert(a.exp == 1);
86
+ ret = deposit64(ret, 52, 11, 0);
87
}
88
- assert(a.exp == 1);
89
- Double ret;
90
- ret.i = 0;
91
- ret.sign = a.sign;
92
- ret.exp = 0;
93
- ret.mant = int128_getlo(a.mant);
94
- return ret.i;
95
+ ret = deposit64(ret, 63, 1, a.sign);
96
+ return ret;
97
}
98
99
float64 internal_mpyhh(float64 a, float64 b,
22
--
100
--
23
2.34.1
101
2.43.0
24
25
diff view generated by jsdifflib
1
Removes a multiplicity of calls to __assert_fail, saving up
1
No need to open-code 64x64->128-bit multiplication.
2
to 360kiB of .text space as measured on an x86_64 host.
3
2
4
Old New Less %Change
3
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
5
9257272    8888680    368592    3.98%    qemu-system-aarch64
6
6100968    5911832    189136    3.10%    qemu-system-riscv64
7
5839112    5707032    132080    2.26%    qemu-system-mips
8
4447608    4341752    105856    2.38%    qemu-system-s390x
9
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
5
---
13
include/tcg/tcg.h | 30 ++++++++++++++++--------------
6
target/hexagon/fma_emu.c | 32 +++-----------------------------
14
tcg/tcg.c | 19 +++++++++++++++++++
7
1 file changed, 3 insertions(+), 29 deletions(-)
15
2 files changed, 35 insertions(+), 14 deletions(-)
16
8
17
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
9
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c
18
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
19
--- a/include/tcg/tcg.h
11
--- a/target/hexagon/fma_emu.c
20
+++ b/include/tcg/tcg.h
12
+++ b/target/hexagon/fma_emu.c
21
@@ -XXX,XX +XXX,XX @@ static inline void *tcg_splitwx_to_rw(const void *rx)
13
@@ -XXX,XX +XXX,XX @@ int32_t float32_getexp(float32 f32)
14
return -1;
22
}
15
}
23
#endif
16
24
17
-static uint32_t int128_getw0(Int128 x)
25
-static inline size_t temp_idx(TCGTemp *ts)
26
-{
18
-{
27
- ptrdiff_t n = ts - tcg_ctx->temps;
19
- return int128_getlo(x);
28
- tcg_debug_assert(n >= 0 && n < tcg_ctx->nb_temps);
29
- return n;
30
-}
20
-}
31
-
21
-
32
static inline TCGArg temp_arg(TCGTemp *ts)
22
-static uint32_t int128_getw1(Int128 x)
23
-{
24
- return int128_getlo(x) >> 32;
25
-}
26
-
27
static Int128 int128_mul_6464(uint64_t ai, uint64_t bi)
33
{
28
{
34
return (uintptr_t)ts;
29
- Int128 a, b;
35
@@ -XXX,XX +XXX,XX @@ static inline TCGTemp *arg_temp(TCGArg a)
30
- uint64_t pp0, pp1a, pp1b, pp1s, pp2;
36
return (TCGTemp *)(uintptr_t)a;
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
-
40
- pp1s = pp1a + pp1b;
41
- if ((pp1s < pp1a) || (pp1s < pp1b)) {
42
- pp2 += (1ULL << 32);
43
- }
44
- uint64_t ret_low = pp0 + (pp1s << 32);
45
- if ((ret_low < pp0) || (ret_low < (pp1s << 32))) {
46
- pp2 += 1;
47
- }
48
-
49
- return int128_make128(ret_low, pp2 + (pp1s >> 32));
50
+ mulu64(&l, &h, ai, bi);
51
+ return int128_make128(l, h);
37
}
52
}
38
53
39
-/* Using the offset of a temporary, relative to TCGContext, rather than
54
static Int128 int128_sub_borrow(Int128 a, Int128 b, int borrow)
40
- its index means that we don't use 0. That leaves offset 0 free for
41
- a NULL representation without having to leave index 0 unused. */
42
+#ifdef CONFIG_DEBUG_TCG
43
+size_t temp_idx(TCGTemp *ts);
44
+TCGTemp *tcgv_i32_temp(TCGv_i32 v);
45
+#else
46
+static inline size_t temp_idx(TCGTemp *ts)
47
+{
48
+ return ts - tcg_ctx->temps;
49
+}
50
+
51
+/*
52
+ * Using the offset of a temporary, relative to TCGContext, rather than
53
+ * its index means that we don't use 0. That leaves offset 0 free for
54
+ * a NULL representation without having to leave index 0 unused.
55
+ */
56
static inline TCGTemp *tcgv_i32_temp(TCGv_i32 v)
57
{
58
- uintptr_t o = (uintptr_t)v;
59
- TCGTemp *t = (void *)tcg_ctx + o;
60
- tcg_debug_assert(offsetof(TCGContext, temps[temp_idx(t)]) == o);
61
- return t;
62
+ return (void *)tcg_ctx + (uintptr_t)v;
63
}
64
+#endif
65
66
static inline TCGTemp *tcgv_i64_temp(TCGv_i64 v)
67
{
68
diff --git a/tcg/tcg.c b/tcg/tcg.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/tcg/tcg.c
71
+++ b/tcg/tcg.c
72
@@ -XXX,XX +XXX,XX @@ TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val)
73
return tcg_constant_vec(t->base_type, vece, val);
74
}
75
76
+#ifdef CONFIG_DEBUG_TCG
77
+size_t temp_idx(TCGTemp *ts)
78
+{
79
+ ptrdiff_t n = ts - tcg_ctx->temps;
80
+ assert(n >= 0 && n < tcg_ctx->nb_temps);
81
+ return n;
82
+}
83
+
84
+TCGTemp *tcgv_i32_temp(TCGv_i32 v)
85
+{
86
+ uintptr_t o = (uintptr_t)v - offsetof(TCGContext, temps);
87
+
88
+ assert(o < sizeof(TCGTemp) * tcg_ctx->nb_temps);
89
+ assert(o % sizeof(TCGTemp) == 0);
90
+
91
+ return (void *)tcg_ctx + (uintptr_t)v;
92
+}
93
+#endif /* CONFIG_DEBUG_TCG */
94
+
95
/* Return true if OP may appear in the opcode stream.
96
Test the runtime variable that controls each opcode. */
97
bool tcg_op_supported(TCGOpcode op)
98
--
55
--
99
2.34.1
56
2.43.0
100
101
diff view generated by jsdifflib
1
All uses replaced with TCGContext.addr_type.
1
Initialize x with accumulated via direct assignment,
2
rather than multiplying by 1.
2
3
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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/sparc64/tcg-target.c.inc | 7 ++++---
7
target/hexagon/fma_emu.c | 2 +-
7
1 file changed, 4 insertions(+), 3 deletions(-)
8
1 file changed, 1 insertion(+), 1 deletion(-)
8
9
9
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/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/sparc64/tcg-target.c.inc
12
--- a/target/hexagon/fma_emu.c
12
+++ b/tcg/sparc64/tcg-target.c.inc
13
+++ b/target/hexagon/fma_emu.c
13
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
14
@@ -XXX,XX +XXX,XX @@ float64 internal_mpyhh(float64 a, float64 b,
14
TCGReg addr_reg, MemOpIdx oi,
15
float64_is_infinity(b)) {
15
bool is_ld)
16
return float64_mul(a, b, fp_status);
16
{
17
}
17
+ TCGType addr_type = s->addr_type;
18
- x.mant = int128_mul_6464(accumulated, 1);
18
TCGLabelQemuLdst *ldst = NULL;
19
+ x.mant = int128_make64(accumulated);
19
MemOp opc = get_memop(oi);
20
x.sticky = sticky;
20
MemOp s_bits = opc & MO_SIZE;
21
prod = fGETUWORD(1, float64_getmant(a)) * fGETUWORD(1, float64_getmant(b));
21
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
22
x.mant = int128_add(x.mant, int128_mul_6464(prod, 0x100000000ULL));
22
tcg_out_arith(s, TCG_REG_T1, TCG_REG_T1, TCG_REG_T3, ARITH_ADD);
23
24
/* Load the tlb comparator and the addend. */
25
- tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_T2, TCG_REG_T1, cmp_off);
26
+ tcg_out_ld(s, addr_type, TCG_REG_T2, TCG_REG_T1, cmp_off);
27
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_T1, TCG_REG_T1, add_off);
28
h->base = TCG_REG_T1;
29
30
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
31
ldst->label_ptr[0] = s->code_ptr;
32
33
/* bne,pn %[xi]cc, label0 */
34
- cc = TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC;
35
+ cc = addr_type == TCG_TYPE_I32 ? BPCC_ICC : BPCC_XCC;
36
tcg_out_bpcc0(s, COND_NE, BPCC_PN | cc, 0);
37
#else
38
/*
39
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
40
#endif
41
42
/* If the guest address must be zero-extended, do in the delay slot. */
43
- if (TARGET_LONG_BITS == 32) {
44
+ if (addr_type == TCG_TYPE_I32) {
45
tcg_out_ext32u(s, TCG_REG_T2, addr_reg);
46
h->index = TCG_REG_T2;
47
} else {
48
--
23
--
49
2.34.1
24
2.43.0
50
51
diff view generated by jsdifflib
1
In preparation for compiling tcg/ only once, eliminate
1
Convert all targets simultaneously, as the gen_intermediate_code
2
the all_helpers array. Instantiate the info structs for
2
function disappears from the target. While there are possible
3
the generic helpers in accel/tcg/, and the structs for
3
workarounds, they're larger than simply performing the conversion.
4
the target-specific helpers in each translate.c.
5
4
6
Since we don't see all of the info structs at startup,
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
initialize at first use, using g_once_init_* to make
8
sure we don't race while doing so.
9
10
Reviewed-by: Anton Johansson <anjo@rev.ng>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
7
---
13
MAINTAINERS | 1 +
8
include/exec/translator.h | 14 --------------
14
include/exec/helper-gen.h | 66 ++++++++++++--------
9
include/hw/core/tcg-cpu-ops.h | 13 +++++++++++++
15
include/exec/helper-tcg.h | 75 -----------------------
10
target/alpha/cpu.h | 2 ++
16
include/qemu/typedefs.h | 1 +
11
target/arm/internals.h | 2 ++
17
include/tcg/helper-info.h | 9 ++-
12
target/avr/cpu.h | 2 ++
18
include/tcg/tcg.h | 2 +-
13
target/hexagon/cpu.h | 2 ++
19
accel/tcg/plugin-gen.c | 5 ++
14
target/hppa/cpu.h | 2 ++
20
accel/tcg/tcg-runtime.c | 4 ++
15
target/i386/tcg/helper-tcg.h | 2 ++
21
target/alpha/translate.c | 3 +
16
target/loongarch/internals.h | 2 ++
22
target/arm/tcg/translate.c | 3 +
17
target/m68k/cpu.h | 2 ++
23
target/avr/translate.c | 5 ++
18
target/microblaze/cpu.h | 2 ++
24
target/cris/translate.c | 6 +-
19
target/mips/tcg/tcg-internal.h | 2 ++
25
target/hexagon/translate.c | 4 ++
20
target/openrisc/cpu.h | 2 ++
26
target/hppa/translate.c | 5 ++
21
target/ppc/cpu.h | 2 ++
27
target/i386/tcg/translate.c | 5 ++
22
target/riscv/cpu.h | 3 +++
28
target/loongarch/translate.c | 4 ++
23
target/rx/cpu.h | 2 ++
29
target/m68k/translate.c | 3 +
24
target/s390x/s390x-internal.h | 2 ++
30
target/microblaze/translate.c | 4 ++
25
target/sh4/cpu.h | 2 ++
31
target/mips/tcg/translate.c | 5 ++
26
target/sparc/cpu.h | 2 ++
32
target/nios2/translate.c | 5 ++
27
target/tricore/cpu.h | 2 ++
33
target/openrisc/translate.c | 5 ++
28
target/xtensa/cpu.h | 2 ++
34
target/ppc/translate.c | 4 ++
29
accel/tcg/cpu-exec.c | 8 +++++---
35
target/riscv/translate.c | 4 ++
30
accel/tcg/translate-all.c | 8 +++++---
36
target/rx/translate.c | 5 ++
31
target/alpha/cpu.c | 1 +
37
target/s390x/tcg/translate.c | 4 ++
32
target/alpha/translate.c | 4 ++--
38
target/sh4/translate.c | 4 ++
33
target/arm/cpu.c | 1 +
39
target/sparc/translate.c | 3 +
34
target/arm/tcg/cpu-v7m.c | 1 +
40
target/tricore/translate.c | 5 ++
35
target/arm/tcg/translate.c | 5 ++---
41
target/xtensa/translate.c | 4 ++
36
target/avr/cpu.c | 1 +
42
tcg/tcg.c | 108 ++++++++++++---------------------
37
target/avr/translate.c | 6 +++---
43
include/exec/helper-info.c.inc | 96 +++++++++++++++++++++++++++++
38
target/hexagon/cpu.c | 1 +
44
31 files changed, 282 insertions(+), 175 deletions(-)
39
target/hexagon/translate.c | 4 ++--
45
delete mode 100644 include/exec/helper-tcg.h
40
target/hppa/cpu.c | 1 +
46
create mode 100644 include/exec/helper-info.c.inc
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(-)
47
71
48
diff --git a/MAINTAINERS b/MAINTAINERS
72
diff --git a/include/exec/translator.h b/include/exec/translator.h
49
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
50
--- a/MAINTAINERS
74
--- a/include/exec/translator.h
51
+++ b/MAINTAINERS
75
+++ b/include/exec/translator.h
52
@@ -XXX,XX +XXX,XX @@ F: include/exec/exec-all.h
53
F: include/exec/tb-flush.h
54
F: include/exec/target_long.h
55
F: include/exec/helper*.h
56
+F: include/exec/helper-info.c.inc
57
F: include/sysemu/cpus.h
58
F: include/sysemu/tcg.h
59
F: include/hw/core/tcg-cpu-ops.h
60
diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/include/exec/helper-gen.h
63
+++ b/include/exec/helper-gen.h
64
@@ -XXX,XX +XXX,XX @@
76
@@ -XXX,XX +XXX,XX @@
65
-/* Helper file for declaring TCG helper functions.
77
#include "qemu/bswap.h"
66
- This one expands generation functions for tcg opcodes. */
78
#include "exec/vaddr.h"
67
+/* SPDX-License-Identifier: GPL-2.0-or-later */
79
68
+/*
80
-/**
69
+ * Helper file for declaring TCG helper functions.
81
- * gen_intermediate_code
70
+ * This one expands generation functions for tcg opcodes.
82
- * @cpu: cpu context
71
+ * Define HELPER_H for the header file to be expanded,
83
- * @tb: translation block
72
+ * and static inline to change from global file scope.
84
- * @max_insns: max number of instructions to translate
73
+ */
85
- * @pc: guest virtual program counter address
74
86
- * @host_pc: host physical program counter address
75
#ifndef HELPER_GEN_H
87
- *
76
#define HELPER_GEN_H
88
- * This function must be provided by the target, which should create
77
89
- * the target-specific DisasContext, and then invoke translator_loop.
78
+#include "tcg/tcg.h"
90
- */
79
+#include "tcg/helper-info.h"
91
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
80
#include "exec/helper-head.h"
92
- vaddr pc, void *host_pc);
81
93
-
82
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
94
/**
83
+extern TCGHelperInfo glue(helper_info_, name); \
95
* DisasJumpType:
84
static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
96
* @DISAS_NEXT: Next instruction in program order.
85
{ \
97
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
86
- tcg_gen_callN(HELPER(name), dh_retvar(ret), 0, NULL); \
98
index XXXXXXX..XXXXXXX 100644
87
+ tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 0, NULL); \
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)
88
}
152
}
89
153
90
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
154
void avr_cpu_tcg_init(void);
91
+extern TCGHelperInfo glue(helper_info_, name); \
155
+void avr_cpu_translate_code(CPUState *cs, TranslationBlock *tb,
92
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
156
+ int *max_insns, vaddr pc, void *host_pc);
93
dh_arg_decl(t1, 1)) \
157
94
{ \
158
int cpu_avr_exec(CPUState *cpu);
95
- TCGTemp *args[1] = { dh_arg(t1, 1) }; \
159
96
- tcg_gen_callN(HELPER(name), dh_retvar(ret), 1, args); \
160
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
97
+ TCGTemp *args[1] = { dh_arg(t1, 1) }; \
161
index XXXXXXX..XXXXXXX 100644
98
+ tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 1, args); \
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)
99
}
178
}
100
179
101
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
180
void hppa_translate_init(void);
102
+extern TCGHelperInfo glue(helper_info_, name); \
181
+void hppa_translate_code(CPUState *cs, TranslationBlock *tb,
103
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
182
+ int *max_insns, vaddr pc, void *host_pc);
104
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2)) \
183
105
{ \
184
#define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
106
- TCGTemp *args[2] = { dh_arg(t1, 1), dh_arg(t2, 2) }; \
185
107
- tcg_gen_callN(HELPER(name), dh_retvar(ret), 2, args); \
186
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
108
+ TCGTemp *args[2] = { dh_arg(t1, 1), dh_arg(t2, 2) }; \
187
index XXXXXXX..XXXXXXX 100644
109
+ tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 2, args); \
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)
110
}
230
}
111
231
112
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
232
void mb_tcg_init(void);
113
+extern TCGHelperInfo glue(helper_info_, name); \
233
+void mb_translate_code(CPUState *cs, TranslationBlock *tb,
114
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
234
+ int *max_insns, vaddr pc, void *host_pc);
115
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
235
116
{ \
236
#define CPU_RESOLVING_TYPE TYPE_MICROBLAZE_CPU
117
- TCGTemp *args[3] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3) }; \
237
118
- tcg_gen_callN(HELPER(name), dh_retvar(ret), 3, args); \
238
diff --git a/target/mips/tcg/tcg-internal.h b/target/mips/tcg/tcg-internal.h
119
+ TCGTemp *args[3] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3) }; \
239
index XXXXXXX..XXXXXXX 100644
120
+ tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 3, args); \
240
--- a/target/mips/tcg/tcg-internal.h
121
}
241
+++ b/target/mips/tcg/tcg-internal.h
122
123
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
124
+extern TCGHelperInfo glue(helper_info_, name); \
125
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
126
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), \
127
dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
128
{ \
129
- TCGTemp *args[4] = { dh_arg(t1, 1), dh_arg(t2, 2), \
130
- dh_arg(t3, 3), dh_arg(t4, 4) }; \
131
- tcg_gen_callN(HELPER(name), dh_retvar(ret), 4, args); \
132
+ TCGTemp *args[4] = { dh_arg(t1, 1), dh_arg(t2, 2), \
133
+ dh_arg(t3, 3), dh_arg(t4, 4) }; \
134
+ tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 4, args); \
135
}
136
137
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
138
+extern TCGHelperInfo glue(helper_info_, name); \
139
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
140
- dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
141
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
142
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
143
{ \
144
- TCGTemp *args[5] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
145
- dh_arg(t4, 4), dh_arg(t5, 5) }; \
146
- tcg_gen_callN(HELPER(name), dh_retvar(ret), 5, args); \
147
+ TCGTemp *args[5] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
148
+ dh_arg(t4, 4), dh_arg(t5, 5) }; \
149
+ tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 5, args); \
150
}
151
152
#define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \
153
+extern TCGHelperInfo glue(helper_info_, name); \
154
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
155
- dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
156
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
157
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6)) \
158
{ \
159
- TCGTemp *args[6] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
160
- dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6) }; \
161
- tcg_gen_callN(HELPER(name), dh_retvar(ret), 6, args); \
162
+ TCGTemp *args[6] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
163
+ dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6) }; \
164
+ tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 6, args); \
165
}
166
167
#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7)\
168
+extern TCGHelperInfo glue(helper_info_, name); \
169
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
170
- dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
171
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
172
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6), \
173
dh_arg_decl(t7, 7)) \
174
{ \
175
- TCGTemp *args[7] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
176
- dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \
177
- dh_arg(t7, 7) }; \
178
- tcg_gen_callN(HELPER(name), dh_retvar(ret), 7, args); \
179
+ TCGTemp *args[7] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
180
+ dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \
181
+ dh_arg(t7, 7) }; \
182
+ tcg_gen_callN(&glue(helper_info_, name), dh_retvar(ret), 7, args); \
183
}
184
185
#include "helper.h"
186
@@ -XXX,XX +XXX,XX @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
187
#undef DEF_HELPER_FLAGS_5
188
#undef DEF_HELPER_FLAGS_6
189
#undef DEF_HELPER_FLAGS_7
190
-#undef GEN_HELPER
191
192
#endif /* HELPER_GEN_H */
193
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
194
deleted file mode 100644
195
index XXXXXXX..XXXXXXX
196
--- a/include/exec/helper-tcg.h
197
+++ /dev/null
198
@@ -XXX,XX +XXX,XX @@
242
@@ -XXX,XX +XXX,XX @@
199
-/* Helper file for declaring TCG helper functions.
243
#include "cpu.h"
200
- This one defines data structures private to tcg.c. */
244
201
-
245
void mips_tcg_init(void);
202
-#ifndef HELPER_TCG_H
246
+void mips_translate_code(CPUState *cs, TranslationBlock *tb,
203
-#define HELPER_TCG_H
247
+ int *max_insns, vaddr pc, void *host_pc);
204
-
248
205
-#include "exec/helper-head.h"
249
void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb);
206
-
250
G_NORETURN void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
207
-/* Need one more level of indirection before stringification
251
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
208
- to get all the macros expanded first. */
252
index XXXXXXX..XXXXXXX 100644
209
-#define str(s) #s
253
--- a/target/openrisc/cpu.h
210
-
254
+++ b/target/openrisc/cpu.h
211
-#define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
255
@@ -XXX,XX +XXX,XX @@ void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
212
- { .func = HELPER(NAME), .name = str(NAME), \
256
int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
213
- .flags = FLAGS | dh_callflag(ret), \
257
int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
214
- .typemask = dh_typemask(ret, 0) },
258
void openrisc_translate_init(void);
215
-
259
+void openrisc_translate_code(CPUState *cs, TranslationBlock *tb,
216
-#define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \
260
+ int *max_insns, vaddr pc, void *host_pc);
217
- { .func = HELPER(NAME), .name = str(NAME), \
261
int print_insn_or1k(bfd_vma addr, disassemble_info *info);
218
- .flags = FLAGS | dh_callflag(ret), \
262
219
- .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) },
263
#ifndef CONFIG_USER_ONLY
220
-
264
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
221
-#define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \
265
index XXXXXXX..XXXXXXX 100644
222
- { .func = HELPER(NAME), .name = str(NAME), \
266
--- a/target/ppc/cpu.h
223
- .flags = FLAGS | dh_callflag(ret), \
267
+++ b/target/ppc/cpu.h
224
- .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
268
@@ -XXX,XX +XXX,XX @@ extern const VMStateDescription vmstate_ppc_cpu;
225
- | dh_typemask(t2, 2) },
269
226
-
270
/*****************************************************************************/
227
-#define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \
271
void ppc_translate_init(void);
228
- { .func = HELPER(NAME), .name = str(NAME), \
272
+void ppc_translate_code(CPUState *cs, TranslationBlock *tb,
229
- .flags = FLAGS | dh_callflag(ret), \
273
+ int *max_insns, vaddr pc, void *host_pc);
230
- .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
274
231
- | dh_typemask(t2, 2) | dh_typemask(t3, 3) },
275
#if !defined(CONFIG_USER_ONLY)
232
-
276
void ppc_store_sdr1(CPUPPCState *env, target_ulong value);
233
-#define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \
277
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
234
- { .func = HELPER(NAME), .name = str(NAME), \
278
index XXXXXXX..XXXXXXX 100644
235
- .flags = FLAGS | dh_callflag(ret), \
279
--- a/target/riscv/cpu.h
236
- .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
280
+++ b/target/riscv/cpu.h
237
- | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) },
281
@@ -XXX,XX +XXX,XX @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
238
-
282
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en);
239
-#define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \
283
240
- { .func = HELPER(NAME), .name = str(NAME), \
284
void riscv_translate_init(void);
241
- .flags = FLAGS | dh_callflag(ret), \
285
+void riscv_translate_code(CPUState *cs, TranslationBlock *tb,
242
- .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
286
+ int *max_insns, vaddr pc, void *host_pc);
243
- | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
244
- | dh_typemask(t5, 5) },
245
-
246
-#define DEF_HELPER_FLAGS_6(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6) \
247
- { .func = HELPER(NAME), .name = str(NAME), \
248
- .flags = FLAGS | dh_callflag(ret), \
249
- .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
250
- | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
251
- | dh_typemask(t5, 5) | dh_typemask(t6, 6) },
252
-
253
-#define DEF_HELPER_FLAGS_7(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6, t7) \
254
- { .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
255
- .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
256
- | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
257
- | dh_typemask(t5, 5) | dh_typemask(t6, 6) | dh_typemask(t7, 7) },
258
-
259
-#include "helper.h"
260
-#include "accel/tcg/tcg-runtime.h"
261
-#include "accel/tcg/plugin-helpers.h"
262
-
263
-#undef str
264
-#undef DEF_HELPER_FLAGS_0
265
-#undef DEF_HELPER_FLAGS_1
266
-#undef DEF_HELPER_FLAGS_2
267
-#undef DEF_HELPER_FLAGS_3
268
-#undef DEF_HELPER_FLAGS_4
269
-#undef DEF_HELPER_FLAGS_5
270
-#undef DEF_HELPER_FLAGS_6
271
-#undef DEF_HELPER_FLAGS_7
272
-
273
-#endif /* HELPER_TCG_H */
274
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
275
index XXXXXXX..XXXXXXX 100644
276
--- a/include/qemu/typedefs.h
277
+++ b/include/qemu/typedefs.h
278
@@ -XXX,XX +XXX,XX @@ typedef struct ReservedRegion ReservedRegion;
279
typedef struct SavedIOTLB SavedIOTLB;
280
typedef struct SHPCDevice SHPCDevice;
281
typedef struct SSIBus SSIBus;
282
+typedef struct TCGHelperInfo TCGHelperInfo;
283
typedef struct TranslationBlock TranslationBlock;
284
typedef struct VirtIODevice VirtIODevice;
285
typedef struct Visitor Visitor;
286
diff --git a/include/tcg/helper-info.h b/include/tcg/helper-info.h
287
index XXXXXXX..XXXXXXX 100644
288
--- a/include/tcg/helper-info.h
289
+++ b/include/tcg/helper-info.h
290
@@ -XXX,XX +XXX,XX @@ typedef struct TCGCallArgumentLoc {
291
unsigned tmp_subindex : 2;
292
} TCGCallArgumentLoc;
293
294
-typedef struct TCGHelperInfo {
295
+struct TCGHelperInfo {
296
void *func;
297
const char *name;
298
+
287
+
299
+ /* Used with g_once_init_enter. */
288
G_NORETURN void riscv_raise_exception(CPURISCVState *env,
300
#ifdef CONFIG_TCG_INTERPRETER
289
uint32_t exception, uintptr_t pc);
301
ffi_cif *cif;
290
302
+#else
291
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
303
+ uintptr_t init;
292
index XXXXXXX..XXXXXXX 100644
304
#endif
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);
305
+
403
+
306
unsigned typemask : 32;
404
assert(tb->size != 0);
307
unsigned flags : 8;
405
tcg_ctx->cpu = NULL;
308
unsigned nr_in : 8;
406
*max_insns = tb->icount;
309
@@ -XXX,XX +XXX,XX @@ typedef struct TCGHelperInfo {
407
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
310
408
/*
311
/* Maximum physical arguments are constrained by TCG_TYPE_I128. */
409
* Overflow of code_gen_buffer, or the current slice of it.
312
TCGCallArgumentLoc in[MAX_CALL_IARGS * (128 / TCG_TARGET_REG_BITS)];
410
*
313
-} TCGHelperInfo;
411
- * TODO: We don't need to re-do gen_intermediate_code, nor
314
+};
412
+ * TODO: We don't need to re-do tcg_ops->translate_code, nor
315
413
* should we re-do the tcg optimization currently hidden
316
#endif /* TCG_HELPER_INFO_H */
414
* inside tcg_gen_code. All that should be required is to
317
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
415
* flush the TBs, allocate a new TB, re-initialize it per
318
index XXXXXXX..XXXXXXX 100644
416
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
319
--- a/include/tcg/tcg.h
417
index XXXXXXX..XXXXXXX 100644
320
+++ b/include/tcg/tcg.h
418
--- a/target/alpha/cpu.c
321
@@ -XXX,XX +XXX,XX @@ typedef struct TCGTargetOpDef {
419
+++ b/target/alpha/cpu.c
322
420
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps alpha_sysemu_ops = {
323
bool tcg_op_supported(TCGOpcode op);
421
324
422
static const TCGCPUOps alpha_tcg_ops = {
325
-void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
423
.initialize = alpha_translate_init,
326
+void tcg_gen_callN(TCGHelperInfo *, TCGTemp *ret, int nargs, TCGTemp **args);
424
+ .translate_code = alpha_translate_code,
327
425
.synchronize_from_tb = alpha_cpu_synchronize_from_tb,
328
TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs);
426
.restore_state_to_opc = alpha_restore_state_to_opc,
329
void tcg_op_remove(TCGContext *s, TCGOp *op);
427
330
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
331
index XXXXXXX..XXXXXXX 100644
332
--- a/accel/tcg/plugin-gen.c
333
+++ b/accel/tcg/plugin-gen.c
334
@@ -XXX,XX +XXX,XX @@
335
#include "exec/exec-all.h"
336
#include "exec/plugin-gen.h"
337
#include "exec/translator.h"
338
+#include "exec/helper-proto.h"
339
+
340
+#define HELPER_H "accel/tcg/plugin-helpers.h"
341
+#include "exec/helper-info.c.inc"
342
+#undef HELPER_H
343
344
#ifdef CONFIG_SOFTMMU
345
# define CONFIG_SOFTMMU_GATE 1
346
diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c
347
index XXXXXXX..XXXXXXX 100644
348
--- a/accel/tcg/tcg-runtime.c
349
+++ b/accel/tcg/tcg-runtime.c
350
@@ -XXX,XX +XXX,XX @@
351
#include "exec/log.h"
352
#include "tcg/tcg.h"
353
354
+#define HELPER_H "accel/tcg/tcg-runtime.h"
355
+#include "exec/helper-info.c.inc"
356
+#undef HELPER_H
357
+
358
/* 32-bit helpers */
359
360
int32_t HELPER(div_i32)(int32_t arg1, int32_t arg2)
361
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
428
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
362
index XXXXXXX..XXXXXXX 100644
429
index XXXXXXX..XXXXXXX 100644
363
--- a/target/alpha/translate.c
430
--- a/target/alpha/translate.c
364
+++ b/target/alpha/translate.c
431
+++ b/target/alpha/translate.c
365
@@ -XXX,XX +XXX,XX @@
432
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps alpha_tr_ops = {
366
#include "exec/translator.h"
433
.tb_stop = alpha_tr_tb_stop,
367
#include "exec/log.h"
434
};
368
435
369
+#define HELPER_H "helper.h"
436
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
370
+#include "exec/helper-info.c.inc"
437
- vaddr pc, void *host_pc)
371
+#undef HELPER_H
438
+void alpha_translate_code(CPUState *cpu, TranslationBlock *tb,
372
439
+ int *max_insns, vaddr pc, void *host_pc)
373
#undef ALPHA_DEBUG_DISAS
440
{
374
#define CONFIG_SOFTFLOAT_INLINE
441
DisasContext dc;
442
translator_loop(cpu, tb, max_insns, pc, host_pc, &alpha_tr_ops, &dc.base);
443
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
444
index XXXXXXX..XXXXXXX 100644
445
--- a/target/arm/cpu.c
446
+++ b/target/arm/cpu.c
447
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps arm_sysemu_ops = {
448
#ifdef CONFIG_TCG
449
static const TCGCPUOps arm_tcg_ops = {
450
.initialize = arm_translate_init,
451
+ .translate_code = arm_translate_code,
452
.synchronize_from_tb = arm_cpu_synchronize_from_tb,
453
.debug_excp_handler = arm_debug_excp_handler,
454
.restore_state_to_opc = arm_restore_state_to_opc,
455
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
456
index XXXXXXX..XXXXXXX 100644
457
--- a/target/arm/tcg/cpu-v7m.c
458
+++ b/target/arm/tcg/cpu-v7m.c
459
@@ -XXX,XX +XXX,XX @@ static void cortex_m55_initfn(Object *obj)
460
461
static const TCGCPUOps arm_v7m_tcg_ops = {
462
.initialize = arm_translate_init,
463
+ .translate_code = arm_translate_code,
464
.synchronize_from_tb = arm_cpu_synchronize_from_tb,
465
.debug_excp_handler = arm_debug_excp_handler,
466
.restore_state_to_opc = arm_restore_state_to_opc,
375
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
467
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
376
index XXXXXXX..XXXXXXX 100644
468
index XXXXXXX..XXXXXXX 100644
377
--- a/target/arm/tcg/translate.c
469
--- a/target/arm/tcg/translate.c
378
+++ b/target/arm/tcg/translate.c
470
+++ b/target/arm/tcg/translate.c
379
@@ -XXX,XX +XXX,XX @@
471
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps thumb_translator_ops = {
380
#include "exec/log.h"
472
.tb_stop = arm_tr_tb_stop,
381
#include "cpregs.h"
473
};
382
474
383
+#define HELPER_H "helper.h"
475
-/* generate intermediate code for basic block 'tb'. */
384
+#include "exec/helper-info.c.inc"
476
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
385
+#undef HELPER_H
477
- vaddr pc, void *host_pc)
386
478
+void arm_translate_code(CPUState *cpu, TranslationBlock *tb,
387
#define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
479
+ int *max_insns, vaddr pc, void *host_pc)
388
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
480
{
481
DisasContext dc = { };
482
const TranslatorOps *ops = &arm_translator_ops;
483
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
484
index XXXXXXX..XXXXXXX 100644
485
--- a/target/avr/cpu.c
486
+++ b/target/avr/cpu.c
487
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps avr_sysemu_ops = {
488
489
static const TCGCPUOps avr_tcg_ops = {
490
.initialize = avr_cpu_tcg_init,
491
+ .translate_code = avr_cpu_translate_code,
492
.synchronize_from_tb = avr_cpu_synchronize_from_tb,
493
.restore_state_to_opc = avr_restore_state_to_opc,
494
.cpu_exec_interrupt = avr_cpu_exec_interrupt,
389
diff --git a/target/avr/translate.c b/target/avr/translate.c
495
diff --git a/target/avr/translate.c b/target/avr/translate.c
390
index XXXXXXX..XXXXXXX 100644
496
index XXXXXXX..XXXXXXX 100644
391
--- a/target/avr/translate.c
497
--- a/target/avr/translate.c
392
+++ b/target/avr/translate.c
498
+++ b/target/avr/translate.c
393
@@ -XXX,XX +XXX,XX @@
499
@@ -XXX,XX +XXX,XX @@ static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
394
#include "exec/translator.h"
500
*
395
#include "exec/gen-icount.h"
501
* - translate()
396
502
* - canonicalize_skip()
397
+#define HELPER_H "helper.h"
503
- * - gen_intermediate_code()
398
+#include "exec/helper-info.c.inc"
504
+ * - translate_code()
399
+#undef HELPER_H
505
* - restore_state_to_opc()
400
+
506
*
401
+
507
*/
402
/*
508
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps avr_tr_ops = {
403
* Define if you want a BREAK instruction translated to a breakpoint
509
.tb_stop = avr_tr_tb_stop,
404
* Active debugging connection is assumed
510
};
405
diff --git a/target/cris/translate.c b/target/cris/translate.c
511
406
index XXXXXXX..XXXXXXX 100644
512
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
407
--- a/target/cris/translate.c
513
- vaddr pc, void *host_pc)
408
+++ b/target/cris/translate.c
514
+void avr_cpu_translate_code(CPUState *cs, TranslationBlock *tb,
409
@@ -XXX,XX +XXX,XX @@
515
+ int *max_insns, vaddr pc, void *host_pc)
410
#include "exec/translator.h"
516
{
411
#include "crisv32-decode.h"
517
DisasContext dc = { };
412
#include "qemu/qemu-print.h"
518
translator_loop(cs, tb, max_insns, pc, host_pc, &avr_tr_ops, &dc.base);
413
-
519
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
414
#include "exec/helper-gen.h"
520
index XXXXXXX..XXXXXXX 100644
415
-
521
--- a/target/hexagon/cpu.c
416
#include "exec/log.h"
522
+++ b/target/hexagon/cpu.c
417
523
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_init(Object *obj)
418
+#define HELPER_H "helper.h"
524
419
+#include "exec/helper-info.c.inc"
525
static const TCGCPUOps hexagon_tcg_ops = {
420
+#undef HELPER_H
526
.initialize = hexagon_translate_init,
421
+
527
+ .translate_code = hexagon_translate_code,
422
528
.synchronize_from_tb = hexagon_cpu_synchronize_from_tb,
423
#define DISAS_CRIS 0
529
.restore_state_to_opc = hexagon_restore_state_to_opc,
424
#if DISAS_CRIS
530
};
425
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
531
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
426
index XXXXXXX..XXXXXXX 100644
532
index XXXXXXX..XXXXXXX 100644
427
--- a/target/hexagon/translate.c
533
--- a/target/hexagon/translate.c
428
+++ b/target/hexagon/translate.c
534
+++ b/target/hexagon/translate.c
429
@@ -XXX,XX +XXX,XX @@
535
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hexagon_tr_ops = {
430
#include "genptr.h"
536
.tb_stop = hexagon_tr_tb_stop,
431
#include "printinsn.h"
537
};
432
538
433
+#define HELPER_H "helper.h"
539
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
434
+#include "exec/helper-info.c.inc"
540
- vaddr pc, void *host_pc)
435
+#undef HELPER_H
541
+void hexagon_translate_code(CPUState *cs, TranslationBlock *tb,
436
+
542
+ int *max_insns, vaddr pc, void *host_pc)
437
#include "analyze_funcs_generated.c.inc"
543
{
438
544
DisasContext ctx;
439
typedef void (*AnalyzeInsn)(DisasContext *ctx);
545
546
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
547
index XXXXXXX..XXXXXXX 100644
548
--- a/target/hppa/cpu.c
549
+++ b/target/hppa/cpu.c
550
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
551
552
static const TCGCPUOps hppa_tcg_ops = {
553
.initialize = hppa_translate_init,
554
+ .translate_code = hppa_translate_code,
555
.synchronize_from_tb = hppa_cpu_synchronize_from_tb,
556
.restore_state_to_opc = hppa_restore_state_to_opc,
557
440
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
558
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
441
index XXXXXXX..XXXXXXX 100644
559
index XXXXXXX..XXXXXXX 100644
442
--- a/target/hppa/translate.c
560
--- a/target/hppa/translate.c
443
+++ b/target/hppa/translate.c
561
+++ b/target/hppa/translate.c
444
@@ -XXX,XX +XXX,XX @@
562
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hppa_tr_ops = {
445
#include "exec/translator.h"
563
#endif
446
#include "exec/log.h"
564
};
447
565
448
+#define HELPER_H "helper.h"
566
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
449
+#include "exec/helper-info.c.inc"
567
- vaddr pc, void *host_pc)
450
+#undef HELPER_H
568
+void hppa_translate_code(CPUState *cs, TranslationBlock *tb,
451
+
569
+ int *max_insns, vaddr pc, void *host_pc)
452
+
570
{
453
/* Since we have a distinction between register size and address size,
571
DisasContext ctx = { };
454
we need to redefine all of these. */
572
translator_loop(cs, tb, max_insns, pc, host_pc, &hppa_tr_ops, &ctx.base);
455
573
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
574
index XXXXXXX..XXXXXXX 100644
575
--- a/target/i386/tcg/tcg-cpu.c
576
+++ b/target/i386/tcg/tcg-cpu.c
577
@@ -XXX,XX +XXX,XX @@ static bool x86_debug_check_breakpoint(CPUState *cs)
578
579
static const TCGCPUOps x86_tcg_ops = {
580
.initialize = tcg_x86_init,
581
+ .translate_code = x86_translate_code,
582
.synchronize_from_tb = x86_cpu_synchronize_from_tb,
583
.restore_state_to_opc = x86_restore_state_to_opc,
584
.cpu_exec_enter = x86_cpu_exec_enter,
456
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
585
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
457
index XXXXXXX..XXXXXXX 100644
586
index XXXXXXX..XXXXXXX 100644
458
--- a/target/i386/tcg/translate.c
587
--- a/target/i386/tcg/translate.c
459
+++ b/target/i386/tcg/translate.c
588
+++ b/target/i386/tcg/translate.c
460
@@ -XXX,XX +XXX,XX @@
589
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps i386_tr_ops = {
461
590
.tb_stop = i386_tr_tb_stop,
462
#include "exec/log.h"
591
};
463
592
464
+#define HELPER_H "helper.h"
593
-/* generate intermediate code for basic block 'tb'. */
465
+#include "exec/helper-info.c.inc"
594
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
466
+#undef HELPER_H
595
- vaddr pc, void *host_pc)
467
+
596
+void x86_translate_code(CPUState *cpu, TranslationBlock *tb,
468
+
597
+ int *max_insns, vaddr pc, void *host_pc)
469
#define PREFIX_REPZ 0x01
598
{
470
#define PREFIX_REPNZ 0x02
599
DisasContext dc;
471
#define PREFIX_LOCK 0x04
600
472
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
601
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
473
index XXXXXXX..XXXXXXX 100644
602
index XXXXXXX..XXXXXXX 100644
474
--- a/target/loongarch/translate.c
603
--- a/target/loongarch/cpu.c
475
+++ b/target/loongarch/translate.c
604
+++ b/target/loongarch/cpu.c
476
@@ -XXX,XX +XXX,XX @@ static TCGv cpu_lladdr, cpu_llval;
605
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
477
606
478
#include "exec/gen-icount.h"
607
static const TCGCPUOps loongarch_tcg_ops = {
479
608
.initialize = loongarch_translate_init,
480
+#define HELPER_H "helper.h"
609
+ .translate_code = loongarch_translate_code,
481
+#include "exec/helper-info.c.inc"
610
.synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
482
+#undef HELPER_H
611
.restore_state_to_opc = loongarch_restore_state_to_opc,
483
+
612
484
#define DISAS_STOP DISAS_TARGET_0
613
diff --git a/target/loongarch/tcg/translate.c b/target/loongarch/tcg/translate.c
485
#define DISAS_EXIT DISAS_TARGET_1
614
index XXXXXXX..XXXXXXX 100644
486
#define DISAS_EXIT_UPDATE DISAS_TARGET_2
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
487
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
640
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
488
index XXXXXXX..XXXXXXX 100644
641
index XXXXXXX..XXXXXXX 100644
489
--- a/target/m68k/translate.c
642
--- a/target/m68k/translate.c
490
+++ b/target/m68k/translate.c
643
+++ b/target/m68k/translate.c
491
@@ -XXX,XX +XXX,XX @@
644
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps m68k_tr_ops = {
492
#include "exec/log.h"
645
.tb_stop = m68k_tr_tb_stop,
493
#include "fpu/softfloat.h"
646
};
494
647
495
+#define HELPER_H "helper.h"
648
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
496
+#include "exec/helper-info.c.inc"
649
- vaddr pc, void *host_pc)
497
+#undef HELPER_H
650
+void m68k_translate_code(CPUState *cpu, TranslationBlock *tb,
498
651
+ int *max_insns, vaddr pc, void *host_pc)
499
//#define DEBUG_DISPATCH 1
652
{
653
DisasContext dc;
654
translator_loop(cpu, tb, max_insns, pc, host_pc, &m68k_tr_ops, &dc.base);
655
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
656
index XXXXXXX..XXXXXXX 100644
657
--- a/target/microblaze/cpu.c
658
+++ b/target/microblaze/cpu.c
659
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps mb_sysemu_ops = {
660
661
static const TCGCPUOps mb_tcg_ops = {
662
.initialize = mb_tcg_init,
663
+ .translate_code = mb_translate_code,
664
.synchronize_from_tb = mb_cpu_synchronize_from_tb,
665
.restore_state_to_opc = mb_restore_state_to_opc,
500
666
501
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
667
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
502
index XXXXXXX..XXXXXXX 100644
668
index XXXXXXX..XXXXXXX 100644
503
--- a/target/microblaze/translate.c
669
--- a/target/microblaze/translate.c
504
+++ b/target/microblaze/translate.c
670
+++ b/target/microblaze/translate.c
505
@@ -XXX,XX +XXX,XX @@
671
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mb_tr_ops = {
506
672
.tb_stop = mb_tr_tb_stop,
507
#include "exec/log.h"
673
};
508
674
509
+#define HELPER_H "helper.h"
675
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
510
+#include "exec/helper-info.c.inc"
676
- vaddr pc, void *host_pc)
511
+#undef HELPER_H
677
+void mb_translate_code(CPUState *cpu, TranslationBlock *tb,
512
+
678
+ int *max_insns, vaddr pc, void *host_pc)
513
#define EXTRACT_FIELD(src, start, end) \
679
{
514
(((src) >> start) & ((1 << (end - start + 1)) - 1))
680
DisasContext dc;
681
translator_loop(cpu, tb, max_insns, pc, host_pc, &mb_tr_ops, &dc.base);
682
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
683
index XXXXXXX..XXXXXXX 100644
684
--- a/target/mips/cpu.c
685
+++ b/target/mips/cpu.c
686
@@ -XXX,XX +XXX,XX @@ static const Property mips_cpu_properties[] = {
687
#include "hw/core/tcg-cpu-ops.h"
688
static const TCGCPUOps mips_tcg_ops = {
689
.initialize = mips_tcg_init,
690
+ .translate_code = mips_translate_code,
691
.synchronize_from_tb = mips_cpu_synchronize_from_tb,
692
.restore_state_to_opc = mips_restore_state_to_opc,
515
693
516
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
694
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
517
index XXXXXXX..XXXXXXX 100644
695
index XXXXXXX..XXXXXXX 100644
518
--- a/target/mips/tcg/translate.c
696
--- a/target/mips/tcg/translate.c
519
+++ b/target/mips/tcg/translate.c
697
+++ b/target/mips/tcg/translate.c
520
@@ -XXX,XX +XXX,XX @@
698
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mips_tr_ops = {
521
#include "fpu_helper.h"
699
.tb_stop = mips_tr_tb_stop,
522
#include "translate.h"
700
};
523
701
524
+#define HELPER_H "helper.h"
702
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
525
+#include "exec/helper-info.c.inc"
703
- vaddr pc, void *host_pc)
526
+#undef HELPER_H
704
+void mips_translate_code(CPUState *cs, TranslationBlock *tb,
527
+
705
+ int *max_insns, vaddr pc, void *host_pc)
528
+
706
{
529
/*
707
DisasContext ctx;
530
* Many sysemu-only helpers are not reachable for user-only.
708
531
* Define stub generators here, so that we need not either sprinkle
709
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
532
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
710
index XXXXXXX..XXXXXXX 100644
533
index XXXXXXX..XXXXXXX 100644
711
--- a/target/openrisc/cpu.c
534
--- a/target/nios2/translate.c
712
+++ b/target/openrisc/cpu.c
535
+++ b/target/nios2/translate.c
713
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps openrisc_sysemu_ops = {
536
@@ -XXX,XX +XXX,XX @@
714
537
#include "exec/gen-icount.h"
715
static const TCGCPUOps openrisc_tcg_ops = {
538
#include "semihosting/semihost.h"
716
.initialize = openrisc_translate_init,
539
717
+ .translate_code = openrisc_translate_code,
540
+#define HELPER_H "helper.h"
718
.synchronize_from_tb = openrisc_cpu_synchronize_from_tb,
541
+#include "exec/helper-info.c.inc"
719
.restore_state_to_opc = openrisc_restore_state_to_opc,
542
+#undef HELPER_H
543
+
544
+
545
/* is_jmp field values */
546
#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
547
720
548
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
721
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
549
index XXXXXXX..XXXXXXX 100644
722
index XXXXXXX..XXXXXXX 100644
550
--- a/target/openrisc/translate.c
723
--- a/target/openrisc/translate.c
551
+++ b/target/openrisc/translate.c
724
+++ b/target/openrisc/translate.c
552
@@ -XXX,XX +XXX,XX @@
725
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps openrisc_tr_ops = {
553
726
.tb_stop = openrisc_tr_tb_stop,
554
#include "exec/log.h"
727
};
555
728
556
+#define HELPER_H "helper.h"
729
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
557
+#include "exec/helper-info.c.inc"
730
- vaddr pc, void *host_pc)
558
+#undef HELPER_H
731
+void openrisc_translate_code(CPUState *cs, TranslationBlock *tb,
559
+
732
+ int *max_insns, vaddr pc, void *host_pc)
560
+
733
{
561
/* is_jmp field values */
734
DisasContext ctx;
562
#define DISAS_EXIT DISAS_TARGET_0 /* force exit to main loop */
735
563
#define DISAS_JUMP DISAS_TARGET_1 /* exit via jmp_pc/jmp_pc_imm */
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
564
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
748
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
565
index XXXXXXX..XXXXXXX 100644
749
index XXXXXXX..XXXXXXX 100644
566
--- a/target/ppc/translate.c
750
--- a/target/ppc/translate.c
567
+++ b/target/ppc/translate.c
751
+++ b/target/ppc/translate.c
568
@@ -XXX,XX +XXX,XX @@
752
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps ppc_tr_ops = {
569
#include "qemu/qemu-print.h"
753
.tb_stop = ppc_tr_tb_stop,
570
#include "qapi/error.h"
754
};
571
755
572
+#define HELPER_H "helper.h"
756
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
573
+#include "exec/helper-info.c.inc"
757
- vaddr pc, void *host_pc)
574
+#undef HELPER_H
758
+void ppc_translate_code(CPUState *cs, TranslationBlock *tb,
575
+
759
+ int *max_insns, vaddr pc, void *host_pc)
576
#define CPU_SINGLE_STEP 0x1
760
{
577
#define CPU_BRANCH_STEP 0x2
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,
578
774
579
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
775
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
580
index XXXXXXX..XXXXXXX 100644
776
index XXXXXXX..XXXXXXX 100644
581
--- a/target/riscv/translate.c
777
--- a/target/riscv/translate.c
582
+++ b/target/riscv/translate.c
778
+++ b/target/riscv/translate.c
583
@@ -XXX,XX +XXX,XX @@
779
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps riscv_tr_ops = {
584
#include "instmap.h"
780
.tb_stop = riscv_tr_tb_stop,
585
#include "internals.h"
781
};
586
782
587
+#define HELPER_H "helper.h"
783
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
588
+#include "exec/helper-info.c.inc"
784
- vaddr pc, void *host_pc)
589
+#undef HELPER_H
785
+void riscv_translate_code(CPUState *cs, TranslationBlock *tb,
590
+
786
+ int *max_insns, vaddr pc, void *host_pc)
591
/* global register indices */
787
{
592
static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
788
DisasContext ctx;
593
static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
789
790
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
791
index XXXXXXX..XXXXXXX 100644
792
--- a/target/rx/cpu.c
793
+++ b/target/rx/cpu.c
794
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps rx_sysemu_ops = {
795
796
static const TCGCPUOps rx_tcg_ops = {
797
.initialize = rx_translate_init,
798
+ .translate_code = rx_translate_code,
799
.synchronize_from_tb = rx_cpu_synchronize_from_tb,
800
.restore_state_to_opc = rx_restore_state_to_opc,
801
.tlb_fill = rx_cpu_tlb_fill,
594
diff --git a/target/rx/translate.c b/target/rx/translate.c
802
diff --git a/target/rx/translate.c b/target/rx/translate.c
595
index XXXXXXX..XXXXXXX 100644
803
index XXXXXXX..XXXXXXX 100644
596
--- a/target/rx/translate.c
804
--- a/target/rx/translate.c
597
+++ b/target/rx/translate.c
805
+++ b/target/rx/translate.c
598
@@ -XXX,XX +XXX,XX @@
806
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps rx_tr_ops = {
599
#include "exec/translator.h"
807
.tb_stop = rx_tr_tb_stop,
600
#include "exec/log.h"
808
};
601
809
602
+#define HELPER_H "helper.h"
810
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
603
+#include "exec/helper-info.c.inc"
811
- vaddr pc, void *host_pc)
604
+#undef HELPER_H
812
+void rx_translate_code(CPUState *cs, TranslationBlock *tb,
605
+
813
+ int *max_insns, vaddr pc, void *host_pc)
606
+
814
{
607
typedef struct DisasContext {
815
DisasContext dc;
608
DisasContextBase base;
816
609
CPURXState *env;
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
610
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
829
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
611
index XXXXXXX..XXXXXXX 100644
830
index XXXXXXX..XXXXXXX 100644
612
--- a/target/s390x/tcg/translate.c
831
--- a/target/s390x/tcg/translate.c
613
+++ b/target/s390x/tcg/translate.c
832
+++ b/target/s390x/tcg/translate.c
614
@@ -XXX,XX +XXX,XX @@
833
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps s390x_tr_ops = {
615
#include "exec/log.h"
834
.disas_log = s390x_tr_disas_log,
616
#include "qemu/atomic128.h"
835
};
617
836
618
+#define HELPER_H "helper.h"
837
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
619
+#include "exec/helper-info.c.inc"
838
- vaddr pc, void *host_pc)
620
+#undef HELPER_H
839
+void s390x_translate_code(CPUState *cs, TranslationBlock *tb,
621
+
840
+ int *max_insns, vaddr pc, void *host_pc)
622
841
{
623
/* Information that (most) every instruction needs to manipulate. */
842
DisasContext dc;
624
typedef struct DisasContext DisasContext;
843
844
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
845
index XXXXXXX..XXXXXXX 100644
846
--- a/target/sh4/cpu.c
847
+++ b/target/sh4/cpu.c
848
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps sh4_sysemu_ops = {
849
850
static const TCGCPUOps superh_tcg_ops = {
851
.initialize = sh4_translate_init,
852
+ .translate_code = sh4_translate_code,
853
.synchronize_from_tb = superh_cpu_synchronize_from_tb,
854
.restore_state_to_opc = superh_restore_state_to_opc,
855
625
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
856
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
626
index XXXXXXX..XXXXXXX 100644
857
index XXXXXXX..XXXXXXX 100644
627
--- a/target/sh4/translate.c
858
--- a/target/sh4/translate.c
628
+++ b/target/sh4/translate.c
859
+++ b/target/sh4/translate.c
629
@@ -XXX,XX +XXX,XX @@
860
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sh4_tr_ops = {
630
#include "exec/log.h"
861
.tb_stop = sh4_tr_tb_stop,
631
#include "qemu/qemu-print.h"
862
};
632
863
633
+#define HELPER_H "helper.h"
864
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
634
+#include "exec/helper-info.c.inc"
865
- vaddr pc, void *host_pc)
635
+#undef HELPER_H
866
+void sh4_translate_code(CPUState *cs, TranslationBlock *tb,
636
+
867
+ int *max_insns, vaddr pc, void *host_pc)
637
868
{
638
typedef struct DisasContext {
869
DisasContext ctx;
639
DisasContextBase base;
870
871
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
872
index XXXXXXX..XXXXXXX 100644
873
--- a/target/sparc/cpu.c
874
+++ b/target/sparc/cpu.c
875
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
876
877
static const TCGCPUOps sparc_tcg_ops = {
878
.initialize = sparc_tcg_init,
879
+ .translate_code = sparc_translate_code,
880
.synchronize_from_tb = sparc_cpu_synchronize_from_tb,
881
.restore_state_to_opc = sparc_restore_state_to_opc,
882
640
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
883
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
641
index XXXXXXX..XXXXXXX 100644
884
index XXXXXXX..XXXXXXX 100644
642
--- a/target/sparc/translate.c
885
--- a/target/sparc/translate.c
643
+++ b/target/sparc/translate.c
886
+++ b/target/sparc/translate.c
644
@@ -XXX,XX +XXX,XX @@
887
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sparc_tr_ops = {
645
#include "exec/log.h"
888
.tb_stop = sparc_tr_tb_stop,
646
#include "asi.h"
889
};
647
890
648
+#define HELPER_H "helper.h"
891
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
649
+#include "exec/helper-info.c.inc"
892
- vaddr pc, void *host_pc)
650
+#undef HELPER_H
893
+void sparc_translate_code(CPUState *cs, TranslationBlock *tb,
651
894
+ int *max_insns, vaddr pc, void *host_pc)
652
#define DYNAMIC_PC 1 /* dynamic pc value */
895
{
653
#define JUMP_PC 2 /* dynamic pc value which takes only two values
896
DisasContext dc = {};
897
898
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
899
index XXXXXXX..XXXXXXX 100644
900
--- a/target/tricore/cpu.c
901
+++ b/target/tricore/cpu.c
902
@@ -XXX,XX +XXX,XX @@ static const struct SysemuCPUOps tricore_sysemu_ops = {
903
904
static const TCGCPUOps tricore_tcg_ops = {
905
.initialize = tricore_tcg_init,
906
+ .translate_code = tricore_translate_code,
907
.synchronize_from_tb = tricore_cpu_synchronize_from_tb,
908
.restore_state_to_opc = tricore_restore_state_to_opc,
909
.tlb_fill = tricore_cpu_tlb_fill,
654
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
910
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
655
index XXXXXXX..XXXXXXX 100644
911
index XXXXXXX..XXXXXXX 100644
656
--- a/target/tricore/translate.c
912
--- a/target/tricore/translate.c
657
+++ b/target/tricore/translate.c
913
+++ b/target/tricore/translate.c
658
@@ -XXX,XX +XXX,XX @@
914
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps tricore_tr_ops = {
659
#include "exec/translator.h"
915
.tb_stop = tricore_tr_tb_stop,
660
#include "exec/log.h"
916
};
661
917
662
+#define HELPER_H "helper.h"
918
-
663
+#include "exec/helper-info.c.inc"
919
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
664
+#undef HELPER_H
920
- vaddr pc, void *host_pc)
665
+
921
+void tricore_translate_code(CPUState *cs, TranslationBlock *tb,
666
+
922
+ int *max_insns, vaddr pc, void *host_pc)
667
/*
923
{
668
* TCG registers
924
DisasContext ctx;
669
*/
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
670
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
938
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
671
index XXXXXXX..XXXXXXX 100644
939
index XXXXXXX..XXXXXXX 100644
672
--- a/target/xtensa/translate.c
940
--- a/target/xtensa/translate.c
673
+++ b/target/xtensa/translate.c
941
+++ b/target/xtensa/translate.c
674
@@ -XXX,XX +XXX,XX @@
942
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps xtensa_translator_ops = {
675
943
.tb_stop = xtensa_tr_tb_stop,
676
#include "exec/log.h"
944
};
677
945
678
+#define HELPER_H "helper.h"
946
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
679
+#include "exec/helper-info.c.inc"
947
- vaddr pc, void *host_pc)
680
+#undef HELPER_H
948
+void xtensa_translate_code(CPUState *cpu, TranslationBlock *tb,
681
+
949
+ int *max_insns, vaddr pc, void *host_pc)
682
950
{
683
struct DisasContext {
951
DisasContext dc = {};
684
DisasContextBase base;
952
translator_loop(cpu, tb, max_insns, pc, host_pc,
685
diff --git a/tcg/tcg.c b/tcg/tcg.c
686
index XXXXXXX..XXXXXXX 100644
687
--- a/tcg/tcg.c
688
+++ b/tcg/tcg.c
689
@@ -XXX,XX +XXX,XX @@ void tcg_pool_reset(TCGContext *s)
690
s->pool_current = NULL;
691
}
692
693
-#include "exec/helper-proto.h"
694
-
695
-static TCGHelperInfo all_helpers[] = {
696
-#include "exec/helper-tcg.h"
697
-};
698
-static GHashTable *helper_table;
699
-
700
/*
701
* Create TCGHelperInfo structures for "tcg/tcg-ldst.h" functions,
702
* akin to what "exec/helper-tcg.h" does with DEF_HELPER_FLAGS_N.
703
@@ -XXX,XX +XXX,XX @@ static ffi_type *typecode_to_ffi(int argmask)
704
g_assert_not_reached();
705
}
706
707
-static void init_ffi_layouts(void)
708
+static ffi_cif *init_ffi_layout(TCGHelperInfo *info)
709
{
710
- /* g_direct_hash/equal for direct comparisons on uint32_t. */
711
- GHashTable *ffi_table = g_hash_table_new(NULL, NULL);
712
+ unsigned typemask = info->typemask;
713
+ struct {
714
+ ffi_cif cif;
715
+ ffi_type *args[];
716
+ } *ca;
717
+ ffi_status status;
718
+ int nargs;
719
720
- for (int i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
721
- TCGHelperInfo *info = &all_helpers[i];
722
- unsigned typemask = info->typemask;
723
- gpointer hash = (gpointer)(uintptr_t)typemask;
724
- struct {
725
- ffi_cif cif;
726
- ffi_type *args[];
727
- } *ca;
728
- ffi_status status;
729
- int nargs;
730
- ffi_cif *cif;
731
+ /* Ignoring the return type, find the last non-zero field. */
732
+ nargs = 32 - clz32(typemask >> 3);
733
+ nargs = DIV_ROUND_UP(nargs, 3);
734
+ assert(nargs <= MAX_CALL_IARGS);
735
736
- cif = g_hash_table_lookup(ffi_table, hash);
737
- if (cif) {
738
- info->cif = cif;
739
- continue;
740
+ ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
741
+ ca->cif.rtype = typecode_to_ffi(typemask & 7);
742
+ ca->cif.nargs = nargs;
743
+
744
+ if (nargs != 0) {
745
+ ca->cif.arg_types = ca->args;
746
+ for (int j = 0; j < nargs; ++j) {
747
+ int typecode = extract32(typemask, (j + 1) * 3, 3);
748
+ ca->args[j] = typecode_to_ffi(typecode);
749
}
750
-
751
- /* Ignoring the return type, find the last non-zero field. */
752
- nargs = 32 - clz32(typemask >> 3);
753
- nargs = DIV_ROUND_UP(nargs, 3);
754
- assert(nargs <= MAX_CALL_IARGS);
755
-
756
- ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
757
- ca->cif.rtype = typecode_to_ffi(typemask & 7);
758
- ca->cif.nargs = nargs;
759
-
760
- if (nargs != 0) {
761
- ca->cif.arg_types = ca->args;
762
- for (int j = 0; j < nargs; ++j) {
763
- int typecode = extract32(typemask, (j + 1) * 3, 3);
764
- ca->args[j] = typecode_to_ffi(typecode);
765
- }
766
- }
767
-
768
- status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
769
- ca->cif.rtype, ca->cif.arg_types);
770
- assert(status == FFI_OK);
771
-
772
- cif = &ca->cif;
773
- info->cif = cif;
774
- g_hash_table_insert(ffi_table, hash, (gpointer)cif);
775
}
776
777
- g_hash_table_destroy(ffi_table);
778
+ status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
779
+ ca->cif.rtype, ca->cif.arg_types);
780
+ assert(status == FFI_OK);
781
+
782
+ return &ca->cif;
783
}
784
+
785
+#define HELPER_INFO_INIT(I) (&(I)->cif)
786
+#define HELPER_INFO_INIT_VAL(I) init_ffi_layout(I)
787
+#else
788
+#define HELPER_INFO_INIT(I) (&(I)->init)
789
+#define HELPER_INFO_INIT_VAL(I) 1
790
#endif /* CONFIG_TCG_INTERPRETER */
791
792
static inline bool arg_slot_reg_p(unsigned arg_slot)
793
@@ -XXX,XX +XXX,XX @@ static void tcg_context_init(unsigned max_cpus)
794
args_ct += n;
795
}
796
797
- /* Register helpers. */
798
- /* Use g_direct_hash/equal for direct pointer comparisons on func. */
799
- helper_table = g_hash_table_new(NULL, NULL);
800
-
801
- for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
802
- init_call_layout(&all_helpers[i]);
803
- g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func,
804
- (gpointer)&all_helpers[i]);
805
- }
806
-
807
init_call_layout(&info_helper_ld32_mmu);
808
init_call_layout(&info_helper_ld64_mmu);
809
init_call_layout(&info_helper_ld128_mmu);
810
@@ -XXX,XX +XXX,XX @@ static void tcg_context_init(unsigned max_cpus)
811
init_call_layout(&info_helper_st64_mmu);
812
init_call_layout(&info_helper_st128_mmu);
813
814
-#ifdef CONFIG_TCG_INTERPRETER
815
- init_ffi_layouts();
816
-#endif
817
-
818
tcg_target_init(s);
819
process_op_defs(s);
820
821
@@ -XXX,XX +XXX,XX @@ bool tcg_op_supported(TCGOpcode op)
822
823
static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs);
824
825
-void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
826
+void tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, int nargs, TCGTemp **args)
827
{
828
- const TCGHelperInfo *info;
829
TCGv_i64 extend_free[MAX_CALL_IARGS];
830
int n_extend = 0;
831
TCGOp *op;
832
int i, n, pi = 0, total_args;
833
834
- info = g_hash_table_lookup(helper_table, (gpointer)func);
835
+ if (unlikely(g_once_init_enter(HELPER_INFO_INIT(info)))) {
836
+ init_call_layout(info);
837
+ g_once_init_leave(HELPER_INFO_INIT(info), HELPER_INFO_INIT_VAL(info));
838
+ }
839
+
840
total_args = info->nr_out + info->nr_in + 2;
841
op = tcg_op_alloc(INDEX_op_call, total_args);
842
843
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
844
g_assert_not_reached();
845
}
846
}
847
- op->args[pi++] = (uintptr_t)func;
848
+ op->args[pi++] = (uintptr_t)info->func;
849
op->args[pi++] = (uintptr_t)info;
850
tcg_debug_assert(pi == total_args);
851
852
diff --git a/include/exec/helper-info.c.inc b/include/exec/helper-info.c.inc
853
new file mode 100644
854
index XXXXXXX..XXXXXXX
855
--- /dev/null
856
+++ b/include/exec/helper-info.c.inc
857
@@ -XXX,XX +XXX,XX @@
858
+/* SPDX-License-Identifier: GPL-2.0-or-later */
859
+/*
860
+ * Helper file for declaring TCG helper functions.
861
+ * This one expands info structures for tcg helpers.
862
+ * Define HELPER_H for the header file to be expanded.
863
+ */
864
+
865
+#include "tcg/tcg.h"
866
+#include "tcg/helper-info.h"
867
+#include "exec/helper-head.h"
868
+
869
+/*
870
+ * Need one more level of indirection before stringification
871
+ * to get all the macros expanded first.
872
+ */
873
+#define str(s) #s
874
+
875
+#define DEF_HELPER_FLAGS_0(NAME, FLAGS, RET) \
876
+ TCGHelperInfo glue(helper_info_, NAME) = { \
877
+ .func = HELPER(NAME), .name = str(NAME), \
878
+ .flags = FLAGS | dh_callflag(RET), \
879
+ .typemask = dh_typemask(RET, 0) \
880
+ };
881
+
882
+#define DEF_HELPER_FLAGS_1(NAME, FLAGS, RET, T1) \
883
+ TCGHelperInfo glue(helper_info_, NAME) = { \
884
+ .func = HELPER(NAME), .name = str(NAME), \
885
+ .flags = FLAGS | dh_callflag(RET), \
886
+ .typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
887
+ };
888
+
889
+#define DEF_HELPER_FLAGS_2(NAME, FLAGS, RET, T1, T2) \
890
+ TCGHelperInfo glue(helper_info_, NAME) = { \
891
+ .func = HELPER(NAME), .name = str(NAME), \
892
+ .flags = FLAGS | dh_callflag(RET), \
893
+ .typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
894
+ | dh_typemask(T2, 2) \
895
+ };
896
+
897
+#define DEF_HELPER_FLAGS_3(NAME, FLAGS, RET, T1, T2, T3) \
898
+ TCGHelperInfo glue(helper_info_, NAME) = { \
899
+ .func = HELPER(NAME), .name = str(NAME), \
900
+ .flags = FLAGS | dh_callflag(RET), \
901
+ .typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
902
+ | dh_typemask(T2, 2) | dh_typemask(T3, 3) \
903
+ };
904
+
905
+#define DEF_HELPER_FLAGS_4(NAME, FLAGS, RET, T1, T2, T3, T4) \
906
+ TCGHelperInfo glue(helper_info_, NAME) = { \
907
+ .func = HELPER(NAME), .name = str(NAME), \
908
+ .flags = FLAGS | dh_callflag(RET), \
909
+ .typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
910
+ | dh_typemask(T2, 2) | dh_typemask(T3, 3) \
911
+ | dh_typemask(T4, 4) \
912
+ };
913
+
914
+#define DEF_HELPER_FLAGS_5(NAME, FLAGS, RET, T1, T2, T3, T4, T5) \
915
+ TCGHelperInfo glue(helper_info_, NAME) = { \
916
+ .func = HELPER(NAME), .name = str(NAME), \
917
+ .flags = FLAGS | dh_callflag(RET), \
918
+ .typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
919
+ | dh_typemask(T2, 2) | dh_typemask(T3, 3) \
920
+ | dh_typemask(T4, 4) | dh_typemask(T5, 5) \
921
+ };
922
+
923
+#define DEF_HELPER_FLAGS_6(NAME, FLAGS, RET, T1, T2, T3, T4, T5, T6) \
924
+ TCGHelperInfo glue(helper_info_, NAME) = { \
925
+ .func = HELPER(NAME), .name = str(NAME), \
926
+ .flags = FLAGS | dh_callflag(RET), \
927
+ .typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
928
+ | dh_typemask(T2, 2) | dh_typemask(T3, 3) \
929
+ | dh_typemask(T4, 4) | dh_typemask(T5, 5) \
930
+ | dh_typemask(T6, 6) \
931
+ };
932
+
933
+#define DEF_HELPER_FLAGS_7(NAME, FLAGS, RET, T1, T2, T3, T4, T5, T6, T7) \
934
+ TCGHelperInfo glue(helper_info_, NAME) = { \
935
+ .func = HELPER(NAME), .name = str(NAME), \
936
+ .flags = FLAGS | dh_callflag(RET), \
937
+ .typemask = dh_typemask(RET, 0) | dh_typemask(T1, 1) \
938
+ | dh_typemask(T2, 2) | dh_typemask(T3, 3) \
939
+ | dh_typemask(T4, 4) | dh_typemask(T5, 5) \
940
+ | dh_typemask(T6, 6) | dh_typemask(T7, 7) \
941
+ };
942
+
943
+#include HELPER_H
944
+
945
+#undef str
946
+#undef DEF_HELPER_FLAGS_0
947
+#undef DEF_HELPER_FLAGS_1
948
+#undef DEF_HELPER_FLAGS_2
949
+#undef DEF_HELPER_FLAGS_3
950
+#undef DEF_HELPER_FLAGS_4
951
+#undef DEF_HELPER_FLAGS_5
952
+#undef DEF_HELPER_FLAGS_6
953
+#undef DEF_HELPER_FLAGS_7
954
--
953
--
955
2.34.1
954
2.43.0
955
956
diff view generated by jsdifflib