1
TCG patch queue, plus one target/sh4 patch that
1
The following changes since commit 627634031092e1514f363fd8659a579398de0f0e:
2
Yoshinori Sato asked me to process.
3
2
4
3
Merge tag 'buildsys-qom-qdev-ui-20230227' of https://github.com/philmd/qemu into staging (2023-02-28 15:09:18 +0000)
5
r~
6
7
8
The following changes since commit efbf38d73e5dcc4d5f8b98c6e7a12be1f3b91745:
9
10
Merge tag 'for-upstream' of git://repo.or.cz/qemu/kevin into staging (2022-10-03 15:06:07 -0400)
11
4
12
are available in the Git repository at:
5
are available in the Git repository at:
13
6
14
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20221004
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20230228
15
8
16
for you to fetch changes up to ab419fd8a035a65942de4e63effcd55ccbf1a9fe:
9
for you to fetch changes up to c7fbf10db8718d2eba87712bc3410b671157a377:
17
10
18
target/sh4: Fix TB_FLAG_UNALIGN (2022-10-04 12:33:05 -0700)
11
tcg: Update docs/devel/tcg-ops.rst for temporary changes (2023-02-28 10:36:19 -1000)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
Cache CPUClass for use in hot code paths.
14
helper-head: Add fpu/softfloat-types.h
22
Add CPUTLBEntryFull, probe_access_full, tlb_set_page_full.
15
softmmu: Use memmove in flatview_write_continue
23
Add generic support for TARGET_TB_PCREL.
16
tcg: Add sign param to probe_access_flags, probe_access_full
24
tcg/ppc: Optimize 26-bit jumps using STQ for POWER 2.07
17
tcg: Convert TARGET_TB_PCREL to CF_PCREL
25
target/sh4: Fix TB_FLAG_UNALIGN
18
tcg: Simplify temporary lifetimes for translators
26
19
27
----------------------------------------------------------------
20
----------------------------------------------------------------
28
Alex Bennée (3):
21
Akihiko Odaki (1):
29
cpu: cache CPUClass in CPUState for hot code paths
22
softmmu: Use memmove in flatview_write_continue
30
hw/core/cpu-sysemu: used cached class in cpu_asidx_from_attrs
31
cputlb: used cached CPUClass in our hot-paths
32
23
33
Leandro Lupori (1):
24
Anton Johansson via (27):
34
tcg/ppc: Optimize 26-bit jumps
25
include/exec: Introduce `CF_PCREL`
26
target/i386: set `CF_PCREL` in `x86_cpu_realizefn`
27
target/arm: set `CF_PCREL` in `arm_cpu_realizefn`
28
accel/tcg: Replace `TARGET_TB_PCREL` with `CF_PCREL`
29
include/exec: Replace `TARGET_TB_PCREL` with `CF_PCREL`
30
target/arm: Replace `TARGET_TB_PCREL` with `CF_PCREL`
31
target/i386: Replace `TARGET_TB_PCREL` with `CF_PCREL`
32
include/exec: Remove `TARGET_TB_PCREL` define
33
target/arm: Remove `TARGET_TB_PCREL` define
34
target/i386: Remove `TARGET_TB_PCREL` define
35
accel/tcg: Move jmp-cache `CF_PCREL` checks to caller
36
accel/tcg: Replace `tb_pc()` with `tb->pc`
37
target/tricore: Replace `tb_pc()` with `tb->pc`
38
target/sparc: Replace `tb_pc()` with `tb->pc`
39
target/sh4: Replace `tb_pc()` with `tb->pc`
40
target/rx: Replace `tb_pc()` with `tb->pc`
41
target/riscv: Replace `tb_pc()` with `tb->pc`
42
target/openrisc: Replace `tb_pc()` with `tb->pc`
43
target/mips: Replace `tb_pc()` with `tb->pc`
44
target/microblaze: Replace `tb_pc()` with `tb->pc`
45
target/loongarch: Replace `tb_pc()` with `tb->pc`
46
target/i386: Replace `tb_pc()` with `tb->pc`
47
target/hppa: Replace `tb_pc()` with `tb->pc`
48
target/hexagon: Replace `tb_pc()` with `tb->pc`
49
target/avr: Replace `tb_pc()` with `tb->pc`
50
target/arm: Replace `tb_pc()` with `tb->pc`
51
include/exec: Remove `tb_pc()`
35
52
36
Richard Henderson (16):
53
Daniel Henrique Barboza (1):
37
accel/tcg: Rename CPUIOTLBEntry to CPUTLBEntryFull
54
accel/tcg: Add 'size' param to probe_access_flags()
38
accel/tcg: Drop addr member from SavedIOTLB
39
accel/tcg: Suppress auto-invalidate in probe_access_internal
40
accel/tcg: Introduce probe_access_full
41
accel/tcg: Introduce tlb_set_page_full
42
include/exec: Introduce TARGET_PAGE_ENTRY_EXTRA
43
accel/tcg: Remove PageDesc code_bitmap
44
accel/tcg: Use bool for page_find_alloc
45
accel/tcg: Use DisasContextBase in plugin_gen_tb_start
46
accel/tcg: Do not align tb->page_addr[0]
47
accel/tcg: Inline tb_flush_jmp_cache
48
include/hw/core: Create struct CPUJumpCache
49
hw/core: Add CPUClass.get_pc
50
accel/tcg: Introduce tb_pc and log_pc
51
accel/tcg: Introduce TARGET_TB_PCREL
52
target/sh4: Fix TB_FLAG_UNALIGN
53
55
54
accel/tcg/internal.h | 10 ++
56
Philippe Mathieu-Daudé (1):
55
accel/tcg/tb-hash.h | 1 +
57
exec/helper-head: Include missing "fpu/softfloat-types.h" header
56
accel/tcg/tb-jmp-cache.h | 65 ++++++++
57
include/exec/cpu-common.h | 1 +
58
include/exec/cpu-defs.h | 48 ++++--
59
include/exec/exec-all.h | 75 ++++++++-
60
include/exec/plugin-gen.h | 7 +-
61
include/hw/core/cpu.h | 28 ++--
62
include/qemu/typedefs.h | 2 +
63
include/tcg/tcg.h | 2 +-
64
target/sh4/cpu.h | 56 ++++---
65
accel/stubs/tcg-stub.c | 4 +
66
accel/tcg/cpu-exec.c | 80 +++++-----
67
accel/tcg/cputlb.c | 259 ++++++++++++++++++--------------
68
accel/tcg/plugin-gen.c | 22 +--
69
accel/tcg/translate-all.c | 214 ++++++++++++--------------
70
accel/tcg/translator.c | 2 +-
71
cpu.c | 9 +-
72
hw/core/cpu-common.c | 3 +-
73
hw/core/cpu-sysemu.c | 5 +-
74
linux-user/sh4/signal.c | 6 +-
75
plugins/core.c | 2 +-
76
target/alpha/cpu.c | 9 ++
77
target/arm/cpu.c | 17 ++-
78
target/arm/mte_helper.c | 14 +-
79
target/arm/sve_helper.c | 4 +-
80
target/arm/translate-a64.c | 2 +-
81
target/avr/cpu.c | 10 +-
82
target/cris/cpu.c | 8 +
83
target/hexagon/cpu.c | 10 +-
84
target/hppa/cpu.c | 12 +-
85
target/i386/cpu.c | 9 ++
86
target/i386/tcg/tcg-cpu.c | 2 +-
87
target/loongarch/cpu.c | 11 +-
88
target/m68k/cpu.c | 8 +
89
target/microblaze/cpu.c | 10 +-
90
target/mips/cpu.c | 8 +
91
target/mips/tcg/exception.c | 2 +-
92
target/mips/tcg/sysemu/special_helper.c | 2 +-
93
target/nios2/cpu.c | 9 ++
94
target/openrisc/cpu.c | 10 +-
95
target/ppc/cpu_init.c | 8 +
96
target/riscv/cpu.c | 17 ++-
97
target/rx/cpu.c | 10 +-
98
target/s390x/cpu.c | 8 +
99
target/s390x/tcg/mem_helper.c | 4 -
100
target/sh4/cpu.c | 18 ++-
101
target/sh4/helper.c | 6 +-
102
target/sh4/translate.c | 90 +++++------
103
target/sparc/cpu.c | 10 +-
104
target/tricore/cpu.c | 11 +-
105
target/xtensa/cpu.c | 8 +
106
tcg/tcg.c | 8 +-
107
trace/control-target.c | 2 +-
108
tcg/ppc/tcg-target.c.inc | 119 +++++++++++----
109
55 files changed, 915 insertions(+), 462 deletions(-)
110
create mode 100644 accel/tcg/tb-jmp-cache.h
111
58
59
Richard Henderson (32):
60
accel/tcg: Add 'size' param to probe_access_full
61
tcg: Adjust TCGContext.temps_in_use check
62
accel/tcg: Pass max_insn to gen_intermediate_code by pointer
63
accel/tcg: Use more accurate max_insns for tb_overflow
64
tcg: Remove branch-to-next regardless of reference count
65
tcg: Rename TEMP_LOCAL to TEMP_TB
66
tcg: Use noinline for major tcg_gen_code subroutines
67
tcg: Add liveness_pass_0
68
tcg: Remove TEMP_NORMAL
69
tcg: Pass TCGTempKind to tcg_temp_new_internal
70
tcg: Use tcg_constant_i32 in tcg_gen_io_start
71
tcg: Add tcg_gen_movi_ptr
72
tcg: Add tcg_temp_ebb_new_{i32,i64,ptr}
73
tcg: Use tcg_temp_ebb_new_* in tcg/
74
tcg: Use tcg_constant_ptr in do_dup
75
accel/tcg/plugin: Use tcg_temp_ebb_*
76
accel/tcg/plugin: Tidy plugin_gen_disable_mem_helpers
77
tcg: Don't re-use TEMP_TB temporaries
78
tcg: Change default temp lifetime to TEMP_TB
79
target/arm: Drop copies in gen_sve_{ldr,str}
80
target/arm: Don't use tcg_temp_local_new_*
81
target/cris: Don't use tcg_temp_local_new
82
target/hexagon: Don't use tcg_temp_local_new_*
83
target/hexagon/idef-parser: Drop gen_tmp_local
84
target/hppa: Don't use tcg_temp_local_new
85
target/i386: Don't use tcg_temp_local_new
86
target/mips: Don't use tcg_temp_local_new
87
target/ppc: Don't use tcg_temp_local_new
88
target/xtensa: Don't use tcg_temp_local_new_*
89
exec/gen-icount: Don't use tcg_temp_local_new_i32
90
tcg: Remove tcg_temp_local_new_*, tcg_const_local_*
91
tcg: Update docs/devel/tcg-ops.rst for temporary changes
92
93
docs/devel/tcg-ops.rst | 230 +++++++++++++----------
94
target/hexagon/idef-parser/README.rst | 4 +-
95
accel/tcg/internal.h | 10 +-
96
accel/tcg/tb-jmp-cache.h | 42 +----
97
include/exec/cpu-defs.h | 3 -
98
include/exec/exec-all.h | 26 +--
99
include/exec/gen-icount.h | 12 +-
100
include/exec/helper-head.h | 2 +
101
include/exec/translator.h | 4 +-
102
include/tcg/tcg-op.h | 7 +-
103
include/tcg/tcg.h | 64 ++++---
104
target/arm/cpu-param.h | 2 -
105
target/arm/tcg/translate-a64.h | 1 -
106
target/arm/tcg/translate.h | 2 +-
107
target/hexagon/gen_tcg.h | 4 +-
108
target/i386/cpu-param.h | 4 -
109
accel/stubs/tcg-stub.c | 2 +-
110
accel/tcg/cpu-exec.c | 62 ++++--
111
accel/tcg/cputlb.c | 21 ++-
112
accel/tcg/perf.c | 2 +-
113
accel/tcg/plugin-gen.c | 32 ++--
114
accel/tcg/tb-maint.c | 10 +-
115
accel/tcg/translate-all.c | 18 +-
116
accel/tcg/translator.c | 6 +-
117
accel/tcg/user-exec.c | 5 +-
118
semihosting/uaccess.c | 2 +-
119
softmmu/physmem.c | 2 +-
120
target/alpha/translate.c | 2 +-
121
target/arm/cpu.c | 17 +-
122
target/arm/ptw.c | 4 +-
123
target/arm/tcg/mte_helper.c | 4 +-
124
target/arm/tcg/sve_helper.c | 4 +-
125
target/arm/tcg/translate-a64.c | 16 +-
126
target/arm/tcg/translate-sve.c | 38 +---
127
target/arm/tcg/translate.c | 14 +-
128
target/avr/cpu.c | 3 +-
129
target/avr/translate.c | 2 +-
130
target/cris/translate.c | 8 +-
131
target/hexagon/cpu.c | 4 +-
132
target/hexagon/genptr.c | 16 +-
133
target/hexagon/idef-parser/parser-helpers.c | 26 +--
134
target/hexagon/translate.c | 4 +-
135
target/hppa/cpu.c | 8 +-
136
target/hppa/translate.c | 5 +-
137
target/i386/cpu.c | 5 +
138
target/i386/helper.c | 2 +-
139
target/i386/tcg/sysemu/excp_helper.c | 4 +-
140
target/i386/tcg/tcg-cpu.c | 8 +-
141
target/i386/tcg/translate.c | 55 +++---
142
target/loongarch/cpu.c | 6 +-
143
target/loongarch/translate.c | 2 +-
144
target/m68k/translate.c | 2 +-
145
target/microblaze/cpu.c | 4 +-
146
target/microblaze/translate.c | 2 +-
147
target/mips/tcg/exception.c | 3 +-
148
target/mips/tcg/sysemu/special_helper.c | 2 +-
149
target/mips/tcg/translate.c | 59 ++----
150
target/nios2/translate.c | 2 +-
151
target/openrisc/cpu.c | 4 +-
152
target/openrisc/translate.c | 2 +-
153
target/ppc/translate.c | 8 +-
154
target/riscv/cpu.c | 7 +-
155
target/riscv/translate.c | 2 +-
156
target/rx/cpu.c | 3 +-
157
target/rx/translate.c | 2 +-
158
target/s390x/tcg/mem_helper.c | 2 +-
159
target/s390x/tcg/translate.c | 2 +-
160
target/sh4/cpu.c | 6 +-
161
target/sh4/translate.c | 2 +-
162
target/sparc/cpu.c | 4 +-
163
target/sparc/translate.c | 2 +-
164
target/tricore/cpu.c | 3 +-
165
target/tricore/translate.c | 2 +-
166
target/xtensa/translate.c | 18 +-
167
tcg/optimize.c | 2 +-
168
tcg/tcg-op-gvec.c | 189 ++++++++++---------
169
tcg/tcg-op.c | 258 ++++++++++++-------------
170
tcg/tcg.c | 280 ++++++++++++++++------------
171
target/cris/translate_v10.c.inc | 10 +-
172
target/mips/tcg/nanomips_translate.c.inc | 4 +-
173
target/ppc/translate/spe-impl.c.inc | 8 +-
174
target/ppc/translate/vmx-impl.c.inc | 4 +-
175
target/hexagon/README | 8 +-
176
target/hexagon/gen_tcg_funcs.py | 18 +-
177
84 files changed, 870 insertions(+), 890 deletions(-)
178
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
'dh_ctype_f32' is defined as 'float32', itself declared
4
in "fpu/softfloat-types.h". Include this header to avoid
5
when refactoring other headers:
6
7
In file included from include/exec/helper-proto.h:7,
8
from include/tcg/tcg-op.h:29,
9
from ../../tcg/tcg-op-vec.c:22:
10
include/exec/helper-head.h:44:22: error: unknown type name ‘float32’; did you mean ‘_Float32’?
11
44 | #define dh_ctype_f32 float32
12
| ^~~~~~~
13
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Message-Id: <20221216225202.25664-1-philmd@linaro.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
---
18
include/exec/helper-head.h | 2 ++
19
1 file changed, 2 insertions(+)
20
21
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/exec/helper-head.h
24
+++ b/include/exec/helper-head.h
25
@@ -XXX,XX +XXX,XX @@
26
#ifndef EXEC_HELPER_HEAD_H
27
#define EXEC_HELPER_HEAD_H
28
29
+#include "fpu/softfloat-types.h"
30
+
31
#define HELPER(name) glue(helper_, name)
32
33
/* Some types that make sense in C, but not for TCG. */
34
--
35
2.34.1
36
37
diff view generated by jsdifflib
New patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
2
3
We found a case where the source passed to flatview_write_continue() may
4
overlap with the destination when fuzzing igb, a new proposed network
5
device with sanitizers.
6
7
igb uses pci_dma_map() to get Tx packet, and pci_dma_write() to write Rx
8
buffer. While pci_dma_write() is usually used to write data from
9
memory not mapped to the guest, if igb is configured to perform
10
loopback, the data will be sourced from the guest memory. The source and
11
destination can overlap and the usage of memcpy() will be invalid in
12
such a case.
13
14
While we do not really have to deal with such an invalid request for
15
igb, detecting the overlap in igb code beforehand requires complex code,
16
and only covers this specific case. Instead, just replace memcpy() with
17
memmove() to tolerate overlaps. Using memmove() will slightly damage the
18
performance as it will need to check overlaps before using SIMD
19
instructions for copying, but the cost should be negligible, considering
20
the inherent complexity of flatview_write_continue().
21
22
The test cases generated by the fuzzer is available at:
23
https://patchew.org/QEMU/20230129053316.1071513-1-alxndr@bu.edu/
24
25
The fixed test case is:
26
fuzz/crash_47dfe62d9f911bf523ff48cd441b61c0013ed805
27
28
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
29
Acked-by: Alexander Bulekov <alxndr@bu.edu>
30
Acked-by: David Hildenbrand <david@redhat.com>
31
Message-Id: <20230131030155.18932-1-akihiko.odaki@daynix.com>
32
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
33
---
34
softmmu/physmem.c | 2 +-
35
1 file changed, 1 insertion(+), 1 deletion(-)
36
37
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/softmmu/physmem.c
40
+++ b/softmmu/physmem.c
41
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
42
} else {
43
/* RAM case */
44
ram_ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
45
- memcpy(ram_ptr, buf, l);
46
+ memmove(ram_ptr, buf, l);
47
invalidate_and_set_dirty(mr, addr1, l);
48
}
49
50
--
51
2.34.1
diff view generated by jsdifflib
1
When PAGE_WRITE_INV is set when calling tlb_set_page,
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
we immediately set TLB_INVALID_MASK in order to force
3
tlb_fill to be called on the next lookup. Here in
4
probe_access_internal, we have just called tlb_fill
5
and eliminated true misses, thus the lookup must be valid.
6
2
7
This allows us to remove a warning comment from s390x.
3
probe_access_flags() as it is today uses probe_access_full(), which in
8
There doesn't seem to be a reason to change the code though.
4
turn uses probe_access_internal() with size = 0. probe_access_internal()
5
then uses the size to call the tlb_fill() callback for the given CPU.
6
This size param ('fault_size' as probe_access_internal() calls it) is
7
ignored by most existing .tlb_fill callback implementations, e.g.
8
arm_cpu_tlb_fill(), ppc_cpu_tlb_fill(), x86_cpu_tlb_fill() and
9
mips_cpu_tlb_fill() to name a few.
9
10
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
But RISC-V riscv_cpu_tlb_fill() actually uses it. The 'size' parameter
11
Reviewed-by: David Hildenbrand <david@redhat.com>
12
is used to check for PMP (Physical Memory Protection) access. This is
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
necessary because PMP does not make any guarantees about all the bytes
14
of the same page having the same permissions, i.e. the same page can
15
have different PMP properties, so we're forced to make sub-page range
16
checks. To allow RISC-V emulation to do a probe_acess_flags() that
17
covers PMP, we need to either add a 'size' param to the existing
18
probe_acess_flags() or create a new interface (e.g.
19
probe_access_range_flags).
20
21
There are quite a few probe_* APIs already, so let's add a 'size' param
22
to probe_access_flags() and re-use this API. This is done by open coding
23
what probe_access_full() does inside probe_acess_flags() and passing the
24
'size' param to probe_acess_internal(). Existing probe_access_flags()
25
callers use size = 0 to not change their current API usage. 'size' is
26
asserted to enforce single page access like probe_access() already does.
27
28
No behavioral changes intended.
29
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Message-Id: <20230223234427.521114-2-dbarboza@ventanamicro.com>
32
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
33
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
---
34
---
15
accel/tcg/cputlb.c | 10 +++++++++-
35
include/exec/exec-all.h | 3 ++-
16
target/s390x/tcg/mem_helper.c | 4 ----
36
accel/stubs/tcg-stub.c | 2 +-
17
2 files changed, 9 insertions(+), 5 deletions(-)
37
accel/tcg/cputlb.c | 17 ++++++++++++++---
38
accel/tcg/user-exec.c | 5 +++--
39
semihosting/uaccess.c | 2 +-
40
target/arm/ptw.c | 2 +-
41
target/arm/tcg/sve_helper.c | 2 +-
42
target/s390x/tcg/mem_helper.c | 2 +-
43
8 files changed, 24 insertions(+), 11 deletions(-)
18
44
45
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/include/exec/exec-all.h
48
+++ b/include/exec/exec-all.h
49
@@ -XXX,XX +XXX,XX @@ static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
50
* probe_access_flags:
51
* @env: CPUArchState
52
* @addr: guest virtual address to look up
53
+ * @size: size of the access
54
* @access_type: read, write or execute permission
55
* @mmu_idx: MMU index to use for lookup
56
* @nonfault: suppress the fault
57
@@ -XXX,XX +XXX,XX @@ static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
58
* Do handle clean pages, so exclude TLB_NOTDIRY from the returned flags.
59
* For simplicity, all "mmio-like" flags are folded to TLB_MMIO.
60
*/
61
-int probe_access_flags(CPUArchState *env, target_ulong addr,
62
+int probe_access_flags(CPUArchState *env, target_ulong addr, int size,
63
MMUAccessType access_type, int mmu_idx,
64
bool nonfault, void **phost, uintptr_t retaddr);
65
66
diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/accel/stubs/tcg-stub.c
69
+++ b/accel/stubs/tcg-stub.c
70
@@ -XXX,XX +XXX,XX @@ void tcg_flush_jmp_cache(CPUState *cpu)
71
{
72
}
73
74
-int probe_access_flags(CPUArchState *env, target_ulong addr,
75
+int probe_access_flags(CPUArchState *env, target_ulong addr, int size,
76
MMUAccessType access_type, int mmu_idx,
77
bool nonfault, void **phost, uintptr_t retaddr)
78
{
19
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
79
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
20
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
21
--- a/accel/tcg/cputlb.c
81
--- a/accel/tcg/cputlb.c
22
+++ b/accel/tcg/cputlb.c
82
+++ b/accel/tcg/cputlb.c
83
@@ -XXX,XX +XXX,XX @@ int probe_access_full(CPUArchState *env, target_ulong addr,
84
return flags;
85
}
86
87
-int probe_access_flags(CPUArchState *env, target_ulong addr,
88
+int probe_access_flags(CPUArchState *env, target_ulong addr, int size,
89
MMUAccessType access_type, int mmu_idx,
90
bool nonfault, void **phost, uintptr_t retaddr)
91
{
92
CPUTLBEntryFull *full;
93
+ int flags;
94
95
- return probe_access_full(env, addr, access_type, mmu_idx,
96
- nonfault, phost, &full, retaddr);
97
+ g_assert(-(addr | TARGET_PAGE_MASK) >= size);
98
+
99
+ flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
100
+ nonfault, phost, &full, retaddr);
101
+
102
+ /* Handle clean RAM pages. */
103
+ if (unlikely(flags & TLB_NOTDIRTY)) {
104
+ notdirty_write(env_cpu(env), addr, 1, full, retaddr);
105
+ flags &= ~TLB_NOTDIRTY;
106
+ }
107
+
108
+ return flags;
109
}
110
111
void *probe_access(CPUArchState *env, target_ulong addr, int size,
112
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/accel/tcg/user-exec.c
115
+++ b/accel/tcg/user-exec.c
23
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
116
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
24
}
117
cpu_loop_exit_sigsegv(env_cpu(env), addr, access_type, maperr, ra);
25
tlb_addr = tlb_read_ofs(entry, elt_ofs);
118
}
26
119
27
+ flags = TLB_FLAGS_MASK;
120
-int probe_access_flags(CPUArchState *env, target_ulong addr,
28
page_addr = addr & TARGET_PAGE_MASK;
121
+int probe_access_flags(CPUArchState *env, target_ulong addr, int size,
29
if (!tlb_hit_page(tlb_addr, page_addr)) {
122
MMUAccessType access_type, int mmu_idx,
30
if (!victim_tlb_hit(env, mmu_idx, index, elt_ofs, page_addr)) {
123
bool nonfault, void **phost, uintptr_t ra)
31
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
124
{
32
125
int flags;
33
/* TLB resize via tlb_fill may have moved the entry. */
126
34
entry = tlb_entry(env, mmu_idx, addr);
127
- flags = probe_access_internal(env, addr, 0, access_type, nonfault, ra);
35
+
128
+ g_assert(-(addr | TARGET_PAGE_MASK) >= size);
36
+ /*
129
+ flags = probe_access_internal(env, addr, size, access_type, nonfault, ra);
37
+ * With PAGE_WRITE_INV, we set TLB_INVALID_MASK immediately,
130
*phost = flags ? NULL : g2h(env_cpu(env), addr);
38
+ * to force the next access through tlb_fill. We've just
131
return flags;
39
+ * called tlb_fill, so we know that this entry *is* valid.
132
}
40
+ */
133
diff --git a/semihosting/uaccess.c b/semihosting/uaccess.c
41
+ flags &= ~TLB_INVALID_MASK;
134
index XXXXXXX..XXXXXXX 100644
42
}
135
--- a/semihosting/uaccess.c
43
tlb_addr = tlb_read_ofs(entry, elt_ofs);
136
+++ b/semihosting/uaccess.c
44
}
137
@@ -XXX,XX +XXX,XX @@ ssize_t softmmu_strlen_user(CPUArchState *env, target_ulong addr)
45
- flags = tlb_addr & TLB_FLAGS_MASK;
138
/* Find the number of bytes remaining in the page. */
46
+ flags &= tlb_addr;
139
left_in_page = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK);
47
140
48
/* Fold all "mmio-like" bits into TLB_MMIO. This is not RAM. */
141
- flags = probe_access_flags(env, addr, MMU_DATA_LOAD,
49
if (unlikely(flags & ~(TLB_WATCHPOINT | TLB_NOTDIRTY))) {
142
+ flags = probe_access_flags(env, addr, 0, MMU_DATA_LOAD,
143
mmu_idx, true, &h, 0);
144
if (flags & TLB_INVALID_MASK) {
145
return -1;
146
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/target/arm/ptw.c
149
+++ b/target/arm/ptw.c
150
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
151
void *discard;
152
153
env->tlb_fi = fi;
154
- flags = probe_access_flags(env, ptw->out_virt, MMU_DATA_STORE,
155
+ flags = probe_access_flags(env, ptw->out_virt, 0, MMU_DATA_STORE,
156
arm_to_core_mmu_idx(ptw->in_ptw_idx),
157
true, &discard, 0);
158
env->tlb_fi = NULL;
159
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/tcg/sve_helper.c
162
+++ b/target/arm/tcg/sve_helper.c
163
@@ -XXX,XX +XXX,XX @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
164
addr = useronly_clean_ptr(addr);
165
166
#ifdef CONFIG_USER_ONLY
167
- flags = probe_access_flags(env, addr, access_type, mmu_idx, nofault,
168
+ flags = probe_access_flags(env, addr, 0, access_type, mmu_idx, nofault,
169
&info->host, retaddr);
170
#else
171
CPUTLBEntryFull *full;
50
diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
172
diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
51
index XXXXXXX..XXXXXXX 100644
173
index XXXXXXX..XXXXXXX 100644
52
--- a/target/s390x/tcg/mem_helper.c
174
--- a/target/s390x/tcg/mem_helper.c
53
+++ b/target/s390x/tcg/mem_helper.c
175
+++ b/target/s390x/tcg/mem_helper.c
54
@@ -XXX,XX +XXX,XX @@ static int s390_probe_access(CPUArchState *env, target_ulong addr, int size,
176
@@ -XXX,XX +XXX,XX @@ static inline int s390_probe_access(CPUArchState *env, target_ulong addr,
55
#else
177
int mmu_idx, bool nonfault,
56
int flags;
178
void **phost, uintptr_t ra)
57
179
{
58
- /*
180
- int flags = probe_access_flags(env, addr, access_type, mmu_idx,
59
- * For !CONFIG_USER_ONLY, we cannot rely on TLB_INVALID_MASK or haddr==NULL
181
+ int flags = probe_access_flags(env, addr, 0, access_type, mmu_idx,
60
- * to detect if there was an exception during tlb_fill().
182
nonfault, phost, ra);
61
- */
183
62
env->tlb_fill_exc = 0;
184
if (unlikely(flags & TLB_INVALID_MASK)) {
63
flags = probe_access_flags(env, addr, access_type, mmu_idx, nonfault, phost,
64
ra);
65
--
185
--
66
2.34.1
186
2.34.1
67
68
diff view generated by jsdifflib
1
Add an interface to return the CPUTLBEntryFull struct
1
Change to match the recent change to probe_access_flags.
2
that goes with the lookup. The result is not intended
2
All existing callers updated to supply 0, so no change in behaviour.
3
to be valid across multiple lookups, so the user must
4
use the results immediately.
5
3
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
7
---
11
include/exec/exec-all.h | 15 +++++++++++++
8
include/exec/exec-all.h | 2 +-
12
include/qemu/typedefs.h | 1 +
9
accel/tcg/cputlb.c | 4 ++--
13
accel/tcg/cputlb.c | 47 +++++++++++++++++++++++++----------------
10
target/arm/ptw.c | 2 +-
14
3 files changed, 45 insertions(+), 18 deletions(-)
11
target/arm/tcg/mte_helper.c | 4 ++--
12
target/arm/tcg/sve_helper.c | 2 +-
13
target/arm/tcg/translate-a64.c | 2 +-
14
target/i386/tcg/sysemu/excp_helper.c | 4 ++--
15
7 files changed, 10 insertions(+), 10 deletions(-)
15
16
16
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
17
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/include/exec/exec-all.h
19
--- a/include/exec/exec-all.h
19
+++ b/include/exec/exec-all.h
20
+++ b/include/exec/exec-all.h
20
@@ -XXX,XX +XXX,XX @@ int probe_access_flags(CPUArchState *env, target_ulong addr,
21
@@ -XXX,XX +XXX,XX @@ int probe_access_flags(CPUArchState *env, target_ulong addr, int size,
21
MMUAccessType access_type, int mmu_idx,
22
* and must be consumed or copied immediately, before any further
22
bool nonfault, void **phost, uintptr_t retaddr);
23
* access or changes to TLB @mmu_idx.
23
24
*/
24
+#ifndef CONFIG_USER_ONLY
25
-int probe_access_full(CPUArchState *env, target_ulong addr,
25
+/**
26
+int probe_access_full(CPUArchState *env, target_ulong addr, int size,
26
+ * probe_access_full:
27
MMUAccessType access_type, int mmu_idx,
27
+ * Like probe_access_flags, except also return into @pfull.
28
bool nonfault, void **phost,
28
+ *
29
CPUTLBEntryFull **pfull, uintptr_t retaddr);
29
+ * The CPUTLBEntryFull structure returned via @pfull is transient
30
+ * and must be consumed or copied immediately, before any further
31
+ * access or changes to TLB @mmu_idx.
32
+ */
33
+int probe_access_full(CPUArchState *env, target_ulong addr,
34
+ MMUAccessType access_type, int mmu_idx,
35
+ bool nonfault, void **phost,
36
+ CPUTLBEntryFull **pfull, uintptr_t retaddr);
37
+#endif
38
+
39
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
40
41
/* Estimated block size for TB allocation. */
42
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/include/qemu/typedefs.h
45
+++ b/include/qemu/typedefs.h
46
@@ -XXX,XX +XXX,XX @@ typedef struct ConfidentialGuestSupport ConfidentialGuestSupport;
47
typedef struct CPUAddressSpace CPUAddressSpace;
48
typedef struct CPUArchState CPUArchState;
49
typedef struct CPUState CPUState;
50
+typedef struct CPUTLBEntryFull CPUTLBEntryFull;
51
typedef struct DeviceListener DeviceListener;
52
typedef struct DeviceState DeviceState;
53
typedef struct DirtyBitmapSnapshot DirtyBitmapSnapshot;
54
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
30
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
55
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
56
--- a/accel/tcg/cputlb.c
32
--- a/accel/tcg/cputlb.c
57
+++ b/accel/tcg/cputlb.c
33
+++ b/accel/tcg/cputlb.c
58
@@ -XXX,XX +XXX,XX @@ static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size,
59
static int probe_access_internal(CPUArchState *env, target_ulong addr,
60
int fault_size, MMUAccessType access_type,
61
int mmu_idx, bool nonfault,
62
- void **phost, uintptr_t retaddr)
63
+ void **phost, CPUTLBEntryFull **pfull,
64
+ uintptr_t retaddr)
65
{
66
uintptr_t index = tlb_index(env, mmu_idx, addr);
67
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
68
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
69
mmu_idx, nonfault, retaddr)) {
70
/* Non-faulting page table read failed. */
71
*phost = NULL;
72
+ *pfull = NULL;
73
return TLB_INVALID_MASK;
74
}
75
76
/* TLB resize via tlb_fill may have moved the entry. */
77
+ index = tlb_index(env, mmu_idx, addr);
78
entry = tlb_entry(env, mmu_idx, addr);
79
80
/*
81
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
82
}
83
flags &= tlb_addr;
84
85
+ *pfull = &env_tlb(env)->d[mmu_idx].fulltlb[index];
86
+
87
/* Fold all "mmio-like" bits into TLB_MMIO. This is not RAM. */
88
if (unlikely(flags & ~(TLB_WATCHPOINT | TLB_NOTDIRTY))) {
89
*phost = NULL;
90
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
34
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
91
return flags;
35
return flags;
92
}
36
}
93
37
94
-int probe_access_flags(CPUArchState *env, target_ulong addr,
38
-int probe_access_full(CPUArchState *env, target_ulong addr,
95
- MMUAccessType access_type, int mmu_idx,
39
+int probe_access_full(CPUArchState *env, target_ulong addr, int size,
96
- bool nonfault, void **phost, uintptr_t retaddr)
40
MMUAccessType access_type, int mmu_idx,
97
+int probe_access_full(CPUArchState *env, target_ulong addr,
41
bool nonfault, void **phost, CPUTLBEntryFull **pfull,
98
+ MMUAccessType access_type, int mmu_idx,
42
uintptr_t retaddr)
99
+ bool nonfault, void **phost, CPUTLBEntryFull **pfull,
100
+ uintptr_t retaddr)
101
{
43
{
102
- int flags;
44
- int flags = probe_access_internal(env, addr, 0, access_type, mmu_idx,
103
-
45
+ int flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
104
- flags = probe_access_internal(env, addr, 0, access_type, mmu_idx,
46
nonfault, phost, pfull, retaddr);
105
- nonfault, phost, retaddr);
106
+ int flags = probe_access_internal(env, addr, 0, access_type, mmu_idx,
107
+ nonfault, phost, pfull, retaddr);
108
47
109
/* Handle clean RAM pages. */
48
/* Handle clean RAM pages. */
110
if (unlikely(flags & TLB_NOTDIRTY)) {
49
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
111
- uintptr_t index = tlb_index(env, mmu_idx, addr);
50
index XXXXXXX..XXXXXXX 100644
112
- CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
51
--- a/target/arm/ptw.c
113
-
52
+++ b/target/arm/ptw.c
114
- notdirty_write(env_cpu(env), addr, 1, full, retaddr);
53
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
115
+ notdirty_write(env_cpu(env), addr, 1, *pfull, retaddr);
54
int flags;
116
flags &= ~TLB_NOTDIRTY;
55
56
env->tlb_fi = fi;
57
- flags = probe_access_full(env, addr, MMU_DATA_LOAD,
58
+ flags = probe_access_full(env, addr, 0, MMU_DATA_LOAD,
59
arm_to_core_mmu_idx(s2_mmu_idx),
60
true, &ptw->out_host, &full, 0);
61
env->tlb_fi = NULL;
62
diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/arm/tcg/mte_helper.c
65
+++ b/target/arm/tcg/mte_helper.c
66
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
67
* valid. Indicate to probe_access_flags no-fault, then assert that
68
* we received a valid page.
69
*/
70
- flags = probe_access_full(env, ptr, ptr_access, ptr_mmu_idx,
71
+ flags = probe_access_full(env, ptr, 0, ptr_access, ptr_mmu_idx,
72
ra == 0, &host, &full, ra);
73
assert(!(flags & TLB_INVALID_MASK));
74
75
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
76
*/
77
in_page = -(ptr | TARGET_PAGE_MASK);
78
if (unlikely(ptr_size > in_page)) {
79
- flags |= probe_access_full(env, ptr + in_page, ptr_access,
80
+ flags |= probe_access_full(env, ptr + in_page, 0, ptr_access,
81
ptr_mmu_idx, ra == 0, &host, &full, ra);
82
assert(!(flags & TLB_INVALID_MASK));
117
}
83
}
118
84
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
119
return flags;
85
index XXXXXXX..XXXXXXX 100644
120
}
86
--- a/target/arm/tcg/sve_helper.c
121
87
+++ b/target/arm/tcg/sve_helper.c
122
+int probe_access_flags(CPUArchState *env, target_ulong addr,
88
@@ -XXX,XX +XXX,XX @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
123
+ MMUAccessType access_type, int mmu_idx,
89
&info->host, retaddr);
124
+ bool nonfault, void **phost, uintptr_t retaddr)
90
#else
125
+{
91
CPUTLBEntryFull *full;
126
+ CPUTLBEntryFull *full;
92
- flags = probe_access_full(env, addr, access_type, mmu_idx, nofault,
127
+
93
+ flags = probe_access_full(env, addr, 0, access_type, mmu_idx, nofault,
128
+ return probe_access_full(env, addr, access_type, mmu_idx,
94
&info->host, &full, retaddr);
129
+ nonfault, phost, &full, retaddr);
95
#endif
130
+}
96
info->flags = flags;
131
+
97
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
132
void *probe_access(CPUArchState *env, target_ulong addr, int size,
98
index XXXXXXX..XXXXXXX 100644
133
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
99
--- a/target/arm/tcg/translate-a64.c
134
{
100
+++ b/target/arm/tcg/translate-a64.c
135
+ CPUTLBEntryFull *full;
101
@@ -XXX,XX +XXX,XX @@ static bool is_guarded_page(CPUARMState *env, DisasContext *s)
136
void *host;
102
* that the TLB entry must be present and valid, and thus this
103
* access will never raise an exception.
104
*/
105
- flags = probe_access_full(env, addr, MMU_INST_FETCH, mmu_idx,
106
+ flags = probe_access_full(env, addr, 0, MMU_INST_FETCH, mmu_idx,
107
false, &host, &full, 0);
108
assert(!(flags & TLB_INVALID_MASK));
109
110
diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/i386/tcg/sysemu/excp_helper.c
113
+++ b/target/i386/tcg/sysemu/excp_helper.c
114
@@ -XXX,XX +XXX,XX @@ static bool ptw_translate(PTETranslate *inout, hwaddr addr)
137
int flags;
115
int flags;
138
116
139
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
117
inout->gaddr = addr;
140
118
- flags = probe_access_full(inout->env, addr, MMU_DATA_STORE,
141
flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
119
+ flags = probe_access_full(inout->env, addr, 0, MMU_DATA_STORE,
142
- false, &host, retaddr);
120
inout->ptw_idx, true, &inout->haddr, &full, 0);
143
+ false, &host, &full, retaddr);
121
144
122
if (unlikely(flags & TLB_INVALID_MASK)) {
145
/* Per the interface, size == 0 merely faults the access. */
123
@@ -XXX,XX +XXX,XX @@ do_check_protect_pse36:
146
if (size == 0) {
124
CPUTLBEntryFull *full;
147
@@ -XXX,XX +XXX,XX @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
125
int flags, nested_page_size;
148
}
126
149
127
- flags = probe_access_full(env, paddr, access_type,
150
if (unlikely(flags & (TLB_NOTDIRTY | TLB_WATCHPOINT))) {
128
+ flags = probe_access_full(env, paddr, 0, access_type,
151
- uintptr_t index = tlb_index(env, mmu_idx, addr);
129
MMU_NESTED_IDX, true,
152
- CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
130
&pte_trans.haddr, &full, 0);
153
-
131
if (unlikely(flags & TLB_INVALID_MASK)) {
154
/* Handle watchpoints. */
155
if (flags & TLB_WATCHPOINT) {
156
int wp_access = (access_type == MMU_DATA_STORE
157
@@ -XXX,XX +XXX,XX @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
158
void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
159
MMUAccessType access_type, int mmu_idx)
160
{
161
+ CPUTLBEntryFull *full;
162
void *host;
163
int flags;
164
165
flags = probe_access_internal(env, addr, 0, access_type,
166
- mmu_idx, true, &host, 0);
167
+ mmu_idx, true, &host, &full, 0);
168
169
/* No combination of flags are expected by the caller. */
170
return flags ? NULL : host;
171
@@ -XXX,XX +XXX,XX @@ void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
172
tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
173
void **hostp)
174
{
175
+ CPUTLBEntryFull *full;
176
void *p;
177
178
(void)probe_access_internal(env, addr, 1, MMU_INST_FETCH,
179
- cpu_mmu_index(env, true), false, &p, 0);
180
+ cpu_mmu_index(env, true), false, &p, &full, 0);
181
if (p == NULL) {
182
return -1;
183
}
184
--
132
--
185
2.34.1
133
2.34.1
186
134
187
135
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Adds a new field to TranslationBlock.cflags denoting whether or not the
4
instructions of a given translation block are pc-relative. This field
5
aims to replace the macro `TARGET_TB_PCREL`.
6
7
Signed-off-by: Anton Johansson <anjo@rev.ng>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-Id: <20230227135202.9710-2-anjo@rev.ng>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
13
include/exec/exec-all.h | 1 +
14
1 file changed, 1 insertion(+)
15
16
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/exec/exec-all.h
19
+++ b/include/exec/exec-all.h
20
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock {
21
#define CF_INVALID 0x00040000 /* TB is stale. Set with @jmp_lock held */
22
#define CF_PARALLEL 0x00080000 /* Generate code for a parallel context */
23
#define CF_NOIRQ 0x00100000 /* Generate an uninterruptible TB */
24
+#define CF_PCREL 0x00200000 /* Opcodes in TB are PC-relative */
25
#define CF_CLUSTER_MASK 0xff000000 /* Top 8 bits are cluster ID */
26
#define CF_CLUSTER_SHIFT 24
27
28
--
29
2.34.1
30
31
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-3-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/i386/cpu.c | 5 +++++
9
1 file changed, 5 insertions(+)
10
11
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/i386/cpu.c
14
+++ b/target/i386/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
16
static bool ht_warned;
17
unsigned requested_lbr_fmt;
18
19
+ /* Use pc-relative instructions in system-mode */
20
+#ifndef CONFIG_USER_ONLY
21
+ cs->tcg_cflags |= CF_PCREL;
22
+#endif
23
+
24
if (cpu->apic_id == UNASSIGNED_APIC_ID) {
25
error_setg(errp, "apic-id property was not initialized properly");
26
return;
27
--
28
2.34.1
29
30
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-4-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/arm/cpu.c | 5 +++++
9
1 file changed, 5 insertions(+)
10
11
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.c
14
+++ b/target/arm/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
16
Error *local_err = NULL;
17
bool no_aa32 = false;
18
19
+ /* Use pc-relative instructions in system-mode */
20
+#ifndef CONFIG_USER_ONLY
21
+ cs->tcg_cflags |= CF_PCREL;
22
+#endif
23
+
24
/* If we needed to query the host kernel for the CPU features
25
* then it's possible that might have failed in the initfn, but
26
* this is the first point where we can report it.
27
--
28
2.34.1
29
30
diff view generated by jsdifflib
1
Prepare for targets to be able to produce TBs that can
1
From: Anton Johansson via <qemu-devel@nongnu.org>
2
run in more than one virtual context.
2
3
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-5-anjo@rev.ng>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
---
7
accel/tcg/internal.h | 4 +++
8
accel/tcg/internal.h | 10 ++++----
8
accel/tcg/tb-jmp-cache.h | 41 +++++++++++++++++++++++++
9
accel/tcg/tb-jmp-cache.h | 48 +++++++++++++++++++--------------------
9
include/exec/cpu-defs.h | 3 ++
10
accel/tcg/cpu-exec.c | 8 +++----
10
include/exec/exec-all.h | 32 ++++++++++++++++++--
11
accel/tcg/perf.c | 2 +-
11
accel/tcg/cpu-exec.c | 16 ++++++----
12
accel/tcg/tb-maint.c | 8 +++----
12
accel/tcg/translate-all.c | 64 ++++++++++++++++++++++++++-------------
13
accel/tcg/translate-all.c | 14 ++++++------
13
6 files changed, 131 insertions(+), 29 deletions(-)
14
6 files changed, 44 insertions(+), 46 deletions(-)
14
15
15
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
16
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/tcg/internal.h
18
--- a/accel/tcg/internal.h
18
+++ b/accel/tcg/internal.h
19
+++ b/accel/tcg/internal.h
19
@@ -XXX,XX +XXX,XX @@ void tb_htable_init(void);
20
@@ -XXX,XX +XXX,XX @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
20
/* Return the current PC from CPU, which may be cached in TB. */
21
/* Return the current PC from CPU, which may be cached in TB. */
21
static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
22
static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
22
{
23
{
23
+#if TARGET_TB_PCREL
24
-#if TARGET_TB_PCREL
24
+ return cpu->cc->get_pc(cpu);
25
- return cpu->cc->get_pc(cpu);
25
+#else
26
-#else
26
return tb_pc(tb);
27
- return tb_pc(tb);
27
+#endif
28
-#endif
28
}
29
+ if (tb_cflags(tb) & CF_PCREL) {
29
30
+ return cpu->cc->get_pc(cpu);
30
#endif /* ACCEL_TCG_INTERNAL_H */
31
+ } else {
32
+ return tb_pc(tb);
33
+ }
34
}
35
36
extern int64_t max_delay;
31
diff --git a/accel/tcg/tb-jmp-cache.h b/accel/tcg/tb-jmp-cache.h
37
diff --git a/accel/tcg/tb-jmp-cache.h b/accel/tcg/tb-jmp-cache.h
32
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
33
--- a/accel/tcg/tb-jmp-cache.h
39
--- a/accel/tcg/tb-jmp-cache.h
34
+++ b/accel/tcg/tb-jmp-cache.h
40
+++ b/accel/tcg/tb-jmp-cache.h
35
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@
36
42
37
/*
43
/*
38
* Accessed in parallel; all accesses to 'tb' must be atomic.
44
* Accessed in parallel; all accesses to 'tb' must be atomic.
39
+ * For TARGET_TB_PCREL, accesses to 'pc' must be protected by
45
- * For TARGET_TB_PCREL, accesses to 'pc' must be protected by
40
+ * a load_acquire/store_release to 'tb'.
46
- * a load_acquire/store_release to 'tb'.
47
+ * For CF_PCREL, accesses to 'pc' must be protected by a
48
+ * load_acquire/store_release to 'tb'.
41
*/
49
*/
42
struct CPUJumpCache {
50
struct CPUJumpCache {
51
struct rcu_head rcu;
43
struct {
52
struct {
44
TranslationBlock *tb;
53
TranslationBlock *tb;
45
+#if TARGET_TB_PCREL
54
-#if TARGET_TB_PCREL
46
+ target_ulong pc;
55
target_ulong pc;
47
+#endif
56
-#endif
48
} array[TB_JMP_CACHE_SIZE];
57
} array[TB_JMP_CACHE_SIZE];
49
};
58
};
50
59
51
+static inline TranslationBlock *
60
static inline TranslationBlock *
52
+tb_jmp_cache_get_tb(CPUJumpCache *jc, uint32_t hash)
61
-tb_jmp_cache_get_tb(CPUJumpCache *jc, uint32_t hash)
53
+{
62
+tb_jmp_cache_get_tb(CPUJumpCache *jc, uint32_t cflags, uint32_t hash)
54
+#if TARGET_TB_PCREL
63
{
55
+ /* Use acquire to ensure current load of pc from jc. */
64
-#if TARGET_TB_PCREL
56
+ return qatomic_load_acquire(&jc->array[hash].tb);
65
- /* Use acquire to ensure current load of pc from jc. */
57
+#else
66
- return qatomic_load_acquire(&jc->array[hash].tb);
58
+ /* Use rcu_read to ensure current load of pc from *tb. */
67
-#else
59
+ return qatomic_rcu_read(&jc->array[hash].tb);
68
- /* Use rcu_read to ensure current load of pc from *tb. */
60
+#endif
69
- return qatomic_rcu_read(&jc->array[hash].tb);
61
+}
70
-#endif
62
+
71
+ if (cflags & CF_PCREL) {
63
+static inline target_ulong
72
+ /* Use acquire to ensure current load of pc from jc. */
64
+tb_jmp_cache_get_pc(CPUJumpCache *jc, uint32_t hash, TranslationBlock *tb)
73
+ return qatomic_load_acquire(&jc->array[hash].tb);
65
+{
74
+ } else {
66
+#if TARGET_TB_PCREL
75
+ /* Use rcu_read to ensure current load of pc from *tb. */
67
+ return jc->array[hash].pc;
76
+ return qatomic_rcu_read(&jc->array[hash].tb);
68
+#else
77
+ }
69
+ return tb_pc(tb);
78
}
70
+#endif
79
71
+}
80
static inline target_ulong
72
+
81
tb_jmp_cache_get_pc(CPUJumpCache *jc, uint32_t hash, TranslationBlock *tb)
73
+static inline void
82
{
74
+tb_jmp_cache_set(CPUJumpCache *jc, uint32_t hash,
83
-#if TARGET_TB_PCREL
75
+ TranslationBlock *tb, target_ulong pc)
84
- return jc->array[hash].pc;
76
+{
85
-#else
77
+#if TARGET_TB_PCREL
86
- return tb_pc(tb);
78
+ jc->array[hash].pc = pc;
87
-#endif
79
+ /* Use store_release on tb to ensure pc is written first. */
88
+ if (tb_cflags(tb) & CF_PCREL) {
80
+ qatomic_store_release(&jc->array[hash].tb, tb);
89
+ return jc->array[hash].pc;
81
+#else
90
+ } else {
82
+ /* Use the pc value already stored in tb->pc. */
91
+ return tb_pc(tb);
83
+ qatomic_set(&jc->array[hash].tb, tb);
92
+ }
84
+#endif
93
}
85
+}
94
86
+
95
static inline void
96
tb_jmp_cache_set(CPUJumpCache *jc, uint32_t hash,
97
TranslationBlock *tb, target_ulong pc)
98
{
99
-#if TARGET_TB_PCREL
100
- jc->array[hash].pc = pc;
101
- /* Use store_release on tb to ensure pc is written first. */
102
- qatomic_store_release(&jc->array[hash].tb, tb);
103
-#else
104
- /* Use the pc value already stored in tb->pc. */
105
- qatomic_set(&jc->array[hash].tb, tb);
106
-#endif
107
+ if (tb_cflags(tb) & CF_PCREL) {
108
+ jc->array[hash].pc = pc;
109
+ /* Use store_release on tb to ensure pc is written first. */
110
+ qatomic_store_release(&jc->array[hash].tb, tb);
111
+ } else{
112
+ /* Use the pc value already stored in tb->pc. */
113
+ qatomic_set(&jc->array[hash].tb, tb);
114
+ }
115
}
116
87
#endif /* ACCEL_TCG_TB_JMP_CACHE_H */
117
#endif /* ACCEL_TCG_TB_JMP_CACHE_H */
88
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
89
index XXXXXXX..XXXXXXX 100644
90
--- a/include/exec/cpu-defs.h
91
+++ b/include/exec/cpu-defs.h
92
@@ -XXX,XX +XXX,XX @@
93
# error TARGET_PAGE_BITS must be defined in cpu-param.h
94
# endif
95
#endif
96
+#ifndef TARGET_TB_PCREL
97
+# define TARGET_TB_PCREL 0
98
+#endif
99
100
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
101
102
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
103
index XXXXXXX..XXXXXXX 100644
104
--- a/include/exec/exec-all.h
105
+++ b/include/exec/exec-all.h
106
@@ -XXX,XX +XXX,XX @@ struct tb_tc {
107
};
108
109
struct TranslationBlock {
110
- target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */
111
- target_ulong cs_base; /* CS base for this block */
112
+#if !TARGET_TB_PCREL
113
+ /*
114
+ * Guest PC corresponding to this block. This must be the true
115
+ * virtual address. Therefore e.g. x86 stores EIP + CS_BASE, and
116
+ * targets like Arm, MIPS, HP-PA, which reuse low bits for ISA or
117
+ * privilege, must store those bits elsewhere.
118
+ *
119
+ * If TARGET_TB_PCREL, the opcodes for the TranslationBlock are
120
+ * written such that the TB is associated only with the physical
121
+ * page and may be run in any virtual address context. In this case,
122
+ * PC must always be taken from ENV in a target-specific manner.
123
+ * Unwind information is taken as offsets from the page, to be
124
+ * deposited into the "current" PC.
125
+ */
126
+ target_ulong pc;
127
+#endif
128
+
129
+ /*
130
+ * Target-specific data associated with the TranslationBlock, e.g.:
131
+ * x86: the original user, the Code Segment virtual base,
132
+ * arm: an extension of tb->flags,
133
+ * s390x: instruction data for EXECUTE,
134
+ * sparc: the next pc of the instruction queue (for delay slots).
135
+ */
136
+ target_ulong cs_base;
137
+
138
uint32_t flags; /* flags defining in which context the code was generated */
139
uint32_t cflags; /* compile flags */
140
141
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock {
142
/* Hide the read to avoid ifdefs for TARGET_TB_PCREL. */
143
static inline target_ulong tb_pc(const TranslationBlock *tb)
144
{
145
+#if TARGET_TB_PCREL
146
+ qemu_build_not_reached();
147
+#else
148
return tb->pc;
149
+#endif
150
}
151
152
/* Hide the qatomic_read to make code a little easier on the eyes */
153
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
118
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
154
index XXXXXXX..XXXXXXX 100644
119
index XXXXXXX..XXXXXXX 100644
155
--- a/accel/tcg/cpu-exec.c
120
--- a/accel/tcg/cpu-exec.c
156
+++ b/accel/tcg/cpu-exec.c
121
+++ b/accel/tcg/cpu-exec.c
157
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
122
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
158
const TranslationBlock *tb = p;
123
const TranslationBlock *tb = p;
159
const struct tb_desc *desc = d;
124
const struct tb_desc *desc = d;
160
125
161
- if (tb_pc(tb) == desc->pc &&
126
- if ((TARGET_TB_PCREL || tb_pc(tb) == desc->pc) &&
162
+ if ((TARGET_TB_PCREL || tb_pc(tb) == desc->pc) &&
127
+ if ((tb_cflags(tb) & CF_PCREL || tb_pc(tb) == desc->pc) &&
163
tb->page_addr[0] == desc->page_addr0 &&
128
tb_page_addr0(tb) == desc->page_addr0 &&
164
tb->cs_base == desc->cs_base &&
129
tb->cs_base == desc->cs_base &&
165
tb->flags == desc->flags &&
130
tb->flags == desc->flags &&
166
@@ -XXX,XX +XXX,XX @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
131
@@ -XXX,XX +XXX,XX @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
167
return NULL;
132
return NULL;
168
}
133
}
169
desc.page_addr0 = phys_pc;
134
desc.page_addr0 = phys_pc;
170
- h = tb_hash_func(phys_pc, pc, flags, cflags, *cpu->trace_dstate);
135
- h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : pc),
171
+ h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : pc),
136
+ h = tb_hash_func(phys_pc, (cflags & CF_PCREL ? 0 : pc),
172
+ flags, cflags, *cpu->trace_dstate);
137
flags, cflags, *cpu->trace_dstate);
173
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
138
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
174
}
139
}
175
176
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
140
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
177
uint32_t flags, uint32_t cflags)
178
{
179
TranslationBlock *tb;
180
+ CPUJumpCache *jc;
181
uint32_t hash;
182
183
/* we should never be trying to look up an INVALID tb */
184
tcg_debug_assert(!(cflags & CF_INVALID));
185
141
186
hash = tb_jmp_cache_hash_func(pc);
142
hash = tb_jmp_cache_hash_func(pc);
187
- tb = qatomic_rcu_read(&cpu->tb_jmp_cache->array[hash].tb);
143
jc = cpu->tb_jmp_cache;
188
+ jc = cpu->tb_jmp_cache;
144
- tb = tb_jmp_cache_get_tb(jc, hash);
189
+ tb = tb_jmp_cache_get_tb(jc, hash);
145
+ tb = tb_jmp_cache_get_tb(jc, cflags, hash);
190
146
191
if (likely(tb &&
147
if (likely(tb &&
192
- tb->pc == pc &&
148
tb_jmp_cache_get_pc(jc, hash, tb) == pc &&
193
+ tb_jmp_cache_get_pc(jc, hash, tb) == pc &&
194
tb->cs_base == cs_base &&
195
tb->flags == flags &&
196
tb->trace_vcpu_dstate == *cpu->trace_dstate &&
197
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
198
if (tb == NULL) {
199
return NULL;
200
}
201
- qatomic_set(&cpu->tb_jmp_cache->array[hash].tb, tb);
202
+ tb_jmp_cache_set(jc, hash, tb, pc);
203
return tb;
204
}
205
206
@@ -XXX,XX +XXX,XX @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
149
@@ -XXX,XX +XXX,XX @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
207
if (cc->tcg_ops->synchronize_from_tb) {
150
if (cc->tcg_ops->synchronize_from_tb) {
208
cc->tcg_ops->synchronize_from_tb(cpu, last_tb);
151
cc->tcg_ops->synchronize_from_tb(cpu, last_tb);
209
} else {
152
} else {
210
+ assert(!TARGET_TB_PCREL);
153
- assert(!TARGET_TB_PCREL);
154
+ tcg_debug_assert(!(tb_cflags(last_tb) & CF_PCREL));
211
assert(cc->set_pc);
155
assert(cc->set_pc);
212
cc->set_pc(cpu, tb_pc(last_tb));
156
cc->set_pc(cpu, tb_pc(last_tb));
213
}
157
}
214
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
158
diff --git a/accel/tcg/perf.c b/accel/tcg/perf.c
215
* for the fast lookup
159
index XXXXXXX..XXXXXXX 100644
216
*/
160
--- a/accel/tcg/perf.c
217
h = tb_jmp_cache_hash_func(pc);
161
+++ b/accel/tcg/perf.c
218
- qatomic_set(&cpu->tb_jmp_cache->array[h].tb, tb);
162
@@ -XXX,XX +XXX,XX @@ void perf_report_code(uint64_t guest_pc, TranslationBlock *tb,
219
+ tb_jmp_cache_set(cpu->tb_jmp_cache, h, tb, pc);
163
for (insn = 0; insn < tb->icount; insn++) {
220
}
164
/* FIXME: This replicates the restore_state_to_opc() logic. */
221
165
q[insn].address = tcg_ctx->gen_insn_data[insn][0];
222
#ifndef CONFIG_USER_ONLY
166
- if (TARGET_TB_PCREL) {
167
+ if (tb_cflags(tb) & CF_PCREL) {
168
q[insn].address |= (guest_pc & TARGET_PAGE_MASK);
169
} else {
170
#if defined(TARGET_I386)
171
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
172
index XXXXXXX..XXXXXXX 100644
173
--- a/accel/tcg/tb-maint.c
174
+++ b/accel/tcg/tb-maint.c
175
@@ -XXX,XX +XXX,XX @@ static bool tb_cmp(const void *ap, const void *bp)
176
const TranslationBlock *a = ap;
177
const TranslationBlock *b = bp;
178
179
- return ((TARGET_TB_PCREL || tb_pc(a) == tb_pc(b)) &&
180
+ return ((tb_cflags(a) & CF_PCREL || tb_pc(a) == tb_pc(b)) &&
181
a->cs_base == b->cs_base &&
182
a->flags == b->flags &&
183
(tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) &&
184
@@ -XXX,XX +XXX,XX @@ static void tb_jmp_cache_inval_tb(TranslationBlock *tb)
185
{
186
CPUState *cpu;
187
188
- if (TARGET_TB_PCREL) {
189
+ if (tb_cflags(tb) & CF_PCREL) {
190
/* A TB may be at any virtual address */
191
CPU_FOREACH(cpu) {
192
tcg_flush_jmp_cache(cpu);
193
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
194
195
/* remove the TB from the hash list */
196
phys_pc = tb_page_addr0(tb);
197
- h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)),
198
+ h = tb_hash_func(phys_pc, (orig_cflags & CF_PCREL ? 0 : tb_pc(tb)),
199
tb->flags, orig_cflags, tb->trace_vcpu_dstate);
200
if (!qht_remove(&tb_ctx.htable, tb, h)) {
201
return;
202
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
203
tb_record(tb, p, p2);
204
205
/* add in the hash table */
206
- h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)),
207
+ h = tb_hash_func(phys_pc, (tb->cflags & CF_PCREL ? 0 : tb_pc(tb)),
208
tb->flags, tb->cflags, tb->trace_vcpu_dstate);
209
qht_insert(&tb_ctx.htable, tb, h, &existing_tb);
210
223
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
211
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
224
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
225
--- a/accel/tcg/translate-all.c
213
--- a/accel/tcg/translate-all.c
226
+++ b/accel/tcg/translate-all.c
214
+++ b/accel/tcg/translate-all.c
227
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
215
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
228
216
229
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
217
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
230
if (i == 0) {
218
if (i == 0) {
231
- prev = (j == 0 ? tb_pc(tb) : 0);
219
- prev = (!TARGET_TB_PCREL && j == 0 ? tb_pc(tb) : 0);
232
+ prev = (!TARGET_TB_PCREL && j == 0 ? tb_pc(tb) : 0);
220
+ prev = (!(tb_cflags(tb) & CF_PCREL) && j == 0 ? tb_pc(tb) : 0);
233
} else {
221
} else {
234
prev = tcg_ctx->gen_insn_data[i - 1][j];
222
prev = tcg_ctx->gen_insn_data[i - 1][j];
235
}
223
}
236
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
224
@@ -XXX,XX +XXX,XX @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc,
237
static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
238
uintptr_t searched_pc, bool reset_icount)
239
{
240
- target_ulong data[TARGET_INSN_START_WORDS] = { tb_pc(tb) };
241
+ target_ulong data[TARGET_INSN_START_WORDS];
242
uintptr_t host_pc = (uintptr_t)tb->tc.ptr;
243
CPUArchState *env = cpu->env_ptr;
244
const uint8_t *p = tb->tc.ptr + tb->tc.size;
245
@@ -XXX,XX +XXX,XX @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
246
return -1;
247
}
225
}
248
226
249
+ memset(data, 0, sizeof(data));
227
memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS);
250
+ if (!TARGET_TB_PCREL) {
228
- if (!TARGET_TB_PCREL) {
251
+ data[0] = tb_pc(tb);
229
+ if (!(tb_cflags(tb) & CF_PCREL)) {
252
+ }
230
data[0] = tb_pc(tb);
253
+
254
/* Reconstruct the stored insn data while looking for the point at
255
which the end of the insn exceeds the searched_pc. */
256
for (i = 0; i < num_insns; ++i) {
257
@@ -XXX,XX +XXX,XX @@ static bool tb_cmp(const void *ap, const void *bp)
258
const TranslationBlock *a = ap;
259
const TranslationBlock *b = bp;
260
261
- return tb_pc(a) == tb_pc(b) &&
262
- a->cs_base == b->cs_base &&
263
- a->flags == b->flags &&
264
- (tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) &&
265
- a->trace_vcpu_dstate == b->trace_vcpu_dstate &&
266
- a->page_addr[0] == b->page_addr[0] &&
267
- a->page_addr[1] == b->page_addr[1];
268
+ return ((TARGET_TB_PCREL || tb_pc(a) == tb_pc(b)) &&
269
+ a->cs_base == b->cs_base &&
270
+ a->flags == b->flags &&
271
+ (tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) &&
272
+ a->trace_vcpu_dstate == b->trace_vcpu_dstate &&
273
+ a->page_addr[0] == b->page_addr[0] &&
274
+ a->page_addr[1] == b->page_addr[1]);
275
}
276
277
void tb_htable_init(void)
278
@@ -XXX,XX +XXX,XX @@ static inline void tb_jmp_unlink(TranslationBlock *dest)
279
qemu_spin_unlock(&dest->jmp_lock);
280
}
281
282
+static void tb_jmp_cache_inval_tb(TranslationBlock *tb)
283
+{
284
+ CPUState *cpu;
285
+
286
+ if (TARGET_TB_PCREL) {
287
+ /* A TB may be at any virtual address */
288
+ CPU_FOREACH(cpu) {
289
+ tcg_flush_jmp_cache(cpu);
290
+ }
291
+ } else {
292
+ uint32_t h = tb_jmp_cache_hash_func(tb_pc(tb));
293
+
294
+ CPU_FOREACH(cpu) {
295
+ CPUJumpCache *jc = cpu->tb_jmp_cache;
296
+
297
+ if (qatomic_read(&jc->array[h].tb) == tb) {
298
+ qatomic_set(&jc->array[h].tb, NULL);
299
+ }
300
+ }
301
+ }
302
+}
303
+
304
/*
305
* In user-mode, call with mmap_lock held.
306
* In !user-mode, if @rm_from_page_list is set, call with the TB's pages'
307
@@ -XXX,XX +XXX,XX @@ static inline void tb_jmp_unlink(TranslationBlock *dest)
308
*/
309
static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
310
{
311
- CPUState *cpu;
312
PageDesc *p;
313
uint32_t h;
314
tb_page_addr_t phys_pc;
315
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
316
317
/* remove the TB from the hash list */
318
phys_pc = tb->page_addr[0];
319
- h = tb_hash_func(phys_pc, tb_pc(tb), tb->flags, orig_cflags,
320
- tb->trace_vcpu_dstate);
321
+ h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)),
322
+ tb->flags, orig_cflags, tb->trace_vcpu_dstate);
323
if (!qht_remove(&tb_ctx.htable, tb, h)) {
324
return;
325
}
231
}
326
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
232
327
}
328
329
/* remove the TB from the hash list */
330
- h = tb_jmp_cache_hash_func(tb->pc);
331
- CPU_FOREACH(cpu) {
332
- CPUJumpCache *jc = cpu->tb_jmp_cache;
333
- if (qatomic_read(&jc->array[h].tb) == tb) {
334
- qatomic_set(&jc->array[h].tb, NULL);
335
- }
336
- }
337
+ tb_jmp_cache_inval_tb(tb);
338
339
/* suppress this TB from the two jump lists */
340
tb_remove_from_jmp_list(tb, 0);
341
@@ -XXX,XX +XXX,XX @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
342
}
343
344
/* add in the hash table */
345
- h = tb_hash_func(phys_pc, tb_pc(tb), tb->flags, tb->cflags,
346
- tb->trace_vcpu_dstate);
347
+ h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)),
348
+ tb->flags, tb->cflags, tb->trace_vcpu_dstate);
349
qht_insert(&tb_ctx.htable, tb, h, &existing_tb);
350
351
/* remove TB from the page(s) if we couldn't insert it */
352
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
233
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
353
234
354
gen_code_buf = tcg_ctx->code_gen_ptr;
235
gen_code_buf = tcg_ctx->code_gen_ptr;
355
tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf);
236
tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf);
356
+#if !TARGET_TB_PCREL
237
-#if !TARGET_TB_PCREL
357
tb->pc = pc;
238
- tb->pc = pc;
358
+#endif
239
-#endif
240
+ if (!(cflags & CF_PCREL)) {
241
+ tb->pc = pc;
242
+ }
359
tb->cs_base = cs_base;
243
tb->cs_base = cs_base;
360
tb->flags = flags;
244
tb->flags = flags;
361
tb->cflags = cflags;
245
tb->cflags = cflags;
246
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
247
tb->tc.size = gen_code_size;
248
249
/*
250
- * For TARGET_TB_PCREL, attribute all executions of the generated
251
- * code to its first mapping.
252
+ * For CF_PCREL, attribute all executions of the generated code
253
+ * to its first mapping.
254
*/
255
perf_report_code(pc, tb, tcg_splitwx_to_rx(gen_code_buf));
256
362
--
257
--
363
2.34.1
258
2.34.1
364
259
365
260
diff view generated by jsdifflib
1
Now that we have collected all of the page data into
1
From: Anton Johansson via <qemu-devel@nongnu.org>
2
CPUTLBEntryFull, provide an interface to record that
3
all in one go, instead of using 4 arguments. This interface
4
allows CPUTLBEntryFull to be extended without having to
5
change the number of arguments.
6
2
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-Id: <20230227135202.9710-6-anjo@rev.ng>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
7
---
12
include/exec/cpu-defs.h | 14 +++++++++++
8
include/exec/exec-all.h | 27 +++++++++++----------------
13
include/exec/exec-all.h | 22 ++++++++++++++++++
9
1 file changed, 11 insertions(+), 16 deletions(-)
14
accel/tcg/cputlb.c | 51 ++++++++++++++++++++++++++---------------
15
3 files changed, 69 insertions(+), 18 deletions(-)
16
10
17
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/cpu-defs.h
20
+++ b/include/exec/cpu-defs.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBEntryFull {
22
* + the offset within the target MemoryRegion (otherwise)
23
*/
24
hwaddr xlat_section;
25
+
26
+ /*
27
+ * @phys_addr contains the physical address in the address space
28
+ * given by cpu_asidx_from_attrs(cpu, @attrs).
29
+ */
30
+ hwaddr phys_addr;
31
+
32
+ /* @attrs contains the memory transaction attributes for the page. */
33
MemTxAttrs attrs;
34
+
35
+ /* @prot contains the complete protections for the page. */
36
+ uint8_t prot;
37
+
38
+ /* @lg_page_size contains the log2 of the page size. */
39
+ uint8_t lg_page_size;
40
} CPUTLBEntryFull;
41
42
/*
43
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
11
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
44
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
45
--- a/include/exec/exec-all.h
13
--- a/include/exec/exec-all.h
46
+++ b/include/exec/exec-all.h
14
+++ b/include/exec/exec-all.h
47
@@ -XXX,XX +XXX,XX @@ void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu,
15
@@ -XXX,XX +XXX,XX @@ struct tb_tc {
48
uint16_t idxmap,
16
};
49
unsigned bits);
17
50
18
struct TranslationBlock {
51
+/**
19
-#if !TARGET_TB_PCREL
52
+ * tlb_set_page_full:
20
/*
53
+ * @cpu: CPU context
21
* Guest PC corresponding to this block. This must be the true
54
+ * @mmu_idx: mmu index of the tlb to modify
22
* virtual address. Therefore e.g. x86 stores EIP + CS_BASE, and
55
+ * @vaddr: virtual address of the entry to add
23
* targets like Arm, MIPS, HP-PA, which reuse low bits for ISA or
56
+ * @full: the details of the tlb entry
24
* privilege, must store those bits elsewhere.
57
+ *
25
*
58
+ * Add an entry to @cpu tlb index @mmu_idx. All of the fields of
26
- * If TARGET_TB_PCREL, the opcodes for the TranslationBlock are
59
+ * @full must be filled, except for xlat_section, and constitute
27
- * written such that the TB is associated only with the physical
60
+ * the complete description of the translated page.
28
- * page and may be run in any virtual address context. In this case,
61
+ *
29
- * PC must always be taken from ENV in a target-specific manner.
62
+ * This is generally called by the target tlb_fill function after
30
+ * If CF_PCREL, the opcodes for the TranslationBlock are written
63
+ * having performed a successful page table walk to find the physical
31
+ * such that the TB is associated only with the physical page and
64
+ * address and attributes for the translation.
32
+ * may be run in any virtual address context. In this case, PC
65
+ *
33
+ * must always be taken from ENV in a target-specific manner.
66
+ * At most one entry for a given virtual address is permitted. Only a
34
* Unwind information is taken as offsets from the page, to be
67
+ * single TARGET_PAGE_SIZE region is mapped; @full->lg_page_size is only
35
* deposited into the "current" PC.
68
+ * used by tlb_flush_page.
36
*/
69
+ */
37
target_ulong pc;
70
+void tlb_set_page_full(CPUState *cpu, int mmu_idx, target_ulong vaddr,
38
-#endif
71
+ CPUTLBEntryFull *full);
39
72
+
40
/*
73
/**
41
* Target-specific data associated with the TranslationBlock, e.g.:
74
* tlb_set_page_with_attrs:
42
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock {
75
* @cpu: CPU to add this TLB entry for
43
uintptr_t jmp_dest[2];
76
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
44
};
77
index XXXXXXX..XXXXXXX 100644
45
78
--- a/accel/tcg/cputlb.c
46
-/* Hide the read to avoid ifdefs for TARGET_TB_PCREL. */
79
+++ b/accel/tcg/cputlb.c
47
-static inline target_ulong tb_pc(const TranslationBlock *tb)
80
@@ -XXX,XX +XXX,XX @@ static void tlb_add_large_page(CPUArchState *env, int mmu_idx,
48
-{
81
env_tlb(env)->d[mmu_idx].large_page_mask = lp_mask;
49
-#if TARGET_TB_PCREL
50
- qemu_build_not_reached();
51
-#else
52
- return tb->pc;
53
-#endif
54
-}
55
-
56
/* Hide the qatomic_read to make code a little easier on the eyes */
57
static inline uint32_t tb_cflags(const TranslationBlock *tb)
58
{
59
return qatomic_read(&tb->cflags);
82
}
60
}
83
61
84
-/* Add a new TLB entry. At most one entry for a given virtual address
62
+/* Hide the read to avoid ifdefs for CF_PCREL. */
85
+/*
63
+static inline target_ulong tb_pc(const TranslationBlock *tb)
86
+ * Add a new TLB entry. At most one entry for a given virtual address
87
* is permitted. Only a single TARGET_PAGE_SIZE region is mapped, the
88
* supplied size is only used by tlb_flush_page.
89
*
90
* Called from TCG-generated code, which is under an RCU read-side
91
* critical section.
92
*/
93
-void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
94
- hwaddr paddr, MemTxAttrs attrs, int prot,
95
- int mmu_idx, target_ulong size)
96
+void tlb_set_page_full(CPUState *cpu, int mmu_idx,
97
+ target_ulong vaddr, CPUTLBEntryFull *full)
98
{
99
CPUArchState *env = cpu->env_ptr;
100
CPUTLB *tlb = env_tlb(env);
101
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
102
CPUTLBEntry *te, tn;
103
hwaddr iotlb, xlat, sz, paddr_page;
104
target_ulong vaddr_page;
105
- int asidx = cpu_asidx_from_attrs(cpu, attrs);
106
- int wp_flags;
107
+ int asidx, wp_flags, prot;
108
bool is_ram, is_romd;
109
110
assert_cpu_is_self(cpu);
111
112
- if (size <= TARGET_PAGE_SIZE) {
113
+ if (full->lg_page_size <= TARGET_PAGE_BITS) {
114
sz = TARGET_PAGE_SIZE;
115
} else {
116
- tlb_add_large_page(env, mmu_idx, vaddr, size);
117
- sz = size;
118
+ sz = (hwaddr)1 << full->lg_page_size;
119
+ tlb_add_large_page(env, mmu_idx, vaddr, sz);
120
}
121
vaddr_page = vaddr & TARGET_PAGE_MASK;
122
- paddr_page = paddr & TARGET_PAGE_MASK;
123
+ paddr_page = full->phys_addr & TARGET_PAGE_MASK;
124
125
+ prot = full->prot;
126
+ asidx = cpu_asidx_from_attrs(cpu, full->attrs);
127
section = address_space_translate_for_iotlb(cpu, asidx, paddr_page,
128
- &xlat, &sz, attrs, &prot);
129
+ &xlat, &sz, full->attrs, &prot);
130
assert(sz >= TARGET_PAGE_SIZE);
131
132
tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
133
" prot=%x idx=%d\n",
134
- vaddr, paddr, prot, mmu_idx);
135
+ vaddr, full->phys_addr, prot, mmu_idx);
136
137
address = vaddr_page;
138
- if (size < TARGET_PAGE_SIZE) {
139
+ if (full->lg_page_size < TARGET_PAGE_BITS) {
140
/* Repeat the MMU check and TLB fill on every access. */
141
address |= TLB_INVALID_MASK;
142
}
143
- if (attrs.byte_swap) {
144
+ if (full->attrs.byte_swap) {
145
address |= TLB_BSWAP;
146
}
147
148
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
149
* subtract here is that of the page base, and not the same as the
150
* vaddr we add back in io_readx()/io_writex()/get_page_addr_code().
151
*/
152
+ desc->fulltlb[index] = *full;
153
desc->fulltlb[index].xlat_section = iotlb - vaddr_page;
154
- desc->fulltlb[index].attrs = attrs;
155
+ desc->fulltlb[index].phys_addr = paddr_page;
156
+ desc->fulltlb[index].prot = prot;
157
158
/* Now calculate the new entry */
159
tn.addend = addend - vaddr_page;
160
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
161
qemu_spin_unlock(&tlb->c.lock);
162
}
163
164
-/* Add a new TLB entry, but without specifying the memory
165
- * transaction attributes to be used.
166
- */
167
+void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
168
+ hwaddr paddr, MemTxAttrs attrs, int prot,
169
+ int mmu_idx, target_ulong size)
170
+{
64
+{
171
+ CPUTLBEntryFull full = {
65
+ assert(!(tb_cflags(tb) & CF_PCREL));
172
+ .phys_addr = paddr,
66
+ return tb->pc;
173
+ .attrs = attrs,
174
+ .prot = prot,
175
+ .lg_page_size = ctz64(size)
176
+ };
177
+
178
+ assert(is_power_of_2(size));
179
+ tlb_set_page_full(cpu, mmu_idx, vaddr, &full);
180
+}
67
+}
181
+
68
+
182
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
69
static inline tb_page_addr_t tb_page_addr0(const TranslationBlock *tb)
183
hwaddr paddr, int prot,
70
{
184
int mmu_idx, target_ulong size)
71
#ifdef CONFIG_USER_ONLY
185
--
72
--
186
2.34.1
73
2.34.1
187
74
188
75
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-7-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/arm/tcg/translate.h | 2 +-
9
target/arm/cpu.c | 8 ++++----
10
target/arm/tcg/translate-a64.c | 8 ++++----
11
target/arm/tcg/translate.c | 6 +++---
12
4 files changed, 12 insertions(+), 12 deletions(-)
13
14
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/tcg/translate.h
17
+++ b/target/arm/tcg/translate.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
19
/* The address of the current instruction being translated. */
20
target_ulong pc_curr;
21
/*
22
- * For TARGET_TB_PCREL, the full value of cpu_pc is not known
23
+ * For CF_PCREL, the full value of cpu_pc is not known
24
* (although the page offset is known). For convenience, the
25
* translation loop uses the full virtual address that triggered
26
* the translation, from base.pc_start through pc_curr.
27
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.c
30
+++ b/target/arm/cpu.c
31
@@ -XXX,XX +XXX,XX @@ static vaddr arm_cpu_get_pc(CPUState *cs)
32
void arm_cpu_synchronize_from_tb(CPUState *cs,
33
const TranslationBlock *tb)
34
{
35
- /* The program counter is always up to date with TARGET_TB_PCREL. */
36
- if (!TARGET_TB_PCREL) {
37
+ /* The program counter is always up to date with CF_PCREL. */
38
+ if (!(tb_cflags(tb) & CF_PCREL)) {
39
CPUARMState *env = cs->env_ptr;
40
/*
41
* It's OK to look at env for the current mode here, because it's
42
@@ -XXX,XX +XXX,XX @@ void arm_restore_state_to_opc(CPUState *cs,
43
CPUARMState *env = cs->env_ptr;
44
45
if (is_a64(env)) {
46
- if (TARGET_TB_PCREL) {
47
+ if (tb_cflags(tb) & CF_PCREL) {
48
env->pc = (env->pc & TARGET_PAGE_MASK) | data[0];
49
} else {
50
env->pc = data[0];
51
@@ -XXX,XX +XXX,XX @@ void arm_restore_state_to_opc(CPUState *cs,
52
env->condexec_bits = 0;
53
env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
54
} else {
55
- if (TARGET_TB_PCREL) {
56
+ if (tb_cflags(tb) & CF_PCREL) {
57
env->regs[15] = (env->regs[15] & TARGET_PAGE_MASK) | data[0];
58
} else {
59
env->regs[15] = data[0];
60
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/tcg/translate-a64.c
63
+++ b/target/arm/tcg/translate-a64.c
64
@@ -XXX,XX +XXX,XX @@ static void reset_btype(DisasContext *s)
65
static void gen_pc_plus_diff(DisasContext *s, TCGv_i64 dest, target_long diff)
66
{
67
assert(s->pc_save != -1);
68
- if (TARGET_TB_PCREL) {
69
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
70
tcg_gen_addi_i64(dest, cpu_pc, (s->pc_curr - s->pc_save) + diff);
71
} else {
72
tcg_gen_movi_i64(dest, s->pc_curr + diff);
73
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, int64_t diff)
74
* update to pc to the unlinked path. A long chain of links
75
* can thus avoid many updates to the PC.
76
*/
77
- if (TARGET_TB_PCREL) {
78
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
79
gen_a64_update_pc(s, diff);
80
tcg_gen_goto_tb(n);
81
} else {
82
@@ -XXX,XX +XXX,XX @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
83
if (page) {
84
/* ADRP (page based) */
85
offset <<= 12;
86
- /* The page offset is ok for TARGET_TB_PCREL. */
87
+ /* The page offset is ok for CF_PCREL. */
88
offset -= s->pc_curr & 0xfff;
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
92
DisasContext *dc = container_of(dcbase, DisasContext, base);
93
target_ulong pc_arg = dc->base.pc_next;
94
95
- if (TARGET_TB_PCREL) {
96
+ if (tb_cflags(dcbase->tb) & CF_PCREL) {
97
pc_arg &= ~TARGET_PAGE_MASK;
98
}
99
tcg_gen_insn_start(pc_arg, 0, 0);
100
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/tcg/translate.c
103
+++ b/target/arm/tcg/translate.c
104
@@ -XXX,XX +XXX,XX @@ static target_long jmp_diff(DisasContext *s, target_long diff)
105
static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, target_long diff)
106
{
107
assert(s->pc_save != -1);
108
- if (TARGET_TB_PCREL) {
109
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
110
tcg_gen_addi_i32(var, cpu_R[15], (s->pc_curr - s->pc_save) + diff);
111
} else {
112
tcg_gen_movi_i32(var, s->pc_curr + diff);
113
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, target_long diff)
114
* update to pc to the unlinked path. A long chain of links
115
* can thus avoid many updates to the PC.
116
*/
117
- if (TARGET_TB_PCREL) {
118
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
119
gen_update_pc(s, diff);
120
tcg_gen_goto_tb(n);
121
} else {
122
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
123
uint32_t condexec_bits;
124
target_ulong pc_arg = dc->base.pc_next;
125
126
- if (TARGET_TB_PCREL) {
127
+ if (tb_cflags(dcbase->tb) & CF_PCREL) {
128
pc_arg &= ~TARGET_PAGE_MASK;
129
}
130
if (dc->eci) {
131
--
132
2.34.1
133
134
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-8-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/i386/helper.c | 2 +-
9
target/i386/tcg/tcg-cpu.c | 6 +++---
10
target/i386/tcg/translate.c | 26 +++++++++++++-------------
11
3 files changed, 17 insertions(+), 17 deletions(-)
12
13
diff --git a/target/i386/helper.c b/target/i386/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/i386/helper.c
16
+++ b/target/i386/helper.c
17
@@ -XXX,XX +XXX,XX @@ static inline target_ulong get_memio_eip(CPUX86State *env)
18
}
19
20
/* Per x86_restore_state_to_opc. */
21
- if (TARGET_TB_PCREL) {
22
+ if (cs->tcg_cflags & CF_PCREL) {
23
return (env->eip & TARGET_PAGE_MASK) | data[0];
24
} else {
25
return data[0] - env->segs[R_CS].base;
26
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/i386/tcg/tcg-cpu.c
29
+++ b/target/i386/tcg/tcg-cpu.c
30
@@ -XXX,XX +XXX,XX @@ static void x86_cpu_exec_exit(CPUState *cs)
31
static void x86_cpu_synchronize_from_tb(CPUState *cs,
32
const TranslationBlock *tb)
33
{
34
- /* The instruction pointer is always up to date with TARGET_TB_PCREL. */
35
- if (!TARGET_TB_PCREL) {
36
+ /* The instruction pointer is always up to date with CF_PCREL. */
37
+ if (!(tb_cflags(tb) & CF_PCREL)) {
38
CPUX86State *env = cs->env_ptr;
39
env->eip = tb_pc(tb) - tb->cs_base;
40
}
41
@@ -XXX,XX +XXX,XX @@ static void x86_restore_state_to_opc(CPUState *cs,
42
CPUX86State *env = &cpu->env;
43
int cc_op = data[1];
44
45
- if (TARGET_TB_PCREL) {
46
+ if (tb_cflags(tb) & CF_PCREL) {
47
env->eip = (env->eip & TARGET_PAGE_MASK) | data[0];
48
} else {
49
env->eip = data[0] - tb->cs_base;
50
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/i386/tcg/translate.c
53
+++ b/target/i386/tcg/translate.c
54
@@ -XXX,XX +XXX,XX @@ static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
55
static void gen_update_eip_cur(DisasContext *s)
56
{
57
assert(s->pc_save != -1);
58
- if (TARGET_TB_PCREL) {
59
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
60
tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save);
61
} else {
62
tcg_gen_movi_tl(cpu_eip, s->base.pc_next - s->cs_base);
63
@@ -XXX,XX +XXX,XX @@ static void gen_update_eip_cur(DisasContext *s)
64
static void gen_update_eip_next(DisasContext *s)
65
{
66
assert(s->pc_save != -1);
67
- if (TARGET_TB_PCREL) {
68
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
69
tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save);
70
} else {
71
tcg_gen_movi_tl(cpu_eip, s->pc - s->cs_base);
72
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 eip_next_i32(DisasContext *s)
73
if (CODE64(s)) {
74
return tcg_constant_i32(-1);
75
}
76
- if (TARGET_TB_PCREL) {
77
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
78
TCGv_i32 ret = tcg_temp_new_i32();
79
tcg_gen_trunc_tl_i32(ret, cpu_eip);
80
tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save);
81
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 eip_next_i32(DisasContext *s)
82
static TCGv eip_next_tl(DisasContext *s)
83
{
84
assert(s->pc_save != -1);
85
- if (TARGET_TB_PCREL) {
86
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
87
TCGv ret = tcg_temp_new();
88
tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save);
89
return ret;
90
@@ -XXX,XX +XXX,XX @@ static TCGv eip_next_tl(DisasContext *s)
91
static TCGv eip_cur_tl(DisasContext *s)
92
{
93
assert(s->pc_save != -1);
94
- if (TARGET_TB_PCREL) {
95
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
96
TCGv ret = tcg_temp_new();
97
tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save);
98
return ret;
99
@@ -XXX,XX +XXX,XX @@ static void gen_rot_rm_T1(DisasContext *s, MemOp ot, int op1, int is_right)
100
tcg_temp_free_i32(t0);
101
tcg_temp_free_i32(t1);
102
103
- /* The CC_OP value is no longer predictable. */
104
+ /* The CC_OP value is no longer predictable. */
105
set_cc_op(s, CC_OP_DYNAMIC);
106
}
107
108
@@ -XXX,XX +XXX,XX @@ static void gen_rotc_rm_T1(DisasContext *s, MemOp ot, int op1,
109
gen_op_ld_v(s, ot, s->T0, s->A0);
110
else
111
gen_op_mov_v_reg(s, ot, s->T0, op1);
112
-
113
+
114
if (is_right) {
115
switch (ot) {
116
case MO_8:
117
@@ -XXX,XX +XXX,XX @@ static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib)
118
ea = cpu_regs[a.base];
119
}
120
if (!ea) {
121
- if (TARGET_TB_PCREL && a.base == -2) {
122
+ if (tb_cflags(s->base.tb) & CF_PCREL && a.base == -2) {
123
/* With cpu_eip ~= pc_save, the expression is pc-relative. */
124
tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save);
125
} else {
126
@@ -XXX,XX +XXX,XX @@ static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
127
if (!CODE64(s)) {
128
if (ot == MO_16) {
129
mask = 0xffff;
130
- if (TARGET_TB_PCREL && CODE32(s)) {
131
+ if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) {
132
use_goto_tb = false;
133
}
134
} else {
135
@@ -XXX,XX +XXX,XX @@ static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
136
gen_update_cc_op(s);
137
set_cc_op(s, CC_OP_DYNAMIC);
138
139
- if (TARGET_TB_PCREL) {
140
+ if (tb_cflags(s->base.tb) & CF_PCREL) {
141
tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save);
142
/*
143
* If we can prove the branch does not leave the page and we have
144
@@ -XXX,XX +XXX,XX @@ static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
145
translator_use_goto_tb(&s->base, new_eip + s->cs_base)) {
146
/* jump to same page: we can use a direct jump */
147
tcg_gen_goto_tb(tb_num);
148
- if (!TARGET_TB_PCREL) {
149
+ if (!(tb_cflags(s->base.tb) & CF_PCREL)) {
150
tcg_gen_movi_tl(cpu_eip, new_eip);
151
}
152
tcg_gen_exit_tb(s->base.tb, tb_num);
153
s->base.is_jmp = DISAS_NORETURN;
154
} else {
155
- if (!TARGET_TB_PCREL) {
156
+ if (!(tb_cflags(s->base.tb) & CF_PCREL)) {
157
tcg_gen_movi_tl(cpu_eip, new_eip);
158
}
159
if (s->jmp_opt) {
160
@@ -XXX,XX +XXX,XX @@ static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
161
target_ulong pc_arg = dc->base.pc_next;
162
163
dc->prev_insn_end = tcg_last_op();
164
- if (TARGET_TB_PCREL) {
165
+ if (tb_cflags(dcbase->tb) & CF_PCREL) {
166
pc_arg -= dc->cs_base;
167
pc_arg &= ~TARGET_PAGE_MASK;
168
}
169
--
170
2.34.1
171
172
diff view generated by jsdifflib
1
Allow the target to cache items from the guest page tables.
1
From: Anton Johansson via <qemu-devel@nongnu.org>
2
2
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-Id: <20230227135202.9710-9-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
7
---
8
include/exec/cpu-defs.h | 9 +++++++++
8
include/exec/cpu-defs.h | 3 ---
9
1 file changed, 9 insertions(+)
9
1 file changed, 3 deletions(-)
10
10
11
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
11
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/exec/cpu-defs.h
13
--- a/include/exec/cpu-defs.h
14
+++ b/include/exec/cpu-defs.h
14
+++ b/include/exec/cpu-defs.h
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBEntryFull {
15
@@ -XXX,XX +XXX,XX @@
16
16
# error TARGET_PAGE_BITS must be defined in cpu-param.h
17
/* @lg_page_size contains the log2 of the page size. */
17
# endif
18
uint8_t lg_page_size;
18
#endif
19
+
19
-#ifndef TARGET_TB_PCREL
20
+ /*
20
-# define TARGET_TB_PCREL 0
21
+ * Allow target-specific additions to this structure.
21
-#endif
22
+ * This may be used to cache items from the guest cpu
22
23
+ * page tables for later use by the implementation.
23
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
24
+ */
24
25
+#ifdef TARGET_PAGE_ENTRY_EXTRA
26
+ TARGET_PAGE_ENTRY_EXTRA
27
+#endif
28
} CPUTLBEntryFull;
29
30
/*
31
--
25
--
32
2.34.1
26
2.34.1
33
27
34
28
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-10-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/arm/cpu-param.h | 2 --
9
1 file changed, 2 deletions(-)
10
11
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu-param.h
14
+++ b/target/arm/cpu-param.h
15
@@ -XXX,XX +XXX,XX @@
16
# define TARGET_PAGE_BITS_VARY
17
# define TARGET_PAGE_BITS_MIN 10
18
19
-# define TARGET_TB_PCREL 1
20
-
21
/*
22
* Cache the attrs and shareability fields from the page table entry.
23
*
24
--
25
2.34.1
26
27
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-11-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/i386/cpu-param.h | 4 ----
9
1 file changed, 4 deletions(-)
10
11
diff --git a/target/i386/cpu-param.h b/target/i386/cpu-param.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/i386/cpu-param.h
14
+++ b/target/i386/cpu-param.h
15
@@ -XXX,XX +XXX,XX @@
16
#define TARGET_PAGE_BITS 12
17
#define NB_MMU_MODES 5
18
19
-#ifndef CONFIG_USER_ONLY
20
-# define TARGET_TB_PCREL 1
21
-#endif
22
-
23
#endif
24
--
25
2.34.1
26
27
diff view generated by jsdifflib
1
Wrap the bare TranslationBlock pointer into a structure.
1
From: Anton Johansson via <qemu-devel@nongnu.org>
2
2
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
tb-jmp-cache.h contains a few small functions that only exist to hide a
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
CF_PCREL check, however the caller often already performs such a check.
5
6
This patch moves CF_PCREL checks from the callee to the caller, and also
7
removes these functions which now only hide an access of the jmp-cache.
8
9
Signed-off-by: Anton Johansson <anjo@rev.ng>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-Id: <20230227135202.9710-12-anjo@rev.ng>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
13
---
7
accel/tcg/tb-hash.h | 1 +
14
accel/tcg/tb-jmp-cache.h | 36 ---------------------------
8
accel/tcg/tb-jmp-cache.h | 24 ++++++++++++++++++++++++
15
accel/tcg/cpu-exec.c | 54 +++++++++++++++++++++++++++++-----------
9
include/exec/cpu-common.h | 1 +
16
2 files changed, 40 insertions(+), 50 deletions(-)
10
include/hw/core/cpu.h | 15 +--------------
11
include/qemu/typedefs.h | 1 +
12
accel/stubs/tcg-stub.c | 4 ++++
13
accel/tcg/cpu-exec.c | 10 +++++++---
14
accel/tcg/cputlb.c | 9 +++++----
15
accel/tcg/translate-all.c | 28 +++++++++++++++++++++++++---
16
hw/core/cpu-common.c | 3 +--
17
plugins/core.c | 2 +-
18
trace/control-target.c | 2 +-
19
12 files changed, 72 insertions(+), 28 deletions(-)
20
create mode 100644 accel/tcg/tb-jmp-cache.h
21
17
22
diff --git a/accel/tcg/tb-hash.h b/accel/tcg/tb-hash.h
18
diff --git a/accel/tcg/tb-jmp-cache.h b/accel/tcg/tb-jmp-cache.h
23
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
24
--- a/accel/tcg/tb-hash.h
20
--- a/accel/tcg/tb-jmp-cache.h
25
+++ b/accel/tcg/tb-hash.h
26
@@ -XXX,XX +XXX,XX @@
27
#include "exec/cpu-defs.h"
28
#include "exec/exec-all.h"
29
#include "qemu/xxhash.h"
30
+#include "tb-jmp-cache.h"
31
32
#ifdef CONFIG_SOFTMMU
33
34
diff --git a/accel/tcg/tb-jmp-cache.h b/accel/tcg/tb-jmp-cache.h
35
new file mode 100644
36
index XXXXXXX..XXXXXXX
37
--- /dev/null
38
+++ b/accel/tcg/tb-jmp-cache.h
21
+++ b/accel/tcg/tb-jmp-cache.h
39
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ struct CPUJumpCache {
40
+/*
23
} array[TB_JMP_CACHE_SIZE];
41
+ * The per-CPU TranslationBlock jump cache.
24
};
42
+ *
25
43
+ * Copyright (c) 2003 Fabrice Bellard
26
-static inline TranslationBlock *
44
+ *
27
-tb_jmp_cache_get_tb(CPUJumpCache *jc, uint32_t cflags, uint32_t hash)
45
+ * SPDX-License-Identifier: GPL-2.0-or-later
46
+ */
47
+
48
+#ifndef ACCEL_TCG_TB_JMP_CACHE_H
49
+#define ACCEL_TCG_TB_JMP_CACHE_H
50
+
51
+#define TB_JMP_CACHE_BITS 12
52
+#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
53
+
54
+/*
55
+ * Accessed in parallel; all accesses to 'tb' must be atomic.
56
+ */
57
+struct CPUJumpCache {
58
+ struct {
59
+ TranslationBlock *tb;
60
+ } array[TB_JMP_CACHE_SIZE];
61
+};
62
+
63
+#endif /* ACCEL_TCG_TB_JMP_CACHE_H */
64
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
65
index XXXXXXX..XXXXXXX 100644
66
--- a/include/exec/cpu-common.h
67
+++ b/include/exec/cpu-common.h
68
@@ -XXX,XX +XXX,XX @@ void cpu_list_unlock(void);
69
unsigned int cpu_list_generation_id_get(void);
70
71
void tcg_flush_softmmu_tlb(CPUState *cs);
72
+void tcg_flush_jmp_cache(CPUState *cs);
73
74
void tcg_iommu_init_notifier_list(CPUState *cpu);
75
void tcg_iommu_free_notifier_list(CPUState *cpu);
76
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
77
index XXXXXXX..XXXXXXX 100644
78
--- a/include/hw/core/cpu.h
79
+++ b/include/hw/core/cpu.h
80
@@ -XXX,XX +XXX,XX @@ struct kvm_run;
81
struct hax_vcpu_state;
82
struct hvf_vcpu_state;
83
84
-#define TB_JMP_CACHE_BITS 12
85
-#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
86
-
87
/* work queue */
88
89
/* The union type allows passing of 64 bit target pointers on 32 bit
90
@@ -XXX,XX +XXX,XX @@ struct CPUState {
91
CPUArchState *env_ptr;
92
IcountDecr *icount_decr_ptr;
93
94
- /* Accessed in parallel; all accesses must be atomic */
95
- TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];
96
+ CPUJumpCache *tb_jmp_cache;
97
98
struct GDBRegisterState *gdb_regs;
99
int gdb_num_regs;
100
@@ -XXX,XX +XXX,XX @@ extern CPUTailQ cpus;
101
102
extern __thread CPUState *current_cpu;
103
104
-static inline void cpu_tb_jmp_cache_clear(CPUState *cpu)
105
-{
28
-{
106
- unsigned int i;
29
- if (cflags & CF_PCREL) {
107
-
30
- /* Use acquire to ensure current load of pc from jc. */
108
- for (i = 0; i < TB_JMP_CACHE_SIZE; i++) {
31
- return qatomic_load_acquire(&jc->array[hash].tb);
109
- qatomic_set(&cpu->tb_jmp_cache[i], NULL);
32
- } else {
33
- /* Use rcu_read to ensure current load of pc from *tb. */
34
- return qatomic_rcu_read(&jc->array[hash].tb);
110
- }
35
- }
111
-}
36
-}
112
-
37
-
113
/**
38
-static inline target_ulong
114
* qemu_tcg_mttcg_enabled:
39
-tb_jmp_cache_get_pc(CPUJumpCache *jc, uint32_t hash, TranslationBlock *tb)
115
* Check whether we are running MultiThread TCG or not.
40
-{
116
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
41
- if (tb_cflags(tb) & CF_PCREL) {
117
index XXXXXXX..XXXXXXX 100644
42
- return jc->array[hash].pc;
118
--- a/include/qemu/typedefs.h
43
- } else {
119
+++ b/include/qemu/typedefs.h
44
- return tb_pc(tb);
120
@@ -XXX,XX +XXX,XX @@ typedef struct CoMutex CoMutex;
45
- }
121
typedef struct ConfidentialGuestSupport ConfidentialGuestSupport;
46
-}
122
typedef struct CPUAddressSpace CPUAddressSpace;
47
-
123
typedef struct CPUArchState CPUArchState;
48
-static inline void
124
+typedef struct CPUJumpCache CPUJumpCache;
49
-tb_jmp_cache_set(CPUJumpCache *jc, uint32_t hash,
125
typedef struct CPUState CPUState;
50
- TranslationBlock *tb, target_ulong pc)
126
typedef struct CPUTLBEntryFull CPUTLBEntryFull;
51
-{
127
typedef struct DeviceListener DeviceListener;
52
- if (tb_cflags(tb) & CF_PCREL) {
128
diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c
53
- jc->array[hash].pc = pc;
129
index XXXXXXX..XXXXXXX 100644
54
- /* Use store_release on tb to ensure pc is written first. */
130
--- a/accel/stubs/tcg-stub.c
55
- qatomic_store_release(&jc->array[hash].tb, tb);
131
+++ b/accel/stubs/tcg-stub.c
56
- } else{
132
@@ -XXX,XX +XXX,XX @@ void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
57
- /* Use the pc value already stored in tb->pc. */
133
{
58
- qatomic_set(&jc->array[hash].tb, tb);
134
}
59
- }
135
60
-}
136
+void tcg_flush_jmp_cache(CPUState *cpu)
61
-
137
+{
62
#endif /* ACCEL_TCG_TB_JMP_CACHE_H */
138
+}
139
+
140
int probe_access_flags(CPUArchState *env, target_ulong addr,
141
MMUAccessType access_type, int mmu_idx,
142
bool nonfault, void **phost, uintptr_t retaddr)
143
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
63
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
144
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
145
--- a/accel/tcg/cpu-exec.c
65
--- a/accel/tcg/cpu-exec.c
146
+++ b/accel/tcg/cpu-exec.c
66
+++ b/accel/tcg/cpu-exec.c
147
@@ -XXX,XX +XXX,XX @@
148
#include "sysemu/replay.h"
149
#include "sysemu/tcg.h"
150
#include "exec/helper-proto.h"
151
+#include "tb-jmp-cache.h"
152
#include "tb-hash.h"
153
#include "tb-context.h"
154
#include "internal.h"
155
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
67
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
156
tcg_debug_assert(!(cflags & CF_INVALID));
157
68
158
hash = tb_jmp_cache_hash_func(pc);
69
hash = tb_jmp_cache_hash_func(pc);
159
- tb = qatomic_rcu_read(&cpu->tb_jmp_cache[hash]);
70
jc = cpu->tb_jmp_cache;
160
+ tb = qatomic_rcu_read(&cpu->tb_jmp_cache->array[hash].tb);
71
- tb = tb_jmp_cache_get_tb(jc, cflags, hash);
161
72
162
if (likely(tb &&
73
- if (likely(tb &&
163
tb->pc == pc &&
74
- tb_jmp_cache_get_pc(jc, hash, tb) == pc &&
164
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
75
- tb->cs_base == cs_base &&
165
if (tb == NULL) {
76
- tb->flags == flags &&
166
return NULL;
77
- tb->trace_vcpu_dstate == *cpu->trace_dstate &&
78
- tb_cflags(tb) == cflags)) {
79
- return tb;
80
+ if (cflags & CF_PCREL) {
81
+ /* Use acquire to ensure current load of pc from jc. */
82
+ tb = qatomic_load_acquire(&jc->array[hash].tb);
83
+
84
+ if (likely(tb &&
85
+ jc->array[hash].pc == pc &&
86
+ tb->cs_base == cs_base &&
87
+ tb->flags == flags &&
88
+ tb->trace_vcpu_dstate == *cpu->trace_dstate &&
89
+ tb_cflags(tb) == cflags)) {
90
+ return tb;
91
+ }
92
+ tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags);
93
+ if (tb == NULL) {
94
+ return NULL;
95
+ }
96
+ jc->array[hash].pc = pc;
97
+ /* Use store_release on tb to ensure pc is written first. */
98
+ qatomic_store_release(&jc->array[hash].tb, tb);
99
+ } else {
100
+ /* Use rcu_read to ensure current load of pc from *tb. */
101
+ tb = qatomic_rcu_read(&jc->array[hash].tb);
102
+
103
+ if (likely(tb &&
104
+ tb_pc(tb) == pc &&
105
+ tb->cs_base == cs_base &&
106
+ tb->flags == flags &&
107
+ tb->trace_vcpu_dstate == *cpu->trace_dstate &&
108
+ tb_cflags(tb) == cflags)) {
109
+ return tb;
110
+ }
111
+ tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags);
112
+ if (tb == NULL) {
113
+ return NULL;
114
+ }
115
+ /* Use the pc value already stored in tb->pc. */
116
+ qatomic_set(&jc->array[hash].tb, tb);
167
}
117
}
168
- qatomic_set(&cpu->tb_jmp_cache[hash], tb);
118
- tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags);
169
+ qatomic_set(&cpu->tb_jmp_cache->array[hash].tb, tb);
119
- if (tb == NULL) {
120
- return NULL;
121
- }
122
- tb_jmp_cache_set(jc, hash, tb, pc);
123
+
170
return tb;
124
return tb;
171
}
125
}
172
126
173
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
127
@@ -XXX,XX +XXX,XX @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
174
175
tb = tb_lookup(cpu, pc, cs_base, flags, cflags);
176
if (tb == NULL) {
177
+ uint32_t h;
178
+
179
mmap_lock();
180
tb = tb_gen_code(cpu, pc, cs_base, flags, cflags);
181
mmap_unlock();
182
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
183
* We add the TB in the virtual pc hash table
184
* for the fast lookup
128
* for the fast lookup
185
*/
129
*/
186
- qatomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb);
130
h = tb_jmp_cache_hash_func(pc);
187
+ h = tb_jmp_cache_hash_func(pc);
131
- tb_jmp_cache_set(cpu->tb_jmp_cache, h, tb, pc);
132
+ /* Use the pc value already stored in tb->pc. */
188
+ qatomic_set(&cpu->tb_jmp_cache->array[h].tb, tb);
133
+ qatomic_set(&cpu->tb_jmp_cache->array[h].tb, tb);
189
}
134
}
190
135
191
#ifndef CONFIG_USER_ONLY
136
#ifndef CONFIG_USER_ONLY
192
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/accel/tcg/cputlb.c
195
+++ b/accel/tcg/cputlb.c
196
@@ -XXX,XX +XXX,XX @@ static void tlb_window_reset(CPUTLBDesc *desc, int64_t ns,
197
198
static void tb_jmp_cache_clear_page(CPUState *cpu, target_ulong page_addr)
199
{
200
- unsigned int i, i0 = tb_jmp_cache_hash_page(page_addr);
201
+ int i, i0 = tb_jmp_cache_hash_page(page_addr);
202
+ CPUJumpCache *jc = cpu->tb_jmp_cache;
203
204
for (i = 0; i < TB_JMP_PAGE_SIZE; i++) {
205
- qatomic_set(&cpu->tb_jmp_cache[i0 + i], NULL);
206
+ qatomic_set(&jc->array[i0 + i].tb, NULL);
207
}
208
}
209
210
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data)
211
212
qemu_spin_unlock(&env_tlb(env)->c.lock);
213
214
- cpu_tb_jmp_cache_clear(cpu);
215
+ tcg_flush_jmp_cache(cpu);
216
217
if (to_clean == ALL_MMUIDX_BITS) {
218
qatomic_set(&env_tlb(env)->c.full_flush_count,
219
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_range_by_mmuidx_async_0(CPUState *cpu,
220
* longer to clear each entry individually than it will to clear it all.
221
*/
222
if (d.len >= (TARGET_PAGE_SIZE * TB_JMP_CACHE_SIZE)) {
223
- cpu_tb_jmp_cache_clear(cpu);
224
+ tcg_flush_jmp_cache(cpu);
225
return;
226
}
227
228
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
229
index XXXXXXX..XXXXXXX 100644
230
--- a/accel/tcg/translate-all.c
231
+++ b/accel/tcg/translate-all.c
232
@@ -XXX,XX +XXX,XX @@
233
#include "sysemu/tcg.h"
234
#include "qapi/error.h"
235
#include "hw/core/tcg-cpu-ops.h"
236
+#include "tb-jmp-cache.h"
237
#include "tb-hash.h"
238
#include "tb-context.h"
239
#include "internal.h"
240
@@ -XXX,XX +XXX,XX @@ static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count)
241
}
242
243
CPU_FOREACH(cpu) {
244
- cpu_tb_jmp_cache_clear(cpu);
245
+ tcg_flush_jmp_cache(cpu);
246
}
247
248
qht_reset_size(&tb_ctx.htable, CODE_GEN_HTABLE_SIZE);
249
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
250
/* remove the TB from the hash list */
251
h = tb_jmp_cache_hash_func(tb->pc);
252
CPU_FOREACH(cpu) {
253
- if (qatomic_read(&cpu->tb_jmp_cache[h]) == tb) {
254
- qatomic_set(&cpu->tb_jmp_cache[h], NULL);
255
+ CPUJumpCache *jc = cpu->tb_jmp_cache;
256
+ if (qatomic_read(&jc->array[h].tb) == tb) {
257
+ qatomic_set(&jc->array[h].tb, NULL);
258
}
259
}
260
261
@@ -XXX,XX +XXX,XX @@ int page_unprotect(target_ulong address, uintptr_t pc)
262
}
263
#endif /* CONFIG_USER_ONLY */
264
265
+/*
266
+ * Called by generic code at e.g. cpu reset after cpu creation,
267
+ * therefore we must be prepared to allocate the jump cache.
268
+ */
269
+void tcg_flush_jmp_cache(CPUState *cpu)
270
+{
271
+ CPUJumpCache *jc = cpu->tb_jmp_cache;
272
+
273
+ if (likely(jc)) {
274
+ for (int i = 0; i < TB_JMP_CACHE_SIZE; i++) {
275
+ qatomic_set(&jc->array[i].tb, NULL);
276
+ }
277
+ } else {
278
+ /* This should happen once during realize, and thus never race. */
279
+ jc = g_new0(CPUJumpCache, 1);
280
+ jc = qatomic_xchg(&cpu->tb_jmp_cache, jc);
281
+ assert(jc == NULL);
282
+ }
283
+}
284
+
285
/* This is a wrapper for common code that can not use CONFIG_SOFTMMU */
286
void tcg_flush_softmmu_tlb(CPUState *cs)
287
{
288
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
289
index XXXXXXX..XXXXXXX 100644
290
--- a/hw/core/cpu-common.c
291
+++ b/hw/core/cpu-common.c
292
@@ -XXX,XX +XXX,XX @@ static void cpu_common_reset(DeviceState *dev)
293
cpu->cflags_next_tb = -1;
294
295
if (tcg_enabled()) {
296
- cpu_tb_jmp_cache_clear(cpu);
297
-
298
+ tcg_flush_jmp_cache(cpu);
299
tcg_flush_softmmu_tlb(cpu);
300
}
301
}
302
diff --git a/plugins/core.c b/plugins/core.c
303
index XXXXXXX..XXXXXXX 100644
304
--- a/plugins/core.c
305
+++ b/plugins/core.c
306
@@ -XXX,XX +XXX,XX @@ struct qemu_plugin_ctx *plugin_id_to_ctx_locked(qemu_plugin_id_t id)
307
static void plugin_cpu_update__async(CPUState *cpu, run_on_cpu_data data)
308
{
309
bitmap_copy(cpu->plugin_mask, &data.host_ulong, QEMU_PLUGIN_EV_MAX);
310
- cpu_tb_jmp_cache_clear(cpu);
311
+ tcg_flush_jmp_cache(cpu);
312
}
313
314
static void plugin_cpu_update__locked(gpointer k, gpointer v, gpointer udata)
315
diff --git a/trace/control-target.c b/trace/control-target.c
316
index XXXXXXX..XXXXXXX 100644
317
--- a/trace/control-target.c
318
+++ b/trace/control-target.c
319
@@ -XXX,XX +XXX,XX @@ static void trace_event_synchronize_vcpu_state_dynamic(
320
{
321
bitmap_copy(vcpu->trace_dstate, vcpu->trace_dstate_delayed,
322
CPU_TRACE_DSTATE_MAX_EVENTS);
323
- cpu_tb_jmp_cache_clear(vcpu);
324
+ tcg_flush_jmp_cache(vcpu);
325
}
326
327
void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
328
--
137
--
329
2.34.1
138
2.34.1
330
139
331
140
diff view generated by jsdifflib
1
Let tb->page_addr[0] contain the address of the first byte of the
1
From: Anton Johansson via <qemu-devel@nongnu.org>
2
translated block, rather than the address of the page containing the
3
start of the translated block. We need to recover this value anyway
4
at various points, and it is easier to discard a page offset when it
5
is not needed, which happens naturally via the existing find_page shift.
6
2
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-13-anjo@rev.ng>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
7
---
10
accel/tcg/cpu-exec.c | 16 ++++++++--------
8
accel/tcg/internal.h | 2 +-
11
accel/tcg/cputlb.c | 3 ++-
9
accel/tcg/cpu-exec.c | 6 +++---
12
accel/tcg/translate-all.c | 9 +++++----
10
accel/tcg/tb-maint.c | 8 ++++----
13
3 files changed, 15 insertions(+), 13 deletions(-)
11
accel/tcg/translate-all.c | 4 ++--
12
4 files changed, 10 insertions(+), 10 deletions(-)
14
13
14
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/accel/tcg/internal.h
17
+++ b/accel/tcg/internal.h
18
@@ -XXX,XX +XXX,XX @@ static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
19
if (tb_cflags(tb) & CF_PCREL) {
20
return cpu->cc->get_pc(cpu);
21
} else {
22
- return tb_pc(tb);
23
+ return tb->pc;
24
}
25
}
26
15
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
27
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
16
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/tcg/cpu-exec.c
29
--- a/accel/tcg/cpu-exec.c
18
+++ b/accel/tcg/cpu-exec.c
30
+++ b/accel/tcg/cpu-exec.c
19
@@ -XXX,XX +XXX,XX @@ struct tb_desc {
20
target_ulong pc;
21
target_ulong cs_base;
22
CPUArchState *env;
23
- tb_page_addr_t phys_page1;
24
+ tb_page_addr_t page_addr0;
25
uint32_t flags;
26
uint32_t cflags;
27
uint32_t trace_vcpu_dstate;
28
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
31
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
32
const TranslationBlock *tb = p;
29
const struct tb_desc *desc = d;
33
const struct tb_desc *desc = d;
30
34
31
if (tb->pc == desc->pc &&
35
- if ((tb_cflags(tb) & CF_PCREL || tb_pc(tb) == desc->pc) &&
32
- tb->page_addr[0] == desc->phys_page1 &&
36
+ if ((tb_cflags(tb) & CF_PCREL || tb->pc == desc->pc) &&
33
+ tb->page_addr[0] == desc->page_addr0 &&
37
tb_page_addr0(tb) == desc->page_addr0 &&
34
tb->cs_base == desc->cs_base &&
38
tb->cs_base == desc->cs_base &&
35
tb->flags == desc->flags &&
39
tb->flags == desc->flags &&
36
tb->trace_vcpu_dstate == desc->trace_vcpu_dstate &&
40
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
37
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
41
tb = qatomic_rcu_read(&jc->array[hash].tb);
38
if (tb->page_addr[1] == -1) {
42
39
return true;
43
if (likely(tb &&
44
- tb_pc(tb) == pc &&
45
+ tb->pc == pc &&
46
tb->cs_base == cs_base &&
47
tb->flags == flags &&
48
tb->trace_vcpu_dstate == *cpu->trace_dstate &&
49
@@ -XXX,XX +XXX,XX @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
40
} else {
50
} else {
41
- tb_page_addr_t phys_page2;
51
tcg_debug_assert(!(tb_cflags(last_tb) & CF_PCREL));
42
- target_ulong virt_page2;
52
assert(cc->set_pc);
43
+ tb_page_addr_t phys_page1;
53
- cc->set_pc(cpu, tb_pc(last_tb));
44
+ target_ulong virt_page1;
54
+ cc->set_pc(cpu, last_tb->pc);
45
46
/*
47
* We know that the first page matched, and an otherwise valid TB
48
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
49
* is different for the new TB. Therefore any exception raised
50
* here by the faulting lookup is not premature.
51
*/
52
- virt_page2 = TARGET_PAGE_ALIGN(desc->pc);
53
- phys_page2 = get_page_addr_code(desc->env, virt_page2);
54
- if (tb->page_addr[1] == phys_page2) {
55
+ virt_page1 = TARGET_PAGE_ALIGN(desc->pc);
56
+ phys_page1 = get_page_addr_code(desc->env, virt_page1);
57
+ if (tb->page_addr[1] == phys_page1) {
58
return true;
59
}
60
}
55
}
61
@@ -XXX,XX +XXX,XX @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
56
if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
62
if (phys_pc == -1) {
57
target_ulong pc = log_pc(cpu, last_tb);
63
return NULL;
58
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
64
}
65
- desc.phys_page1 = phys_pc & TARGET_PAGE_MASK;
66
+ desc.page_addr0 = phys_pc;
67
h = tb_hash_func(phys_pc, pc, flags, cflags, *cpu->trace_dstate);
68
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
69
}
70
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
71
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
72
--- a/accel/tcg/cputlb.c
60
--- a/accel/tcg/tb-maint.c
73
+++ b/accel/tcg/cputlb.c
61
+++ b/accel/tcg/tb-maint.c
74
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
62
@@ -XXX,XX +XXX,XX @@ static bool tb_cmp(const void *ap, const void *bp)
75
can be detected */
63
const TranslationBlock *a = ap;
76
void tlb_protect_code(ram_addr_t ram_addr)
64
const TranslationBlock *b = bp;
77
{
65
78
- cpu_physical_memory_test_and_clear_dirty(ram_addr, TARGET_PAGE_SIZE,
66
- return ((tb_cflags(a) & CF_PCREL || tb_pc(a) == tb_pc(b)) &&
79
+ cpu_physical_memory_test_and_clear_dirty(ram_addr & TARGET_PAGE_MASK,
67
+ return ((tb_cflags(a) & CF_PCREL || a->pc == b->pc) &&
80
+ TARGET_PAGE_SIZE,
68
a->cs_base == b->cs_base &&
81
DIRTY_MEMORY_CODE);
69
a->flags == b->flags &&
82
}
70
(tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) &&
71
@@ -XXX,XX +XXX,XX @@ static void tb_jmp_cache_inval_tb(TranslationBlock *tb)
72
tcg_flush_jmp_cache(cpu);
73
}
74
} else {
75
- uint32_t h = tb_jmp_cache_hash_func(tb_pc(tb));
76
+ uint32_t h = tb_jmp_cache_hash_func(tb->pc);
77
78
CPU_FOREACH(cpu) {
79
CPUJumpCache *jc = cpu->tb_jmp_cache;
80
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
81
82
/* remove the TB from the hash list */
83
phys_pc = tb_page_addr0(tb);
84
- h = tb_hash_func(phys_pc, (orig_cflags & CF_PCREL ? 0 : tb_pc(tb)),
85
+ h = tb_hash_func(phys_pc, (orig_cflags & CF_PCREL ? 0 : tb->pc),
86
tb->flags, orig_cflags, tb->trace_vcpu_dstate);
87
if (!qht_remove(&tb_ctx.htable, tb, h)) {
88
return;
89
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
90
tb_record(tb, p, p2);
91
92
/* add in the hash table */
93
- h = tb_hash_func(phys_pc, (tb->cflags & CF_PCREL ? 0 : tb_pc(tb)),
94
+ h = tb_hash_func(phys_pc, (tb->cflags & CF_PCREL ? 0 : tb->pc),
95
tb->flags, tb->cflags, tb->trace_vcpu_dstate);
96
qht_insert(&tb_ctx.htable, tb, h, &existing_tb);
83
97
84
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
98
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
85
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
86
--- a/accel/tcg/translate-all.c
100
--- a/accel/tcg/translate-all.c
87
+++ b/accel/tcg/translate-all.c
101
+++ b/accel/tcg/translate-all.c
88
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
102
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
89
qemu_spin_unlock(&tb->jmp_lock);
103
90
104
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
91
/* remove the TB from the hash list */
105
if (i == 0) {
92
- phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
106
- prev = (!(tb_cflags(tb) & CF_PCREL) && j == 0 ? tb_pc(tb) : 0);
93
+ phys_pc = tb->page_addr[0];
107
+ prev = (!(tb_cflags(tb) & CF_PCREL) && j == 0 ? tb->pc : 0);
94
h = tb_hash_func(phys_pc, tb->pc, tb->flags, orig_cflags,
108
} else {
95
tb->trace_vcpu_dstate);
109
prev = tcg_ctx->gen_insn_data[i - 1][j];
96
if (!qht_remove(&tb_ctx.htable, tb, h)) {
110
}
97
@@ -XXX,XX +XXX,XX @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
111
@@ -XXX,XX +XXX,XX @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc,
98
* we can only insert TBs that are fully initialized.
112
99
*/
113
memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS);
100
page_lock_pair(&p, phys_pc, &p2, phys_page2, true);
114
if (!(tb_cflags(tb) & CF_PCREL)) {
101
- tb_page_add(p, tb, 0, phys_pc & TARGET_PAGE_MASK);
115
- data[0] = tb_pc(tb);
102
+ tb_page_add(p, tb, 0, phys_pc);
116
+ data[0] = tb->pc;
103
if (p2) {
117
}
104
tb_page_add(p2, tb, 1, phys_page2);
118
105
} else {
119
/*
106
@@ -XXX,XX +XXX,XX @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
107
if (n == 0) {
108
/* NOTE: tb_end may be after the end of the page, but
109
it is not a problem */
110
- tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
111
+ tb_start = tb->page_addr[0];
112
tb_end = tb_start + tb->size;
113
} else {
114
tb_start = tb->page_addr[1];
115
- tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
116
+ tb_end = tb_start + ((tb->page_addr[0] + tb->size)
117
+ & ~TARGET_PAGE_MASK);
118
}
119
if (!(tb_end <= start || tb_start >= end)) {
120
#ifdef TARGET_HAS_PRECISE_SMC
121
--
120
--
122
2.34.1
121
2.34.1
123
122
124
123
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-14-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/tricore/cpu.c | 3 ++-
9
1 file changed, 2 insertions(+), 1 deletion(-)
10
11
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/tricore/cpu.c
14
+++ b/target/tricore/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void tricore_cpu_synchronize_from_tb(CPUState *cs,
16
TriCoreCPU *cpu = TRICORE_CPU(cs);
17
CPUTriCoreState *env = &cpu->env;
18
19
- env->PC = tb_pc(tb);
20
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
21
+ env->PC = tb->pc;
22
}
23
24
static void tricore_restore_state_to_opc(CPUState *cs,
25
--
26
2.34.1
27
28
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-15-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/sparc/cpu.c | 4 +++-
9
1 file changed, 3 insertions(+), 1 deletion(-)
10
11
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/sparc/cpu.c
14
+++ b/target/sparc/cpu.c
15
@@ -XXX,XX +XXX,XX @@
16
#include "exec/exec-all.h"
17
#include "hw/qdev-properties.h"
18
#include "qapi/visitor.h"
19
+#include "tcg/tcg.h"
20
21
//#define DEBUG_FEATURES
22
23
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_synchronize_from_tb(CPUState *cs,
24
{
25
SPARCCPU *cpu = SPARC_CPU(cs);
26
27
- cpu->env.pc = tb_pc(tb);
28
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
29
+ cpu->env.pc = tb->pc;
30
cpu->env.npc = tb->cs_base;
31
}
32
33
--
34
2.34.1
35
36
diff view generated by jsdifflib
1
The value previously chosen overlaps GUSA_MASK.
1
From: Anton Johansson via <qemu-devel@nongnu.org>
2
2
3
Rename all DELAY_SLOT_* and GUSA_* defines to emphasize
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
that they are included in TB_FLAGs. Add aliases for the
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
FPSCR and SR bits that are included in TB_FLAGS, so that
5
Message-Id: <20230227135202.9710-16-anjo@rev.ng>
6
we don't accidentally reassign those bits.
7
8
Fixes: 4da06fb3062 ("target/sh4: Implement prctl_unalign_sigbus")
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/856
10
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
7
---
13
target/sh4/cpu.h | 56 +++++++++++++------------
8
target/sh4/cpu.c | 6 ++++--
14
linux-user/sh4/signal.c | 6 +--
9
1 file changed, 4 insertions(+), 2 deletions(-)
15
target/sh4/cpu.c | 6 +--
16
target/sh4/helper.c | 6 +--
17
target/sh4/translate.c | 90 ++++++++++++++++++++++-------------------
18
5 files changed, 88 insertions(+), 76 deletions(-)
19
10
20
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/sh4/cpu.h
23
+++ b/target/sh4/cpu.h
24
@@ -XXX,XX +XXX,XX @@
25
#define FPSCR_RM_NEAREST (0 << 0)
26
#define FPSCR_RM_ZERO (1 << 0)
27
28
-#define DELAY_SLOT_MASK 0x7
29
-#define DELAY_SLOT (1 << 0)
30
-#define DELAY_SLOT_CONDITIONAL (1 << 1)
31
-#define DELAY_SLOT_RTE (1 << 2)
32
+#define TB_FLAG_DELAY_SLOT (1 << 0)
33
+#define TB_FLAG_DELAY_SLOT_COND (1 << 1)
34
+#define TB_FLAG_DELAY_SLOT_RTE (1 << 2)
35
+#define TB_FLAG_PENDING_MOVCA (1 << 3)
36
+#define TB_FLAG_GUSA_SHIFT 4 /* [11:4] */
37
+#define TB_FLAG_GUSA_EXCLUSIVE (1 << 12)
38
+#define TB_FLAG_UNALIGN (1 << 13)
39
+#define TB_FLAG_SR_FD (1 << SR_FD) /* 15 */
40
+#define TB_FLAG_FPSCR_PR FPSCR_PR /* 19 */
41
+#define TB_FLAG_FPSCR_SZ FPSCR_SZ /* 20 */
42
+#define TB_FLAG_FPSCR_FR FPSCR_FR /* 21 */
43
+#define TB_FLAG_SR_RB (1 << SR_RB) /* 29 */
44
+#define TB_FLAG_SR_MD (1 << SR_MD) /* 30 */
45
46
-#define TB_FLAG_PENDING_MOVCA (1 << 3)
47
-#define TB_FLAG_UNALIGN (1 << 4)
48
-
49
-#define GUSA_SHIFT 4
50
-#ifdef CONFIG_USER_ONLY
51
-#define GUSA_EXCLUSIVE (1 << 12)
52
-#define GUSA_MASK ((0xff << GUSA_SHIFT) | GUSA_EXCLUSIVE)
53
-#else
54
-/* Provide dummy versions of the above to allow tests against tbflags
55
- to be elided while avoiding ifdefs. */
56
-#define GUSA_EXCLUSIVE 0
57
-#define GUSA_MASK 0
58
-#endif
59
-
60
-#define TB_FLAG_ENVFLAGS_MASK (DELAY_SLOT_MASK | GUSA_MASK)
61
+#define TB_FLAG_DELAY_SLOT_MASK (TB_FLAG_DELAY_SLOT | \
62
+ TB_FLAG_DELAY_SLOT_COND | \
63
+ TB_FLAG_DELAY_SLOT_RTE)
64
+#define TB_FLAG_GUSA_MASK ((0xff << TB_FLAG_GUSA_SHIFT) | \
65
+ TB_FLAG_GUSA_EXCLUSIVE)
66
+#define TB_FLAG_FPSCR_MASK (TB_FLAG_FPSCR_PR | \
67
+ TB_FLAG_FPSCR_SZ | \
68
+ TB_FLAG_FPSCR_FR)
69
+#define TB_FLAG_SR_MASK (TB_FLAG_SR_FD | \
70
+ TB_FLAG_SR_RB | \
71
+ TB_FLAG_SR_MD)
72
+#define TB_FLAG_ENVFLAGS_MASK (TB_FLAG_DELAY_SLOT_MASK | \
73
+ TB_FLAG_GUSA_MASK)
74
75
typedef struct tlb_t {
76
uint32_t vpn;        /* virtual page number */
77
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index (CPUSH4State *env, bool ifetch)
78
{
79
/* The instruction in a RTE delay slot is fetched in privileged
80
mode, but executed in user mode. */
81
- if (ifetch && (env->flags & DELAY_SLOT_RTE)) {
82
+ if (ifetch && (env->flags & TB_FLAG_DELAY_SLOT_RTE)) {
83
return 0;
84
} else {
85
return (env->sr & (1u << SR_MD)) == 0 ? 1 : 0;
86
@@ -XXX,XX +XXX,XX @@ static inline void cpu_get_tb_cpu_state(CPUSH4State *env, target_ulong *pc,
87
{
88
*pc = env->pc;
89
/* For a gUSA region, notice the end of the region. */
90
- *cs_base = env->flags & GUSA_MASK ? env->gregs[0] : 0;
91
- *flags = env->flags /* TB_FLAG_ENVFLAGS_MASK: bits 0-2, 4-12 */
92
- | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR)) /* Bits 19-21 */
93
- | (env->sr & ((1u << SR_MD) | (1u << SR_RB))) /* Bits 29-30 */
94
- | (env->sr & (1u << SR_FD)) /* Bit 15 */
95
+ *cs_base = env->flags & TB_FLAG_GUSA_MASK ? env->gregs[0] : 0;
96
+ *flags = env->flags
97
+ | (env->fpscr & TB_FLAG_FPSCR_MASK)
98
+ | (env->sr & TB_FLAG_SR_MASK)
99
| (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 3 */
100
#ifdef CONFIG_USER_ONLY
101
*flags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus;
102
diff --git a/linux-user/sh4/signal.c b/linux-user/sh4/signal.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/linux-user/sh4/signal.c
105
+++ b/linux-user/sh4/signal.c
106
@@ -XXX,XX +XXX,XX @@ static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc)
107
__get_user(regs->fpul, &sc->sc_fpul);
108
109
regs->tra = -1; /* disable syscall checks */
110
- regs->flags &= ~(DELAY_SLOT_MASK | GUSA_MASK);
111
+ regs->flags = 0;
112
}
113
114
void setup_frame(int sig, struct target_sigaction *ka,
115
@@ -XXX,XX +XXX,XX @@ void setup_frame(int sig, struct target_sigaction *ka,
116
regs->gregs[5] = 0;
117
regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
118
regs->pc = (unsigned long) ka->_sa_handler;
119
- regs->flags &= ~(DELAY_SLOT_MASK | GUSA_MASK);
120
+ regs->flags &= ~(TB_FLAG_DELAY_SLOT_MASK | TB_FLAG_GUSA_MASK);
121
122
unlock_user_struct(frame, frame_addr, 1);
123
return;
124
@@ -XXX,XX +XXX,XX @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
125
regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
126
regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
127
regs->pc = (unsigned long) ka->_sa_handler;
128
- regs->flags &= ~(DELAY_SLOT_MASK | GUSA_MASK);
129
+ regs->flags &= ~(TB_FLAG_DELAY_SLOT_MASK | TB_FLAG_GUSA_MASK);
130
131
unlock_user_struct(frame, frame_addr, 1);
132
return;
133
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
11
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
134
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
135
--- a/target/sh4/cpu.c
13
--- a/target/sh4/cpu.c
136
+++ b/target/sh4/cpu.c
14
+++ b/target/sh4/cpu.c
15
@@ -XXX,XX +XXX,XX @@
16
#include "migration/vmstate.h"
17
#include "exec/exec-all.h"
18
#include "fpu/softfloat-helpers.h"
19
+#include "tcg/tcg.h"
20
21
static void superh_cpu_set_pc(CPUState *cs, vaddr value)
22
{
137
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_synchronize_from_tb(CPUState *cs,
23
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_synchronize_from_tb(CPUState *cs,
24
{
138
SuperHCPU *cpu = SUPERH_CPU(cs);
25
SuperHCPU *cpu = SUPERH_CPU(cs);
139
26
140
cpu->env.pc = tb_pc(tb);
27
- cpu->env.pc = tb_pc(tb);
141
- cpu->env.flags = tb->flags & TB_FLAG_ENVFLAGS_MASK;
28
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
142
+ cpu->env.flags = tb->flags;
29
+ cpu->env.pc = tb->pc;
30
cpu->env.flags = tb->flags & TB_FLAG_ENVFLAGS_MASK;
143
}
31
}
144
32
145
#ifndef CONFIG_USER_ONLY
146
@@ -XXX,XX +XXX,XX @@ static bool superh_io_recompile_replay_branch(CPUState *cs,
33
@@ -XXX,XX +XXX,XX @@ static bool superh_io_recompile_replay_branch(CPUState *cs,
147
SuperHCPU *cpu = SUPERH_CPU(cs);
148
CPUSH4State *env = &cpu->env;
34
CPUSH4State *env = &cpu->env;
149
35
150
- if ((env->flags & ((DELAY_SLOT | DELAY_SLOT_CONDITIONAL))) != 0
36
if ((env->flags & (TB_FLAG_DELAY_SLOT | TB_FLAG_DELAY_SLOT_COND))
151
+ if ((env->flags & (TB_FLAG_DELAY_SLOT | TB_FLAG_DELAY_SLOT_COND))
37
- && env->pc != tb_pc(tb)) {
152
&& env->pc != tb_pc(tb)) {
38
+ && !(cs->tcg_cflags & CF_PCREL) && env->pc != tb->pc) {
153
env->pc -= 2;
39
env->pc -= 2;
154
- env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
40
env->flags &= ~(TB_FLAG_DELAY_SLOT | TB_FLAG_DELAY_SLOT_COND);
155
+ env->flags &= ~(TB_FLAG_DELAY_SLOT | TB_FLAG_DELAY_SLOT_COND);
156
return true;
41
return true;
157
}
158
return false;
159
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/sh4/helper.c
162
+++ b/target/sh4/helper.c
163
@@ -XXX,XX +XXX,XX @@ void superh_cpu_do_interrupt(CPUState *cs)
164
env->sr |= (1u << SR_BL) | (1u << SR_MD) | (1u << SR_RB);
165
env->lock_addr = -1;
166
167
- if (env->flags & DELAY_SLOT_MASK) {
168
+ if (env->flags & TB_FLAG_DELAY_SLOT_MASK) {
169
/* Branch instruction should be executed again before delay slot. */
170
    env->spc -= 2;
171
    /* Clear flags for exception/interrupt routine. */
172
- env->flags &= ~DELAY_SLOT_MASK;
173
+ env->flags &= ~TB_FLAG_DELAY_SLOT_MASK;
174
}
175
176
if (do_exp) {
177
@@ -XXX,XX +XXX,XX @@ bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
178
CPUSH4State *env = &cpu->env;
179
180
/* Delay slots are indivisible, ignore interrupts */
181
- if (env->flags & DELAY_SLOT_MASK) {
182
+ if (env->flags & TB_FLAG_DELAY_SLOT_MASK) {
183
return false;
184
} else {
185
superh_cpu_do_interrupt(cs);
186
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/target/sh4/translate.c
189
+++ b/target/sh4/translate.c
190
@@ -XXX,XX +XXX,XX @@ void superh_cpu_dump_state(CPUState *cs, FILE *f, int flags)
191
         i, env->gregs[i], i + 1, env->gregs[i + 1],
192
         i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
193
}
194
- if (env->flags & DELAY_SLOT) {
195
+ if (env->flags & TB_FLAG_DELAY_SLOT) {
196
qemu_printf("in delay slot (delayed_pc=0x%08x)\n",
197
         env->delayed_pc);
198
- } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
199
+ } else if (env->flags & TB_FLAG_DELAY_SLOT_COND) {
200
qemu_printf("in conditional delay slot (delayed_pc=0x%08x)\n",
201
         env->delayed_pc);
202
- } else if (env->flags & DELAY_SLOT_RTE) {
203
+ } else if (env->flags & TB_FLAG_DELAY_SLOT_RTE) {
204
qemu_fprintf(f, "in rte delay slot (delayed_pc=0x%08x)\n",
205
env->delayed_pc);
206
}
207
@@ -XXX,XX +XXX,XX @@ static inline void gen_save_cpu_state(DisasContext *ctx, bool save_pc)
208
209
static inline bool use_exit_tb(DisasContext *ctx)
210
{
211
- return (ctx->tbflags & GUSA_EXCLUSIVE) != 0;
212
+ return (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE) != 0;
213
}
214
215
static bool use_goto_tb(DisasContext *ctx, target_ulong dest)
216
@@ -XXX,XX +XXX,XX @@ static void gen_conditional_jump(DisasContext *ctx, target_ulong dest,
217
TCGLabel *l1 = gen_new_label();
218
TCGCond cond_not_taken = jump_if_true ? TCG_COND_EQ : TCG_COND_NE;
219
220
- if (ctx->tbflags & GUSA_EXCLUSIVE) {
221
+ if (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE) {
222
/* When in an exclusive region, we must continue to the end.
223
Therefore, exit the region on a taken branch, but otherwise
224
fall through to the next instruction. */
225
tcg_gen_brcondi_i32(cond_not_taken, cpu_sr_t, 0, l1);
226
- tcg_gen_movi_i32(cpu_flags, ctx->envflags & ~GUSA_MASK);
227
+ tcg_gen_movi_i32(cpu_flags, ctx->envflags & ~TB_FLAG_GUSA_MASK);
228
/* Note that this won't actually use a goto_tb opcode because we
229
disallow it in use_goto_tb, but it handles exit + singlestep. */
230
gen_goto_tb(ctx, 0, dest);
231
@@ -XXX,XX +XXX,XX @@ static void gen_delayed_conditional_jump(DisasContext * ctx)
232
tcg_gen_mov_i32(ds, cpu_delayed_cond);
233
tcg_gen_discard_i32(cpu_delayed_cond);
234
235
- if (ctx->tbflags & GUSA_EXCLUSIVE) {
236
+ if (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE) {
237
/* When in an exclusive region, we must continue to the end.
238
Therefore, exit the region on a taken branch, but otherwise
239
fall through to the next instruction. */
240
tcg_gen_brcondi_i32(TCG_COND_EQ, ds, 0, l1);
241
242
/* Leave the gUSA region. */
243
- tcg_gen_movi_i32(cpu_flags, ctx->envflags & ~GUSA_MASK);
244
+ tcg_gen_movi_i32(cpu_flags, ctx->envflags & ~TB_FLAG_GUSA_MASK);
245
gen_jump(ctx);
246
247
gen_set_label(l1);
248
@@ -XXX,XX +XXX,XX @@ static inline void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
249
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
250
251
#define CHECK_NOT_DELAY_SLOT \
252
- if (ctx->envflags & DELAY_SLOT_MASK) { \
253
- goto do_illegal_slot; \
254
+ if (ctx->envflags & TB_FLAG_DELAY_SLOT_MASK) { \
255
+ goto do_illegal_slot; \
256
}
257
258
#define CHECK_PRIVILEGED \
259
@@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx)
260
case 0x000b:        /* rts */
261
    CHECK_NOT_DELAY_SLOT
262
    tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
263
- ctx->envflags |= DELAY_SLOT;
264
+ ctx->envflags |= TB_FLAG_DELAY_SLOT;
265
    ctx->delayed_pc = (uint32_t) - 1;
266
    return;
267
case 0x0028:        /* clrmac */
268
@@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx)
269
    CHECK_NOT_DELAY_SLOT
270
gen_write_sr(cpu_ssr);
271
    tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
272
- ctx->envflags |= DELAY_SLOT_RTE;
273
+ ctx->envflags |= TB_FLAG_DELAY_SLOT_RTE;
274
    ctx->delayed_pc = (uint32_t) - 1;
275
ctx->base.is_jmp = DISAS_STOP;
276
    return;
277
@@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx)
278
    return;
279
case 0xe000:        /* mov #imm,Rn */
280
#ifdef CONFIG_USER_ONLY
281
- /* Detect the start of a gUSA region. If so, update envflags
282
- and end the TB. This will allow us to see the end of the
283
- region (stored in R0) in the next TB. */
284
+ /*
285
+ * Detect the start of a gUSA region (mov #-n, r15).
286
+ * If so, update envflags and end the TB. This will allow us
287
+ * to see the end of the region (stored in R0) in the next TB.
288
+ */
289
if (B11_8 == 15 && B7_0s < 0 &&
290
(tb_cflags(ctx->base.tb) & CF_PARALLEL)) {
291
- ctx->envflags = deposit32(ctx->envflags, GUSA_SHIFT, 8, B7_0s);
292
+ ctx->envflags =
293
+ deposit32(ctx->envflags, TB_FLAG_GUSA_SHIFT, 8, B7_0s);
294
ctx->base.is_jmp = DISAS_STOP;
295
}
296
#endif
297
@@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx)
298
case 0xa000:        /* bra disp */
299
    CHECK_NOT_DELAY_SLOT
300
ctx->delayed_pc = ctx->base.pc_next + 4 + B11_0s * 2;
301
- ctx->envflags |= DELAY_SLOT;
302
+ ctx->envflags |= TB_FLAG_DELAY_SLOT;
303
    return;
304
case 0xb000:        /* bsr disp */
305
    CHECK_NOT_DELAY_SLOT
306
tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
307
ctx->delayed_pc = ctx->base.pc_next + 4 + B11_0s * 2;
308
- ctx->envflags |= DELAY_SLOT;
309
+ ctx->envflags |= TB_FLAG_DELAY_SLOT;
310
    return;
311
}
312
313
@@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx)
314
    CHECK_NOT_DELAY_SLOT
315
tcg_gen_xori_i32(cpu_delayed_cond, cpu_sr_t, 1);
316
ctx->delayed_pc = ctx->base.pc_next + 4 + B7_0s * 2;
317
- ctx->envflags |= DELAY_SLOT_CONDITIONAL;
318
+ ctx->envflags |= TB_FLAG_DELAY_SLOT_COND;
319
    return;
320
case 0x8900:        /* bt label */
321
    CHECK_NOT_DELAY_SLOT
322
@@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx)
323
    CHECK_NOT_DELAY_SLOT
324
tcg_gen_mov_i32(cpu_delayed_cond, cpu_sr_t);
325
ctx->delayed_pc = ctx->base.pc_next + 4 + B7_0s * 2;
326
- ctx->envflags |= DELAY_SLOT_CONDITIONAL;
327
+ ctx->envflags |= TB_FLAG_DELAY_SLOT_COND;
328
    return;
329
case 0x8800:        /* cmp/eq #imm,R0 */
330
tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(0), B7_0s);
331
@@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx)
332
case 0x0023:        /* braf Rn */
333
    CHECK_NOT_DELAY_SLOT
334
tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->base.pc_next + 4);
335
- ctx->envflags |= DELAY_SLOT;
336
+ ctx->envflags |= TB_FLAG_DELAY_SLOT;
337
    ctx->delayed_pc = (uint32_t) - 1;
338
    return;
339
case 0x0003:        /* bsrf Rn */
340
    CHECK_NOT_DELAY_SLOT
341
tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
342
    tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
343
- ctx->envflags |= DELAY_SLOT;
344
+ ctx->envflags |= TB_FLAG_DELAY_SLOT;
345
    ctx->delayed_pc = (uint32_t) - 1;
346
    return;
347
case 0x4015:        /* cmp/pl Rn */
348
@@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx)
349
case 0x402b:        /* jmp @Rn */
350
    CHECK_NOT_DELAY_SLOT
351
    tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
352
- ctx->envflags |= DELAY_SLOT;
353
+ ctx->envflags |= TB_FLAG_DELAY_SLOT;
354
    ctx->delayed_pc = (uint32_t) - 1;
355
    return;
356
case 0x400b:        /* jsr @Rn */
357
    CHECK_NOT_DELAY_SLOT
358
tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
359
    tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
360
- ctx->envflags |= DELAY_SLOT;
361
+ ctx->envflags |= TB_FLAG_DELAY_SLOT;
362
    ctx->delayed_pc = (uint32_t) - 1;
363
    return;
364
case 0x400e:        /* ldc Rm,SR */
365
@@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx)
366
fflush(stderr);
367
#endif
368
do_illegal:
369
- if (ctx->envflags & DELAY_SLOT_MASK) {
370
+ if (ctx->envflags & TB_FLAG_DELAY_SLOT_MASK) {
371
do_illegal_slot:
372
gen_save_cpu_state(ctx, true);
373
gen_helper_raise_slot_illegal_instruction(cpu_env);
374
@@ -XXX,XX +XXX,XX @@ static void _decode_opc(DisasContext * ctx)
375
376
do_fpu_disabled:
377
gen_save_cpu_state(ctx, true);
378
- if (ctx->envflags & DELAY_SLOT_MASK) {
379
+ if (ctx->envflags & TB_FLAG_DELAY_SLOT_MASK) {
380
gen_helper_raise_slot_fpu_disable(cpu_env);
381
} else {
382
gen_helper_raise_fpu_disable(cpu_env);
383
@@ -XXX,XX +XXX,XX @@ static void decode_opc(DisasContext * ctx)
384
385
_decode_opc(ctx);
386
387
- if (old_flags & DELAY_SLOT_MASK) {
388
+ if (old_flags & TB_FLAG_DELAY_SLOT_MASK) {
389
/* go out of the delay slot */
390
- ctx->envflags &= ~DELAY_SLOT_MASK;
391
+ ctx->envflags &= ~TB_FLAG_DELAY_SLOT_MASK;
392
393
/* When in an exclusive region, we must continue to the end
394
for conditional branches. */
395
- if (ctx->tbflags & GUSA_EXCLUSIVE
396
- && old_flags & DELAY_SLOT_CONDITIONAL) {
397
+ if (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE
398
+ && old_flags & TB_FLAG_DELAY_SLOT_COND) {
399
gen_delayed_conditional_jump(ctx);
400
return;
401
}
402
/* Otherwise this is probably an invalid gUSA region.
403
Drop the GUSA bits so the next TB doesn't see them. */
404
- ctx->envflags &= ~GUSA_MASK;
405
+ ctx->envflags &= ~TB_FLAG_GUSA_MASK;
406
407
tcg_gen_movi_i32(cpu_flags, ctx->envflags);
408
- if (old_flags & DELAY_SLOT_CONDITIONAL) {
409
+ if (old_flags & TB_FLAG_DELAY_SLOT_COND) {
410
     gen_delayed_conditional_jump(ctx);
411
} else {
412
gen_jump(ctx);
413
@@ -XXX,XX +XXX,XX @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
414
}
415
416
/* The entire region has been translated. */
417
- ctx->envflags &= ~GUSA_MASK;
418
+ ctx->envflags &= ~TB_FLAG_GUSA_MASK;
419
ctx->base.pc_next = pc_end;
420
ctx->base.num_insns += max_insns - 1;
421
return;
422
@@ -XXX,XX +XXX,XX @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
423
424
/* Restart with the EXCLUSIVE bit set, within a TB run via
425
cpu_exec_step_atomic holding the exclusive lock. */
426
- ctx->envflags |= GUSA_EXCLUSIVE;
427
+ ctx->envflags |= TB_FLAG_GUSA_EXCLUSIVE;
428
gen_save_cpu_state(ctx, false);
429
gen_helper_exclusive(cpu_env);
430
ctx->base.is_jmp = DISAS_NORETURN;
431
@@ -XXX,XX +XXX,XX @@ static void sh4_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
432
(tbflags & (1 << SR_RB))) * 0x10;
433
ctx->fbank = tbflags & FPSCR_FR ? 0x10 : 0;
434
435
- if (tbflags & GUSA_MASK) {
436
+#ifdef CONFIG_USER_ONLY
437
+ if (tbflags & TB_FLAG_GUSA_MASK) {
438
+ /* In gUSA exclusive region. */
439
uint32_t pc = ctx->base.pc_next;
440
uint32_t pc_end = ctx->base.tb->cs_base;
441
- int backup = sextract32(ctx->tbflags, GUSA_SHIFT, 8);
442
+ int backup = sextract32(ctx->tbflags, TB_FLAG_GUSA_SHIFT, 8);
443
int max_insns = (pc_end - pc) / 2;
444
445
if (pc != pc_end + backup || max_insns < 2) {
446
/* This is a malformed gUSA region. Don't do anything special,
447
since the interpreter is likely to get confused. */
448
- ctx->envflags &= ~GUSA_MASK;
449
- } else if (tbflags & GUSA_EXCLUSIVE) {
450
+ ctx->envflags &= ~TB_FLAG_GUSA_MASK;
451
+ } else if (tbflags & TB_FLAG_GUSA_EXCLUSIVE) {
452
/* Regardless of single-stepping or the end of the page,
453
we must complete execution of the gUSA region while
454
holding the exclusive lock. */
455
@@ -XXX,XX +XXX,XX @@ static void sh4_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
456
return;
457
}
458
}
459
+#endif
460
461
/* Since the ISA is fixed-width, we can bound by the number
462
of instructions remaining on the page. */
463
@@ -XXX,XX +XXX,XX @@ static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
464
DisasContext *ctx = container_of(dcbase, DisasContext, base);
465
466
#ifdef CONFIG_USER_ONLY
467
- if (unlikely(ctx->envflags & GUSA_MASK)
468
- && !(ctx->envflags & GUSA_EXCLUSIVE)) {
469
+ if (unlikely(ctx->envflags & TB_FLAG_GUSA_MASK)
470
+ && !(ctx->envflags & TB_FLAG_GUSA_EXCLUSIVE)) {
471
/* We're in an gUSA region, and we have not already fallen
472
back on using an exclusive region. Attempt to parse the
473
region into a single supported atomic operation. Failure
474
@@ -XXX,XX +XXX,XX @@ static void sh4_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
475
{
476
DisasContext *ctx = container_of(dcbase, DisasContext, base);
477
478
- if (ctx->tbflags & GUSA_EXCLUSIVE) {
479
+ if (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE) {
480
/* Ending the region of exclusivity. Clear the bits. */
481
- ctx->envflags &= ~GUSA_MASK;
482
+ ctx->envflags &= ~TB_FLAG_GUSA_MASK;
483
}
484
485
switch (ctx->base.is_jmp) {
486
--
42
--
487
2.34.1
43
2.34.1
44
45
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-17-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/rx/cpu.c | 3 ++-
9
1 file changed, 2 insertions(+), 1 deletion(-)
10
11
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/rx/cpu.c
14
+++ b/target/rx/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_synchronize_from_tb(CPUState *cs,
16
{
17
RXCPU *cpu = RX_CPU(cs);
18
19
- cpu->env.pc = tb_pc(tb);
20
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
21
+ cpu->env.pc = tb->pc;
22
}
23
24
static void rx_restore_state_to_opc(CPUState *cs,
25
--
26
2.34.1
27
28
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-Id: <20230227135202.9710-18-anjo@rev.ng>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
target/riscv/cpu.c | 7 +++++--
10
1 file changed, 5 insertions(+), 2 deletions(-)
11
12
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/cpu.c
15
+++ b/target/riscv/cpu.c
16
@@ -XXX,XX +XXX,XX @@
17
#include "fpu/softfloat-helpers.h"
18
#include "sysemu/kvm.h"
19
#include "kvm_riscv.h"
20
+#include "tcg/tcg.h"
21
22
/* RISC-V CPU definitions */
23
24
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
25
CPURISCVState *env = &cpu->env;
26
RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
27
28
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
29
+
30
if (xl == MXL_RV32) {
31
- env->pc = (int32_t)tb_pc(tb);
32
+ env->pc = (int32_t) tb->pc;
33
} else {
34
- env->pc = tb_pc(tb);
35
+ env->pc = tb->pc;
36
}
37
}
38
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-19-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/openrisc/cpu.c | 4 +++-
9
1 file changed, 3 insertions(+), 1 deletion(-)
10
11
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/openrisc/cpu.c
14
+++ b/target/openrisc/cpu.c
15
@@ -XXX,XX +XXX,XX @@
16
#include "qemu/qemu-print.h"
17
#include "cpu.h"
18
#include "exec/exec-all.h"
19
+#include "tcg/tcg.h"
20
21
static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
22
{
23
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_synchronize_from_tb(CPUState *cs,
24
{
25
OpenRISCCPU *cpu = OPENRISC_CPU(cs);
26
27
- cpu->env.pc = tb_pc(tb);
28
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
29
+ cpu->env.pc = tb->pc;
30
}
31
32
static void openrisc_restore_state_to_opc(CPUState *cs,
33
--
34
2.34.1
35
36
diff view generated by jsdifflib
1
The availability of tb->pc will shortly be conditional.
1
From: Anton Johansson via <qemu-devel@nongnu.org>
2
Introduce accessor functions to minimize ifdefs.
3
2
4
Pass around a known pc to places like tcg_gen_code,
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
5
where the caller must already have the value.
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
5
Message-Id: <20230227135202.9710-20-anjo@rev.ng>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
7
---
10
accel/tcg/internal.h | 6 ++++
8
target/mips/tcg/exception.c | 3 ++-
11
include/exec/exec-all.h | 6 ++++
9
target/mips/tcg/sysemu/special_helper.c | 2 +-
12
include/tcg/tcg.h | 2 +-
10
2 files changed, 3 insertions(+), 2 deletions(-)
13
accel/tcg/cpu-exec.c | 46 ++++++++++++++-----------
14
accel/tcg/translate-all.c | 37 +++++++++++---------
15
target/arm/cpu.c | 4 +--
16
target/avr/cpu.c | 2 +-
17
target/hexagon/cpu.c | 2 +-
18
target/hppa/cpu.c | 4 +--
19
target/i386/tcg/tcg-cpu.c | 2 +-
20
target/loongarch/cpu.c | 2 +-
21
target/microblaze/cpu.c | 2 +-
22
target/mips/tcg/exception.c | 2 +-
23
target/mips/tcg/sysemu/special_helper.c | 2 +-
24
target/openrisc/cpu.c | 2 +-
25
target/riscv/cpu.c | 4 +--
26
target/rx/cpu.c | 2 +-
27
target/sh4/cpu.c | 4 +--
28
target/sparc/cpu.c | 2 +-
29
target/tricore/cpu.c | 2 +-
30
tcg/tcg.c | 8 ++---
31
21 files changed, 82 insertions(+), 61 deletions(-)
32
11
33
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/accel/tcg/internal.h
36
+++ b/accel/tcg/internal.h
37
@@ -XXX,XX +XXX,XX @@ G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
38
void page_init(void);
39
void tb_htable_init(void);
40
41
+/* Return the current PC from CPU, which may be cached in TB. */
42
+static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
43
+{
44
+ return tb_pc(tb);
45
+}
46
+
47
#endif /* ACCEL_TCG_INTERNAL_H */
48
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/include/exec/exec-all.h
51
+++ b/include/exec/exec-all.h
52
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock {
53
uintptr_t jmp_dest[2];
54
};
55
56
+/* Hide the read to avoid ifdefs for TARGET_TB_PCREL. */
57
+static inline target_ulong tb_pc(const TranslationBlock *tb)
58
+{
59
+ return tb->pc;
60
+}
61
+
62
/* Hide the qatomic_read to make code a little easier on the eyes */
63
static inline uint32_t tb_cflags(const TranslationBlock *tb)
64
{
65
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
66
index XXXXXXX..XXXXXXX 100644
67
--- a/include/tcg/tcg.h
68
+++ b/include/tcg/tcg.h
69
@@ -XXX,XX +XXX,XX @@ void tcg_register_thread(void);
70
void tcg_prologue_init(TCGContext *s);
71
void tcg_func_start(TCGContext *s);
72
73
-int tcg_gen_code(TCGContext *s, TranslationBlock *tb);
74
+int tcg_gen_code(TCGContext *s, TranslationBlock *tb, target_ulong pc_start);
75
76
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
77
78
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/accel/tcg/cpu-exec.c
81
+++ b/accel/tcg/cpu-exec.c
82
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
83
const TranslationBlock *tb = p;
84
const struct tb_desc *desc = d;
85
86
- if (tb->pc == desc->pc &&
87
+ if (tb_pc(tb) == desc->pc &&
88
tb->page_addr[0] == desc->page_addr0 &&
89
tb->cs_base == desc->cs_base &&
90
tb->flags == desc->flags &&
91
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
92
return tb;
93
}
94
95
-static inline void log_cpu_exec(target_ulong pc, CPUState *cpu,
96
- const TranslationBlock *tb)
97
+static void log_cpu_exec(target_ulong pc, CPUState *cpu,
98
+ const TranslationBlock *tb)
99
{
100
- if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_CPU | CPU_LOG_EXEC))
101
- && qemu_log_in_addr_range(pc)) {
102
-
103
+ if (qemu_log_in_addr_range(pc)) {
104
qemu_log_mask(CPU_LOG_EXEC,
105
"Trace %d: %p [" TARGET_FMT_lx
106
"/" TARGET_FMT_lx "/%08x/%08x] %s\n",
107
@@ -XXX,XX +XXX,XX @@ const void *HELPER(lookup_tb_ptr)(CPUArchState *env)
108
return tcg_code_gen_epilogue;
109
}
110
111
- log_cpu_exec(pc, cpu, tb);
112
+ if (qemu_loglevel_mask(CPU_LOG_TB_CPU | CPU_LOG_EXEC)) {
113
+ log_cpu_exec(pc, cpu, tb);
114
+ }
115
116
return tb->tc.ptr;
117
}
118
@@ -XXX,XX +XXX,XX @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
119
TranslationBlock *last_tb;
120
const void *tb_ptr = itb->tc.ptr;
121
122
- log_cpu_exec(itb->pc, cpu, itb);
123
+ if (qemu_loglevel_mask(CPU_LOG_TB_CPU | CPU_LOG_EXEC)) {
124
+ log_cpu_exec(log_pc(cpu, itb), cpu, itb);
125
+ }
126
127
qemu_thread_jit_execute();
128
ret = tcg_qemu_tb_exec(env, tb_ptr);
129
@@ -XXX,XX +XXX,XX @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
130
* of the start of the TB.
131
*/
132
CPUClass *cc = CPU_GET_CLASS(cpu);
133
- qemu_log_mask_and_addr(CPU_LOG_EXEC, last_tb->pc,
134
- "Stopped execution of TB chain before %p ["
135
- TARGET_FMT_lx "] %s\n",
136
- last_tb->tc.ptr, last_tb->pc,
137
- lookup_symbol(last_tb->pc));
138
+
139
if (cc->tcg_ops->synchronize_from_tb) {
140
cc->tcg_ops->synchronize_from_tb(cpu, last_tb);
141
} else {
142
assert(cc->set_pc);
143
- cc->set_pc(cpu, last_tb->pc);
144
+ cc->set_pc(cpu, tb_pc(last_tb));
145
+ }
146
+ if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
147
+ target_ulong pc = log_pc(cpu, last_tb);
148
+ if (qemu_log_in_addr_range(pc)) {
149
+ qemu_log("Stopped execution of TB chain before %p ["
150
+ TARGET_FMT_lx "] %s\n",
151
+ last_tb->tc.ptr, pc, lookup_symbol(pc));
152
+ }
153
}
154
}
155
156
@@ -XXX,XX +XXX,XX @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
157
158
qemu_spin_unlock(&tb_next->jmp_lock);
159
160
- qemu_log_mask_and_addr(CPU_LOG_EXEC, tb->pc,
161
- "Linking TBs %p [" TARGET_FMT_lx
162
- "] index %d -> %p [" TARGET_FMT_lx "]\n",
163
- tb->tc.ptr, tb->pc, n,
164
- tb_next->tc.ptr, tb_next->pc);
165
+ qemu_log_mask(CPU_LOG_EXEC, "Linking TBs %p index %d -> %p\n",
166
+ tb->tc.ptr, n, tb_next->tc.ptr);
167
return;
168
169
out_unlock_next:
170
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
171
}
172
173
static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
174
+ target_ulong pc,
175
TranslationBlock **last_tb, int *tb_exit)
176
{
177
int32_t insns_left;
178
179
- trace_exec_tb(tb, tb->pc);
180
+ trace_exec_tb(tb, pc);
181
tb = cpu_tb_exec(cpu, tb, tb_exit);
182
if (*tb_exit != TB_EXIT_REQUESTED) {
183
*last_tb = tb;
184
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
185
tb_add_jump(last_tb, tb_exit, tb);
186
}
187
188
- cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit);
189
+ cpu_loop_exec_tb(cpu, tb, pc, &last_tb, &tb_exit);
190
191
/* Try to align the host and virtual clocks
192
if the guest is in advance */
193
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
194
index XXXXXXX..XXXXXXX 100644
195
--- a/accel/tcg/translate-all.c
196
+++ b/accel/tcg/translate-all.c
197
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
198
199
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
200
if (i == 0) {
201
- prev = (j == 0 ? tb->pc : 0);
202
+ prev = (j == 0 ? tb_pc(tb) : 0);
203
} else {
204
prev = tcg_ctx->gen_insn_data[i - 1][j];
205
}
206
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
207
static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
208
uintptr_t searched_pc, bool reset_icount)
209
{
210
- target_ulong data[TARGET_INSN_START_WORDS] = { tb->pc };
211
+ target_ulong data[TARGET_INSN_START_WORDS] = { tb_pc(tb) };
212
uintptr_t host_pc = (uintptr_t)tb->tc.ptr;
213
CPUArchState *env = cpu->env_ptr;
214
const uint8_t *p = tb->tc.ptr + tb->tc.size;
215
@@ -XXX,XX +XXX,XX @@ static bool tb_cmp(const void *ap, const void *bp)
216
const TranslationBlock *a = ap;
217
const TranslationBlock *b = bp;
218
219
- return a->pc == b->pc &&
220
+ return tb_pc(a) == tb_pc(b) &&
221
a->cs_base == b->cs_base &&
222
a->flags == b->flags &&
223
(tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) &&
224
@@ -XXX,XX +XXX,XX @@ static void do_tb_invalidate_check(void *p, uint32_t hash, void *userp)
225
TranslationBlock *tb = p;
226
target_ulong addr = *(target_ulong *)userp;
227
228
- if (!(addr + TARGET_PAGE_SIZE <= tb->pc || addr >= tb->pc + tb->size)) {
229
+ if (!(addr + TARGET_PAGE_SIZE <= tb_pc(tb) ||
230
+ addr >= tb_pc(tb) + tb->size)) {
231
printf("ERROR invalidate: address=" TARGET_FMT_lx
232
- " PC=%08lx size=%04x\n", addr, (long)tb->pc, tb->size);
233
+ " PC=%08lx size=%04x\n", addr, (long)tb_pc(tb), tb->size);
234
}
235
}
236
237
@@ -XXX,XX +XXX,XX @@ static void do_tb_page_check(void *p, uint32_t hash, void *userp)
238
TranslationBlock *tb = p;
239
int flags1, flags2;
240
241
- flags1 = page_get_flags(tb->pc);
242
- flags2 = page_get_flags(tb->pc + tb->size - 1);
243
+ flags1 = page_get_flags(tb_pc(tb));
244
+ flags2 = page_get_flags(tb_pc(tb) + tb->size - 1);
245
if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
246
printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
247
- (long)tb->pc, tb->size, flags1, flags2);
248
+ (long)tb_pc(tb), tb->size, flags1, flags2);
249
}
250
}
251
252
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
253
254
/* remove the TB from the hash list */
255
phys_pc = tb->page_addr[0];
256
- h = tb_hash_func(phys_pc, tb->pc, tb->flags, orig_cflags,
257
+ h = tb_hash_func(phys_pc, tb_pc(tb), tb->flags, orig_cflags,
258
tb->trace_vcpu_dstate);
259
if (!qht_remove(&tb_ctx.htable, tb, h)) {
260
return;
261
@@ -XXX,XX +XXX,XX @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
262
}
263
264
/* add in the hash table */
265
- h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags,
266
+ h = tb_hash_func(phys_pc, tb_pc(tb), tb->flags, tb->cflags,
267
tb->trace_vcpu_dstate);
268
qht_insert(&tb_ctx.htable, tb, h, &existing_tb);
269
270
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
271
tcg_ctx->cpu = NULL;
272
max_insns = tb->icount;
273
274
- trace_translate_block(tb, tb->pc, tb->tc.ptr);
275
+ trace_translate_block(tb, pc, tb->tc.ptr);
276
277
/* generate machine code */
278
tb->jmp_reset_offset[0] = TB_JMP_RESET_OFFSET_INVALID;
279
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
280
ti = profile_getclock();
281
#endif
282
283
- gen_code_size = tcg_gen_code(tcg_ctx, tb);
284
+ gen_code_size = tcg_gen_code(tcg_ctx, tb, pc);
285
if (unlikely(gen_code_size < 0)) {
286
error_return:
287
switch (gen_code_size) {
288
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
289
290
#ifdef DEBUG_DISAS
291
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) &&
292
- qemu_log_in_addr_range(tb->pc)) {
293
+ qemu_log_in_addr_range(pc)) {
294
FILE *logfile = qemu_log_trylock();
295
if (logfile) {
296
int code_size, data_size;
297
@@ -XXX,XX +XXX,XX @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
298
*/
299
cpu->cflags_next_tb = curr_cflags(cpu) | CF_MEMI_ONLY | CF_LAST_IO | n;
300
301
- qemu_log_mask_and_addr(CPU_LOG_EXEC, tb->pc,
302
- "cpu_io_recompile: rewound execution of TB to "
303
- TARGET_FMT_lx "\n", tb->pc);
304
+ if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
305
+ target_ulong pc = log_pc(cpu, tb);
306
+ if (qemu_log_in_addr_range(pc)) {
307
+ qemu_log("cpu_io_recompile: rewound execution of TB to "
308
+ TARGET_FMT_lx "\n", pc);
309
+ }
310
+ }
311
312
cpu_loop_exit_noexc(cpu);
313
}
314
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
315
index XXXXXXX..XXXXXXX 100644
316
--- a/target/arm/cpu.c
317
+++ b/target/arm/cpu.c
318
@@ -XXX,XX +XXX,XX @@ void arm_cpu_synchronize_from_tb(CPUState *cs,
319
* never possible for an AArch64 TB to chain to an AArch32 TB.
320
*/
321
if (is_a64(env)) {
322
- env->pc = tb->pc;
323
+ env->pc = tb_pc(tb);
324
} else {
325
- env->regs[15] = tb->pc;
326
+ env->regs[15] = tb_pc(tb);
327
}
328
}
329
#endif /* CONFIG_TCG */
330
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
331
index XXXXXXX..XXXXXXX 100644
332
--- a/target/avr/cpu.c
333
+++ b/target/avr/cpu.c
334
@@ -XXX,XX +XXX,XX @@ static void avr_cpu_synchronize_from_tb(CPUState *cs,
335
AVRCPU *cpu = AVR_CPU(cs);
336
CPUAVRState *env = &cpu->env;
337
338
- env->pc_w = tb->pc / 2; /* internally PC points to words */
339
+ env->pc_w = tb_pc(tb) / 2; /* internally PC points to words */
340
}
341
342
static void avr_cpu_reset(DeviceState *ds)
343
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
344
index XXXXXXX..XXXXXXX 100644
345
--- a/target/hexagon/cpu.c
346
+++ b/target/hexagon/cpu.c
347
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_synchronize_from_tb(CPUState *cs,
348
{
349
HexagonCPU *cpu = HEXAGON_CPU(cs);
350
CPUHexagonState *env = &cpu->env;
351
- env->gpr[HEX_REG_PC] = tb->pc;
352
+ env->gpr[HEX_REG_PC] = tb_pc(tb);
353
}
354
355
static bool hexagon_cpu_has_work(CPUState *cs)
356
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
357
index XXXXXXX..XXXXXXX 100644
358
--- a/target/hppa/cpu.c
359
+++ b/target/hppa/cpu.c
360
@@ -XXX,XX +XXX,XX @@ static void hppa_cpu_synchronize_from_tb(CPUState *cs,
361
HPPACPU *cpu = HPPA_CPU(cs);
362
363
#ifdef CONFIG_USER_ONLY
364
- cpu->env.iaoq_f = tb->pc;
365
+ cpu->env.iaoq_f = tb_pc(tb);
366
cpu->env.iaoq_b = tb->cs_base;
367
#else
368
/* Recover the IAOQ values from the GVA + PRIV. */
369
@@ -XXX,XX +XXX,XX @@ static void hppa_cpu_synchronize_from_tb(CPUState *cs,
370
int32_t diff = cs_base;
371
372
cpu->env.iasq_f = iasq_f;
373
- cpu->env.iaoq_f = (tb->pc & ~iasq_f) + priv;
374
+ cpu->env.iaoq_f = (tb_pc(tb) & ~iasq_f) + priv;
375
if (diff) {
376
cpu->env.iaoq_b = cpu->env.iaoq_f + diff;
377
}
378
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
379
index XXXXXXX..XXXXXXX 100644
380
--- a/target/i386/tcg/tcg-cpu.c
381
+++ b/target/i386/tcg/tcg-cpu.c
382
@@ -XXX,XX +XXX,XX @@ static void x86_cpu_synchronize_from_tb(CPUState *cs,
383
{
384
X86CPU *cpu = X86_CPU(cs);
385
386
- cpu->env.eip = tb->pc - tb->cs_base;
387
+ cpu->env.eip = tb_pc(tb) - tb->cs_base;
388
}
389
390
#ifndef CONFIG_USER_ONLY
391
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
392
index XXXXXXX..XXXXXXX 100644
393
--- a/target/loongarch/cpu.c
394
+++ b/target/loongarch/cpu.c
395
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
396
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
397
CPULoongArchState *env = &cpu->env;
398
399
- env->pc = tb->pc;
400
+ env->pc = tb_pc(tb);
401
}
402
#endif /* CONFIG_TCG */
403
404
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
405
index XXXXXXX..XXXXXXX 100644
406
--- a/target/microblaze/cpu.c
407
+++ b/target/microblaze/cpu.c
408
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_synchronize_from_tb(CPUState *cs,
409
{
410
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
411
412
- cpu->env.pc = tb->pc;
413
+ cpu->env.pc = tb_pc(tb);
414
cpu->env.iflags = tb->flags & IFLAGS_TB_MASK;
415
}
416
417
diff --git a/target/mips/tcg/exception.c b/target/mips/tcg/exception.c
12
diff --git a/target/mips/tcg/exception.c b/target/mips/tcg/exception.c
418
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
419
--- a/target/mips/tcg/exception.c
14
--- a/target/mips/tcg/exception.c
420
+++ b/target/mips/tcg/exception.c
15
+++ b/target/mips/tcg/exception.c
421
@@ -XXX,XX +XXX,XX @@ void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb)
16
@@ -XXX,XX +XXX,XX @@ void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb)
422
MIPSCPU *cpu = MIPS_CPU(cs);
17
MIPSCPU *cpu = MIPS_CPU(cs);
423
CPUMIPSState *env = &cpu->env;
18
CPUMIPSState *env = &cpu->env;
424
19
425
- env->active_tc.PC = tb->pc;
20
- env->active_tc.PC = tb_pc(tb);
426
+ env->active_tc.PC = tb_pc(tb);
21
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
22
+ env->active_tc.PC = tb->pc;
427
env->hflags &= ~MIPS_HFLAG_BMASK;
23
env->hflags &= ~MIPS_HFLAG_BMASK;
428
env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
24
env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
429
}
25
}
430
diff --git a/target/mips/tcg/sysemu/special_helper.c b/target/mips/tcg/sysemu/special_helper.c
26
diff --git a/target/mips/tcg/sysemu/special_helper.c b/target/mips/tcg/sysemu/special_helper.c
431
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
432
--- a/target/mips/tcg/sysemu/special_helper.c
28
--- a/target/mips/tcg/sysemu/special_helper.c
433
+++ b/target/mips/tcg/sysemu/special_helper.c
29
+++ b/target/mips/tcg/sysemu/special_helper.c
434
@@ -XXX,XX +XXX,XX @@ bool mips_io_recompile_replay_branch(CPUState *cs, const TranslationBlock *tb)
30
@@ -XXX,XX +XXX,XX @@ bool mips_io_recompile_replay_branch(CPUState *cs, const TranslationBlock *tb)
435
CPUMIPSState *env = &cpu->env;
31
CPUMIPSState *env = &cpu->env;
436
32
437
if ((env->hflags & MIPS_HFLAG_BMASK) != 0
33
if ((env->hflags & MIPS_HFLAG_BMASK) != 0
438
- && env->active_tc.PC != tb->pc) {
34
- && env->active_tc.PC != tb_pc(tb)) {
439
+ && env->active_tc.PC != tb_pc(tb)) {
35
+ && !(cs->tcg_cflags & CF_PCREL) && env->active_tc.PC != tb->pc) {
440
env->active_tc.PC -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4);
36
env->active_tc.PC -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4);
441
env->hflags &= ~MIPS_HFLAG_BMASK;
37
env->hflags &= ~MIPS_HFLAG_BMASK;
442
return true;
38
return true;
443
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
444
index XXXXXXX..XXXXXXX 100644
445
--- a/target/openrisc/cpu.c
446
+++ b/target/openrisc/cpu.c
447
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_synchronize_from_tb(CPUState *cs,
448
{
449
OpenRISCCPU *cpu = OPENRISC_CPU(cs);
450
451
- cpu->env.pc = tb->pc;
452
+ cpu->env.pc = tb_pc(tb);
453
}
454
455
456
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
457
index XXXXXXX..XXXXXXX 100644
458
--- a/target/riscv/cpu.c
459
+++ b/target/riscv/cpu.c
460
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
461
RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
462
463
if (xl == MXL_RV32) {
464
- env->pc = (int32_t)tb->pc;
465
+ env->pc = (int32_t)tb_pc(tb);
466
} else {
467
- env->pc = tb->pc;
468
+ env->pc = tb_pc(tb);
469
}
470
}
471
472
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
473
index XXXXXXX..XXXXXXX 100644
474
--- a/target/rx/cpu.c
475
+++ b/target/rx/cpu.c
476
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_synchronize_from_tb(CPUState *cs,
477
{
478
RXCPU *cpu = RX_CPU(cs);
479
480
- cpu->env.pc = tb->pc;
481
+ cpu->env.pc = tb_pc(tb);
482
}
483
484
static bool rx_cpu_has_work(CPUState *cs)
485
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
486
index XXXXXXX..XXXXXXX 100644
487
--- a/target/sh4/cpu.c
488
+++ b/target/sh4/cpu.c
489
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_synchronize_from_tb(CPUState *cs,
490
{
491
SuperHCPU *cpu = SUPERH_CPU(cs);
492
493
- cpu->env.pc = tb->pc;
494
+ cpu->env.pc = tb_pc(tb);
495
cpu->env.flags = tb->flags & TB_FLAG_ENVFLAGS_MASK;
496
}
497
498
@@ -XXX,XX +XXX,XX @@ static bool superh_io_recompile_replay_branch(CPUState *cs,
499
CPUSH4State *env = &cpu->env;
500
501
if ((env->flags & ((DELAY_SLOT | DELAY_SLOT_CONDITIONAL))) != 0
502
- && env->pc != tb->pc) {
503
+ && env->pc != tb_pc(tb)) {
504
env->pc -= 2;
505
env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
506
return true;
507
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
508
index XXXXXXX..XXXXXXX 100644
509
--- a/target/sparc/cpu.c
510
+++ b/target/sparc/cpu.c
511
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_synchronize_from_tb(CPUState *cs,
512
{
513
SPARCCPU *cpu = SPARC_CPU(cs);
514
515
- cpu->env.pc = tb->pc;
516
+ cpu->env.pc = tb_pc(tb);
517
cpu->env.npc = tb->cs_base;
518
}
519
520
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
521
index XXXXXXX..XXXXXXX 100644
522
--- a/target/tricore/cpu.c
523
+++ b/target/tricore/cpu.c
524
@@ -XXX,XX +XXX,XX @@ static void tricore_cpu_synchronize_from_tb(CPUState *cs,
525
TriCoreCPU *cpu = TRICORE_CPU(cs);
526
CPUTriCoreState *env = &cpu->env;
527
528
- env->PC = tb->pc;
529
+ env->PC = tb_pc(tb);
530
}
531
532
static void tricore_cpu_reset(DeviceState *dev)
533
diff --git a/tcg/tcg.c b/tcg/tcg.c
534
index XXXXXXX..XXXXXXX 100644
535
--- a/tcg/tcg.c
536
+++ b/tcg/tcg.c
537
@@ -XXX,XX +XXX,XX @@ int64_t tcg_cpu_exec_time(void)
538
#endif
539
540
541
-int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
542
+int tcg_gen_code(TCGContext *s, TranslationBlock *tb, target_ulong pc_start)
543
{
544
#ifdef CONFIG_PROFILER
545
TCGProfile *prof = &s->prof;
546
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
547
548
#ifdef DEBUG_DISAS
549
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
550
- && qemu_log_in_addr_range(tb->pc))) {
551
+ && qemu_log_in_addr_range(pc_start))) {
552
FILE *logfile = qemu_log_trylock();
553
if (logfile) {
554
fprintf(logfile, "OP:\n");
555
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
556
if (s->nb_indirects > 0) {
557
#ifdef DEBUG_DISAS
558
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND)
559
- && qemu_log_in_addr_range(tb->pc))) {
560
+ && qemu_log_in_addr_range(pc_start))) {
561
FILE *logfile = qemu_log_trylock();
562
if (logfile) {
563
fprintf(logfile, "OP before indirect lowering:\n");
564
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
565
566
#ifdef DEBUG_DISAS
567
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
568
- && qemu_log_in_addr_range(tb->pc))) {
569
+ && qemu_log_in_addr_range(pc_start))) {
570
FILE *logfile = qemu_log_trylock();
571
if (logfile) {
572
fprintf(logfile, "OP after optimization and liveness analysis:\n");
573
--
39
--
574
2.34.1
40
2.34.1
575
41
576
42
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-21-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/microblaze/cpu.c | 4 +++-
9
1 file changed, 3 insertions(+), 1 deletion(-)
10
11
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/microblaze/cpu.c
14
+++ b/target/microblaze/cpu.c
15
@@ -XXX,XX +XXX,XX @@
16
#include "exec/exec-all.h"
17
#include "exec/gdbstub.h"
18
#include "fpu/softfloat-helpers.h"
19
+#include "tcg/tcg.h"
20
21
static const struct {
22
const char *name;
23
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_synchronize_from_tb(CPUState *cs,
24
{
25
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
26
27
- cpu->env.pc = tb_pc(tb);
28
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
29
+ cpu->env.pc = tb->pc;
30
cpu->env.iflags = tb->flags & IFLAGS_TB_MASK;
31
}
32
33
--
34
2.34.1
35
36
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-22-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/loongarch/cpu.c | 6 ++++--
9
1 file changed, 4 insertions(+), 2 deletions(-)
10
11
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/cpu.c
14
+++ b/target/loongarch/cpu.c
15
@@ -XXX,XX +XXX,XX @@
16
#include "fpu/softfloat-helpers.h"
17
#include "cpu-csr.h"
18
#include "sysemu/reset.h"
19
+#include "tcg/tcg.h"
20
21
const char * const regnames[32] = {
22
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
23
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
24
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
25
CPULoongArchState *env = &cpu->env;
26
27
- env->pc = tb_pc(tb);
28
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
29
+ env->pc = tb->pc;
30
}
31
32
static void loongarch_restore_state_to_opc(CPUState *cs,
33
@@ -XXX,XX +XXX,XX @@ static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model)
34
35
oc = object_class_by_name(cpu_model);
36
if (!oc) {
37
- g_autofree char *typename
38
+ g_autofree char *typename
39
= g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model);
40
oc = object_class_by_name(typename);
41
if (!oc) {
42
--
43
2.34.1
44
45
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-23-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/i386/tcg/tcg-cpu.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/i386/tcg/tcg-cpu.c
14
+++ b/target/i386/tcg/tcg-cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void x86_cpu_synchronize_from_tb(CPUState *cs,
16
/* The instruction pointer is always up to date with CF_PCREL. */
17
if (!(tb_cflags(tb) & CF_PCREL)) {
18
CPUX86State *env = cs->env_ptr;
19
- env->eip = tb_pc(tb) - tb->cs_base;
20
+ env->eip = tb->pc - tb->cs_base;
21
}
22
}
23
24
--
25
2.34.1
26
27
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-24-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/hppa/cpu.c | 8 +++++---
9
1 file changed, 5 insertions(+), 3 deletions(-)
10
11
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/hppa/cpu.c
14
+++ b/target/hppa/cpu.c
15
@@ -XXX,XX +XXX,XX @@
16
#include "qemu/module.h"
17
#include "exec/exec-all.h"
18
#include "fpu/softfloat.h"
19
-
20
+#include "tcg/tcg.h"
21
22
static void hppa_cpu_set_pc(CPUState *cs, vaddr value)
23
{
24
@@ -XXX,XX +XXX,XX @@ static void hppa_cpu_synchronize_from_tb(CPUState *cs,
25
{
26
HPPACPU *cpu = HPPA_CPU(cs);
27
28
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
29
+
30
#ifdef CONFIG_USER_ONLY
31
- cpu->env.iaoq_f = tb_pc(tb);
32
+ cpu->env.iaoq_f = tb->pc;
33
cpu->env.iaoq_b = tb->cs_base;
34
#else
35
/* Recover the IAOQ values from the GVA + PRIV. */
36
@@ -XXX,XX +XXX,XX @@ static void hppa_cpu_synchronize_from_tb(CPUState *cs,
37
int32_t diff = cs_base;
38
39
cpu->env.iasq_f = iasq_f;
40
- cpu->env.iaoq_f = (tb_pc(tb) & ~iasq_f) + priv;
41
+ cpu->env.iaoq_f = (tb->pc & ~iasq_f) + priv;
42
if (diff) {
43
cpu->env.iaoq_b = cpu->env.iaoq_f + diff;
44
}
45
--
46
2.34.1
47
48
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
6
Message-Id: <20230227135202.9710-25-anjo@rev.ng>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
target/hexagon/cpu.c | 4 +++-
10
1 file changed, 3 insertions(+), 1 deletion(-)
11
12
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/hexagon/cpu.c
15
+++ b/target/hexagon/cpu.c
16
@@ -XXX,XX +XXX,XX @@
17
#include "qapi/error.h"
18
#include "hw/qdev-properties.h"
19
#include "fpu/softfloat-helpers.h"
20
+#include "tcg/tcg.h"
21
22
static void hexagon_v67_cpu_init(Object *obj)
23
{
24
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_synchronize_from_tb(CPUState *cs,
25
{
26
HexagonCPU *cpu = HEXAGON_CPU(cs);
27
CPUHexagonState *env = &cpu->env;
28
- env->gpr[HEX_REG_PC] = tb_pc(tb);
29
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
30
+ env->gpr[HEX_REG_PC] = tb->pc;
31
}
32
33
static bool hexagon_cpu_has_work(CPUState *cs)
34
--
35
2.34.1
36
37
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-26-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/avr/cpu.c | 3 ++-
9
1 file changed, 2 insertions(+), 1 deletion(-)
10
11
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/avr/cpu.c
14
+++ b/target/avr/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void avr_cpu_synchronize_from_tb(CPUState *cs,
16
AVRCPU *cpu = AVR_CPU(cs);
17
CPUAVRState *env = &cpu->env;
18
19
- env->pc_w = tb_pc(tb) / 2; /* internally PC points to words */
20
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
21
+ env->pc_w = tb->pc / 2; /* internally PC points to words */
22
}
23
24
static void avr_restore_state_to_opc(CPUState *cs,
25
--
26
2.34.1
27
28
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Anton Johansson via <qemu-devel@nongnu.org>
2
2
3
The class cast checkers are quite expensive and always on (unlike the
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
dynamic case who's checks are gated by CONFIG_QOM_CAST_DEBUG). To
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
avoid the overhead of repeatedly checking something which should never
5
Message-Id: <20230227135202.9710-27-anjo@rev.ng>
6
change we cache the CPUClass reference for use in the hot code paths.
7
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-Id: <20220811151413.3350684-3-alex.bennee@linaro.org>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-Id: <20220923084803.498337-3-clg@kaod.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
---
7
---
15
include/hw/core/cpu.h | 9 +++++++++
8
target/arm/cpu.c | 4 ++--
16
cpu.c | 9 ++++-----
9
1 file changed, 2 insertions(+), 2 deletions(-)
17
2 files changed, 13 insertions(+), 5 deletions(-)
18
10
19
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
11
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/core/cpu.h
13
--- a/target/arm/cpu.c
22
+++ b/include/hw/core/cpu.h
14
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
15
@@ -XXX,XX +XXX,XX @@ void arm_cpu_synchronize_from_tb(CPUState *cs,
24
*/
16
* never possible for an AArch64 TB to chain to an AArch32 TB.
25
#define CPU(obj) ((CPUState *)(obj))
17
*/
26
18
if (is_a64(env)) {
27
+/*
19
- env->pc = tb_pc(tb);
28
+ * The class checkers bring in CPU_GET_CLASS() which is potentially
20
+ env->pc = tb->pc;
29
+ * expensive given the eventual call to
21
} else {
30
+ * object_class_dynamic_cast_assert(). Because of this the CPUState
22
- env->regs[15] = tb_pc(tb);
31
+ * has a cached value for the class in cs->cc which is set up in
23
+ env->regs[15] = tb->pc;
32
+ * cpu_exec_realizefn() for use in hot code paths.
24
}
33
+ */
34
typedef struct CPUClass CPUClass;
35
DECLARE_CLASS_CHECKERS(CPUClass, CPU,
36
TYPE_CPU)
37
@@ -XXX,XX +XXX,XX @@ struct qemu_work_item;
38
struct CPUState {
39
/*< private >*/
40
DeviceState parent_obj;
41
+ /* cache to avoid expensive CPU_GET_CLASS */
42
+ CPUClass *cc;
43
/*< public >*/
44
45
int nr_cores;
46
diff --git a/cpu.c b/cpu.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/cpu.c
49
+++ b/cpu.c
50
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_cpu_common = {
51
52
void cpu_exec_realizefn(CPUState *cpu, Error **errp)
53
{
54
-#ifndef CONFIG_USER_ONLY
55
- CPUClass *cc = CPU_GET_CLASS(cpu);
56
-#endif
57
+ /* cache the cpu class for the hotpath */
58
+ cpu->cc = CPU_GET_CLASS(cpu);
59
60
cpu_list_add(cpu);
61
if (!accel_cpu_realizefn(cpu, errp)) {
62
@@ -XXX,XX +XXX,XX @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
63
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
64
vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
65
}
25
}
66
- if (cc->sysemu_ops->legacy_vmsd != NULL) {
67
- vmstate_register(NULL, cpu->cpu_index, cc->sysemu_ops->legacy_vmsd, cpu);
68
+ if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) {
69
+ vmstate_register(NULL, cpu->cpu_index, cpu->cc->sysemu_ops->legacy_vmsd, cpu);
70
}
71
#endif /* CONFIG_USER_ONLY */
72
}
26
}
73
--
27
--
74
2.34.1
28
2.34.1
75
29
76
30
diff view generated by jsdifflib
New patch
1
From: Anton Johansson via <qemu-devel@nongnu.org>
1
2
3
Signed-off-by: Anton Johansson <anjo@rev.ng>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-Id: <20230227135202.9710-28-anjo@rev.ng>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
include/exec/exec-all.h | 7 -------
9
1 file changed, 7 deletions(-)
10
11
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/exec/exec-all.h
14
+++ b/include/exec/exec-all.h
15
@@ -XXX,XX +XXX,XX @@ static inline uint32_t tb_cflags(const TranslationBlock *tb)
16
return qatomic_read(&tb->cflags);
17
}
18
19
-/* Hide the read to avoid ifdefs for CF_PCREL. */
20
-static inline target_ulong tb_pc(const TranslationBlock *tb)
21
-{
22
- assert(!(tb_cflags(tb) & CF_PCREL));
23
- return tb->pc;
24
-}
25
-
26
static inline tb_page_addr_t tb_page_addr0(const TranslationBlock *tb)
27
{
28
#ifdef CONFIG_USER_ONLY
29
--
30
2.34.1
31
32
diff view generated by jsdifflib
New patch
1
Change the temps_in_use check to use assert not fprintf.
2
Move the assert for double-free before the check for count,
3
since that is the more immediate problem.
1
4
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
tcg/tcg.c | 12 +++++-------
9
1 file changed, 5 insertions(+), 7 deletions(-)
10
11
diff --git a/tcg/tcg.c b/tcg/tcg.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/tcg.c
14
+++ b/tcg/tcg.c
15
@@ -XXX,XX +XXX,XX @@ void tcg_temp_free_internal(TCGTemp *ts)
16
g_assert_not_reached();
17
}
18
19
-#if defined(CONFIG_DEBUG_TCG)
20
- s->temps_in_use--;
21
- if (s->temps_in_use < 0) {
22
- fprintf(stderr, "More temporaries freed than allocated!\n");
23
- }
24
-#endif
25
-
26
tcg_debug_assert(ts->temp_allocated != 0);
27
ts->temp_allocated = 0;
28
29
+#if defined(CONFIG_DEBUG_TCG)
30
+ assert(s->temps_in_use > 0);
31
+ s->temps_in_use--;
32
+#endif
33
+
34
idx = temp_idx(ts);
35
k = ts->base_type + (ts->kind == TEMP_NORMAL ? 0 : TCG_TYPE_COUNT);
36
set_bit(idx, s->free_temps[k].l);
37
--
38
2.34.1
39
40
diff view generated by jsdifflib
1
Bool is more appropriate type for the alloc parameter.
1
In preparation for returning the number of insns generated
2
via the same pointer. Adjust only the prototypes so far.
2
3
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
6
---
7
accel/tcg/translate-all.c | 14 +++++++-------
7
include/exec/translator.h | 4 ++--
8
1 file changed, 7 insertions(+), 7 deletions(-)
8
accel/tcg/translate-all.c | 2 +-
9
accel/tcg/translator.c | 4 ++--
10
target/alpha/translate.c | 2 +-
11
target/arm/tcg/translate.c | 2 +-
12
target/avr/translate.c | 2 +-
13
target/cris/translate.c | 2 +-
14
target/hexagon/translate.c | 2 +-
15
target/hppa/translate.c | 2 +-
16
target/i386/tcg/translate.c | 2 +-
17
target/loongarch/translate.c | 2 +-
18
target/m68k/translate.c | 2 +-
19
target/microblaze/translate.c | 2 +-
20
target/mips/tcg/translate.c | 2 +-
21
target/nios2/translate.c | 2 +-
22
target/openrisc/translate.c | 2 +-
23
target/ppc/translate.c | 2 +-
24
target/riscv/translate.c | 2 +-
25
target/rx/translate.c | 2 +-
26
target/s390x/tcg/translate.c | 2 +-
27
target/sh4/translate.c | 2 +-
28
target/sparc/translate.c | 2 +-
29
target/tricore/translate.c | 2 +-
30
target/xtensa/translate.c | 2 +-
31
24 files changed, 26 insertions(+), 26 deletions(-)
9
32
33
diff --git a/include/exec/translator.h b/include/exec/translator.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/exec/translator.h
36
+++ b/include/exec/translator.h
37
@@ -XXX,XX +XXX,XX @@
38
* This function must be provided by the target, which should create
39
* the target-specific DisasContext, and then invoke translator_loop.
40
*/
41
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
42
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
43
target_ulong pc, void *host_pc);
44
45
/**
46
@@ -XXX,XX +XXX,XX @@ typedef struct TranslatorOps {
47
* - When single-stepping is enabled (system-wide or on the current vCPU).
48
* - When too many instructions have been translated.
49
*/
50
-void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
51
+void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
52
target_ulong pc, void *host_pc,
53
const TranslatorOps *ops, DisasContextBase *db);
54
10
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
55
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
11
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
12
--- a/accel/tcg/translate-all.c
57
--- a/accel/tcg/translate-all.c
13
+++ b/accel/tcg/translate-all.c
58
+++ b/accel/tcg/translate-all.c
14
@@ -XXX,XX +XXX,XX @@ void page_init(void)
59
@@ -XXX,XX +XXX,XX @@ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
15
#endif
60
tcg_func_start(tcg_ctx);
61
62
tcg_ctx->cpu = env_cpu(env);
63
- gen_intermediate_code(env_cpu(env), tb, *max_insns, pc, host_pc);
64
+ gen_intermediate_code(env_cpu(env), tb, max_insns, pc, host_pc);
65
assert(tb->size != 0);
66
tcg_ctx->cpu = NULL;
67
*max_insns = tb->icount;
68
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/accel/tcg/translator.c
71
+++ b/accel/tcg/translator.c
72
@@ -XXX,XX +XXX,XX @@ bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest)
73
return ((db->pc_first ^ dest) & TARGET_PAGE_MASK) == 0;
16
}
74
}
17
75
18
-static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
76
-void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
19
+static PageDesc *page_find_alloc(tb_page_addr_t index, bool alloc)
77
+void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
20
{
78
target_ulong pc, void *host_pc,
21
PageDesc *pd;
79
const TranslatorOps *ops, DisasContextBase *db)
22
void **lp;
80
{
23
@@ -XXX,XX +XXX,XX @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
81
@@ -XXX,XX +XXX,XX @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
24
82
db->pc_next = pc;
25
static inline PageDesc *page_find(tb_page_addr_t index)
83
db->is_jmp = DISAS_NEXT;
26
{
84
db->num_insns = 0;
27
- return page_find_alloc(index, 0);
85
- db->max_insns = max_insns;
28
+ return page_find_alloc(index, false);
86
+ db->max_insns = *max_insns;
29
}
87
db->singlestep_enabled = cflags & CF_SINGLE_STEP;
30
88
db->host_addr[0] = host_pc;
31
static void page_lock_pair(PageDesc **ret_p1, tb_page_addr_t phys1,
89
db->host_addr[1] = NULL;
32
- PageDesc **ret_p2, tb_page_addr_t phys2, int alloc);
90
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
33
+ PageDesc **ret_p2, tb_page_addr_t phys2, bool alloc);
91
index XXXXXXX..XXXXXXX 100644
34
92
--- a/target/alpha/translate.c
35
/* In user-mode page locks aren't used; mmap_lock is enough */
93
+++ b/target/alpha/translate.c
36
#ifdef CONFIG_USER_ONLY
94
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps alpha_tr_ops = {
37
@@ -XXX,XX +XXX,XX @@ static inline void page_unlock(PageDesc *pd)
95
.disas_log = alpha_tr_disas_log,
38
/* lock the page(s) of a TB in the correct acquisition order */
96
};
39
static inline void page_lock_tb(const TranslationBlock *tb)
97
40
{
98
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
41
- page_lock_pair(NULL, tb->page_addr[0], NULL, tb->page_addr[1], 0);
99
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
42
+ page_lock_pair(NULL, tb->page_addr[0], NULL, tb->page_addr[1], false);
100
target_ulong pc, void *host_pc)
43
}
101
{
44
102
DisasContext dc;
45
static inline void page_unlock_tb(const TranslationBlock *tb)
103
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
46
@@ -XXX,XX +XXX,XX @@ void page_collection_unlock(struct page_collection *set)
104
index XXXXXXX..XXXXXXX 100644
47
#endif /* !CONFIG_USER_ONLY */
105
--- a/target/arm/tcg/translate.c
48
106
+++ b/target/arm/tcg/translate.c
49
static void page_lock_pair(PageDesc **ret_p1, tb_page_addr_t phys1,
107
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps thumb_translator_ops = {
50
- PageDesc **ret_p2, tb_page_addr_t phys2, int alloc)
108
};
51
+ PageDesc **ret_p2, tb_page_addr_t phys2, bool alloc)
109
52
{
110
/* generate intermediate code for basic block 'tb'. */
53
PageDesc *p1, *p2;
111
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
54
tb_page_addr_t page1;
112
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
55
@@ -XXX,XX +XXX,XX @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
113
target_ulong pc, void *host_pc)
56
* Note that inserting into the hash table first isn't an option, since
114
{
57
* we can only insert TBs that are fully initialized.
115
DisasContext dc = { };
58
*/
116
diff --git a/target/avr/translate.c b/target/avr/translate.c
59
- page_lock_pair(&p, phys_pc, &p2, phys_page2, 1);
117
index XXXXXXX..XXXXXXX 100644
60
+ page_lock_pair(&p, phys_pc, &p2, phys_page2, true);
118
--- a/target/avr/translate.c
61
tb_page_add(p, tb, 0, phys_pc & TARGET_PAGE_MASK);
119
+++ b/target/avr/translate.c
62
if (p2) {
120
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps avr_tr_ops = {
63
tb_page_add(p2, tb, 1, phys_page2);
121
.disas_log = avr_tr_disas_log,
64
@@ -XXX,XX +XXX,XX @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
122
};
65
for (addr = start, len = end - start;
123
66
len != 0;
124
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
67
len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
125
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
68
- PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
126
target_ulong pc, void *host_pc)
69
+ PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, true);
127
{
70
128
DisasContext dc = { };
71
/* If the write protection bit is set, then we invalidate
129
diff --git a/target/cris/translate.c b/target/cris/translate.c
72
the code inside. */
130
index XXXXXXX..XXXXXXX 100644
131
--- a/target/cris/translate.c
132
+++ b/target/cris/translate.c
133
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps cris_tr_ops = {
134
.disas_log = cris_tr_disas_log,
135
};
136
137
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
138
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
139
target_ulong pc, void *host_pc)
140
{
141
DisasContext dc;
142
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/target/hexagon/translate.c
145
+++ b/target/hexagon/translate.c
146
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hexagon_tr_ops = {
147
.disas_log = hexagon_tr_disas_log,
148
};
149
150
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
151
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
152
target_ulong pc, void *host_pc)
153
{
154
DisasContext ctx;
155
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/hppa/translate.c
158
+++ b/target/hppa/translate.c
159
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hppa_tr_ops = {
160
.disas_log = hppa_tr_disas_log,
161
};
162
163
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
164
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
165
target_ulong pc, void *host_pc)
166
{
167
DisasContext ctx;
168
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/target/i386/tcg/translate.c
171
+++ b/target/i386/tcg/translate.c
172
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps i386_tr_ops = {
173
};
174
175
/* generate intermediate code for basic block 'tb'. */
176
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
177
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
178
target_ulong pc, void *host_pc)
179
{
180
DisasContext dc;
181
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/loongarch/translate.c
184
+++ b/target/loongarch/translate.c
185
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps loongarch_tr_ops = {
186
.disas_log = loongarch_tr_disas_log,
187
};
188
189
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
190
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
191
target_ulong pc, void *host_pc)
192
{
193
DisasContext ctx;
194
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
195
index XXXXXXX..XXXXXXX 100644
196
--- a/target/m68k/translate.c
197
+++ b/target/m68k/translate.c
198
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps m68k_tr_ops = {
199
.disas_log = m68k_tr_disas_log,
200
};
201
202
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
203
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
204
target_ulong pc, void *host_pc)
205
{
206
DisasContext dc;
207
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
208
index XXXXXXX..XXXXXXX 100644
209
--- a/target/microblaze/translate.c
210
+++ b/target/microblaze/translate.c
211
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mb_tr_ops = {
212
.disas_log = mb_tr_disas_log,
213
};
214
215
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
216
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
217
target_ulong pc, void *host_pc)
218
{
219
DisasContext dc;
220
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
221
index XXXXXXX..XXXXXXX 100644
222
--- a/target/mips/tcg/translate.c
223
+++ b/target/mips/tcg/translate.c
224
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mips_tr_ops = {
225
.disas_log = mips_tr_disas_log,
226
};
227
228
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
229
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
230
target_ulong pc, void *host_pc)
231
{
232
DisasContext ctx;
233
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
234
index XXXXXXX..XXXXXXX 100644
235
--- a/target/nios2/translate.c
236
+++ b/target/nios2/translate.c
237
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps nios2_tr_ops = {
238
.disas_log = nios2_tr_disas_log,
239
};
240
241
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
242
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
243
target_ulong pc, void *host_pc)
244
{
245
DisasContext dc;
246
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/target/openrisc/translate.c
249
+++ b/target/openrisc/translate.c
250
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps openrisc_tr_ops = {
251
.disas_log = openrisc_tr_disas_log,
252
};
253
254
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
255
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
256
target_ulong pc, void *host_pc)
257
{
258
DisasContext ctx;
259
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
260
index XXXXXXX..XXXXXXX 100644
261
--- a/target/ppc/translate.c
262
+++ b/target/ppc/translate.c
263
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps ppc_tr_ops = {
264
.disas_log = ppc_tr_disas_log,
265
};
266
267
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
268
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
269
target_ulong pc, void *host_pc)
270
{
271
DisasContext ctx;
272
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
273
index XXXXXXX..XXXXXXX 100644
274
--- a/target/riscv/translate.c
275
+++ b/target/riscv/translate.c
276
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps riscv_tr_ops = {
277
.disas_log = riscv_tr_disas_log,
278
};
279
280
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
281
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
282
target_ulong pc, void *host_pc)
283
{
284
DisasContext ctx;
285
diff --git a/target/rx/translate.c b/target/rx/translate.c
286
index XXXXXXX..XXXXXXX 100644
287
--- a/target/rx/translate.c
288
+++ b/target/rx/translate.c
289
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps rx_tr_ops = {
290
.disas_log = rx_tr_disas_log,
291
};
292
293
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
294
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
295
target_ulong pc, void *host_pc)
296
{
297
DisasContext dc;
298
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
299
index XXXXXXX..XXXXXXX 100644
300
--- a/target/s390x/tcg/translate.c
301
+++ b/target/s390x/tcg/translate.c
302
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps s390x_tr_ops = {
303
.disas_log = s390x_tr_disas_log,
304
};
305
306
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
307
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
308
target_ulong pc, void *host_pc)
309
{
310
DisasContext dc;
311
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
312
index XXXXXXX..XXXXXXX 100644
313
--- a/target/sh4/translate.c
314
+++ b/target/sh4/translate.c
315
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sh4_tr_ops = {
316
.disas_log = sh4_tr_disas_log,
317
};
318
319
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
320
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
321
target_ulong pc, void *host_pc)
322
{
323
DisasContext ctx;
324
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
325
index XXXXXXX..XXXXXXX 100644
326
--- a/target/sparc/translate.c
327
+++ b/target/sparc/translate.c
328
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sparc_tr_ops = {
329
.disas_log = sparc_tr_disas_log,
330
};
331
332
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
333
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
334
target_ulong pc, void *host_pc)
335
{
336
DisasContext dc = {};
337
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
338
index XXXXXXX..XXXXXXX 100644
339
--- a/target/tricore/translate.c
340
+++ b/target/tricore/translate.c
341
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps tricore_tr_ops = {
342
};
343
344
345
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
346
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
347
target_ulong pc, void *host_pc)
348
{
349
DisasContext ctx;
350
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
351
index XXXXXXX..XXXXXXX 100644
352
--- a/target/xtensa/translate.c
353
+++ b/target/xtensa/translate.c
354
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps xtensa_translator_ops = {
355
.disas_log = xtensa_tr_disas_log,
356
};
357
358
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
359
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
360
target_ulong pc, void *host_pc)
361
{
362
DisasContext dc = {};
73
--
363
--
74
2.34.1
364
2.34.1
75
365
76
366
diff view generated by jsdifflib
New patch
1
Write back the number of insns that we attempt to translate,
2
so that if we longjmp out we have a more accurate limit for
3
the next attempt. This results in fewer restarts when some
4
limit is consumed by few instructions.
1
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
accel/tcg/translator.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/accel/tcg/translator.c
15
+++ b/accel/tcg/translator.c
16
@@ -XXX,XX +XXX,XX @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
17
plugin_enabled = plugin_gen_tb_start(cpu, db, cflags & CF_MEMI_ONLY);
18
19
while (true) {
20
- db->num_insns++;
21
+ *max_insns = ++db->num_insns;
22
ops->insn_start(db, cpu);
23
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
24
25
--
26
2.34.1
27
28
diff view generated by jsdifflib
New patch
1
Just because the label reference count is more than 1 does
2
not mean we cannot remove a branch-to-next. By doing this
3
first, the label reference count may drop to 0, and then
4
the label itself gets removed as before.
1
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
tcg/tcg.c | 33 +++++++++++++++++----------------
10
1 file changed, 17 insertions(+), 16 deletions(-)
11
12
diff --git a/tcg/tcg.c b/tcg/tcg.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/tcg.c
15
+++ b/tcg/tcg.c
16
@@ -XXX,XX +XXX,XX @@ TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op,
17
/* Reachable analysis : remove unreachable code. */
18
static void reachable_code_pass(TCGContext *s)
19
{
20
- TCGOp *op, *op_next;
21
+ TCGOp *op, *op_next, *op_prev;
22
bool dead = false;
23
24
QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
25
@@ -XXX,XX +XXX,XX @@ static void reachable_code_pass(TCGContext *s)
26
switch (op->opc) {
27
case INDEX_op_set_label:
28
label = arg_label(op->args[0]);
29
+
30
+ /*
31
+ * Optimization can fold conditional branches to unconditional.
32
+ * If we find a label which is preceded by an unconditional
33
+ * branch to next, remove the branch. We couldn't do this when
34
+ * processing the branch because any dead code between the branch
35
+ * and label had not yet been removed.
36
+ */
37
+ op_prev = QTAILQ_PREV(op, link);
38
+ if (op_prev->opc == INDEX_op_br &&
39
+ label == arg_label(op_prev->args[0])) {
40
+ tcg_op_remove(s, op_prev);
41
+ /* Fall through means insns become live again. */
42
+ dead = false;
43
+ }
44
+
45
if (label->refs == 0) {
46
/*
47
* While there is an occasional backward branch, virtually
48
@@ -XXX,XX +XXX,XX @@ static void reachable_code_pass(TCGContext *s)
49
/* Once we see a label, insns become live again. */
50
dead = false;
51
remove = false;
52
-
53
- /*
54
- * Optimization can fold conditional branches to unconditional.
55
- * If we find a label with one reference which is preceded by
56
- * an unconditional branch to it, remove both. This needed to
57
- * wait until the dead code in between them was removed.
58
- */
59
- if (label->refs == 1) {
60
- TCGOp *op_prev = QTAILQ_PREV(op, link);
61
- if (op_prev->opc == INDEX_op_br &&
62
- label == arg_label(op_prev->args[0])) {
63
- tcg_op_remove(s, op_prev);
64
- remove = true;
65
- }
66
- }
67
}
68
break;
69
70
--
71
2.34.1
72
73
diff view generated by jsdifflib
New patch
1
Use TEMP_TB as that is more explicit about the default
2
lifetime of the data. While "global" and "local" used
3
to be contrasting, we have more lifetimes than that now.
1
4
5
Do not yet rename tcg_temp_local_new_*, just the enum.
6
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
include/tcg/tcg.h | 12 ++++++++----
11
tcg/optimize.c | 2 +-
12
tcg/tcg.c | 18 +++++++++---------
13
3 files changed, 18 insertions(+), 14 deletions(-)
14
15
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/tcg/tcg.h
18
+++ b/include/tcg/tcg.h
19
@@ -XXX,XX +XXX,XX @@ typedef enum TCGTempVal {
20
typedef enum TCGTempKind {
21
/* Temp is dead at the end of all basic blocks. */
22
TEMP_NORMAL,
23
- /* Temp is live across conditional branch, but dead otherwise. */
24
+ /*
25
+ * Temp is dead at the end of the extended basic block (EBB),
26
+ * the single-entry multiple-exit region that falls through
27
+ * conditional branches.
28
+ */
29
TEMP_EBB,
30
- /* Temp is saved across basic blocks but dead at the end of TBs. */
31
- TEMP_LOCAL,
32
- /* Temp is saved across both basic blocks and translation blocks. */
33
+ /* Temp is live across the entire translation block, but dead at end. */
34
+ TEMP_TB,
35
+ /* Temp is live across the entire translation block, and between them. */
36
TEMP_GLOBAL,
37
/* Temp is in a fixed register. */
38
TEMP_FIXED,
39
diff --git a/tcg/optimize.c b/tcg/optimize.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/tcg/optimize.c
42
+++ b/tcg/optimize.c
43
@@ -XXX,XX +XXX,XX @@ static TCGTemp *find_better_copy(TCGContext *s, TCGTemp *ts)
44
} else if (i->kind > ts->kind) {
45
if (i->kind == TEMP_GLOBAL) {
46
g = i;
47
- } else if (i->kind == TEMP_LOCAL) {
48
+ } else if (i->kind == TEMP_TB) {
49
l = i;
50
}
51
}
52
diff --git a/tcg/tcg.c b/tcg/tcg.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/tcg/tcg.c
55
+++ b/tcg/tcg.c
56
@@ -XXX,XX +XXX,XX @@ TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
57
TCGTemp *tcg_temp_new_internal(TCGType type, bool temp_local)
58
{
59
TCGContext *s = tcg_ctx;
60
- TCGTempKind kind = temp_local ? TEMP_LOCAL : TEMP_NORMAL;
61
+ TCGTempKind kind = temp_local ? TEMP_TB : TEMP_NORMAL;
62
TCGTemp *ts;
63
int idx, k;
64
65
@@ -XXX,XX +XXX,XX @@ void tcg_temp_free_internal(TCGTemp *ts)
66
*/
67
return;
68
case TEMP_NORMAL:
69
- case TEMP_LOCAL:
70
+ case TEMP_TB:
71
break;
72
default:
73
g_assert_not_reached();
74
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_start(TCGContext *s)
75
case TEMP_EBB:
76
val = TEMP_VAL_DEAD;
77
/* fall through */
78
- case TEMP_LOCAL:
79
+ case TEMP_TB:
80
ts->mem_allocated = 0;
81
break;
82
default:
83
@@ -XXX,XX +XXX,XX @@ static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
84
case TEMP_GLOBAL:
85
pstrcpy(buf, buf_size, ts->name);
86
break;
87
- case TEMP_LOCAL:
88
+ case TEMP_TB:
89
snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
90
break;
91
case TEMP_EBB:
92
@@ -XXX,XX +XXX,XX @@ static void la_bb_end(TCGContext *s, int ng, int nt)
93
switch (ts->kind) {
94
case TEMP_FIXED:
95
case TEMP_GLOBAL:
96
- case TEMP_LOCAL:
97
+ case TEMP_TB:
98
state = TS_DEAD | TS_MEM;
99
break;
100
case TEMP_NORMAL:
101
@@ -XXX,XX +XXX,XX @@ static void la_bb_sync(TCGContext *s, int ng, int nt)
102
int state;
103
104
switch (ts->kind) {
105
- case TEMP_LOCAL:
106
+ case TEMP_TB:
107
state = ts->state;
108
ts->state = state | TS_MEM;
109
if (state != TS_DEAD) {
110
@@ -XXX,XX +XXX,XX @@ static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
111
case TEMP_FIXED:
112
return;
113
case TEMP_GLOBAL:
114
- case TEMP_LOCAL:
115
+ case TEMP_TB:
116
new_type = TEMP_VAL_MEM;
117
break;
118
case TEMP_NORMAL:
119
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
120
TCGTemp *ts = &s->temps[i];
121
122
switch (ts->kind) {
123
- case TEMP_LOCAL:
124
+ case TEMP_TB:
125
temp_save(s, ts, allocated_regs);
126
break;
127
case TEMP_NORMAL:
128
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_cbranch(TCGContext *s, TCGRegSet allocated_regs)
129
* Keep tcg_debug_asserts for safety.
130
*/
131
switch (ts->kind) {
132
- case TEMP_LOCAL:
133
+ case TEMP_TB:
134
tcg_debug_assert(ts->val_type != TEMP_VAL_REG || ts->mem_coherent);
135
break;
136
case TEMP_NORMAL:
137
--
138
2.34.1
139
140
diff view generated by jsdifflib
New patch
1
This makes it easier to assign blame with perf.
1
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/tcg.c | 9 ++++++---
8
1 file changed, 6 insertions(+), 3 deletions(-)
9
10
diff --git a/tcg/tcg.c b/tcg/tcg.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/tcg.c
13
+++ b/tcg/tcg.c
14
@@ -XXX,XX +XXX,XX @@ TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *old_op,
15
}
16
17
/* Reachable analysis : remove unreachable code. */
18
-static void reachable_code_pass(TCGContext *s)
19
+static void __attribute__((noinline))
20
+reachable_code_pass(TCGContext *s)
21
{
22
TCGOp *op, *op_next, *op_prev;
23
bool dead = false;
24
@@ -XXX,XX +XXX,XX @@ static void la_cross_call(TCGContext *s, int nt)
25
/* Liveness analysis : update the opc_arg_life array to tell if a
26
given input arguments is dead. Instructions updating dead
27
temporaries are removed. */
28
-static void liveness_pass_1(TCGContext *s)
29
+static void __attribute__((noinline))
30
+liveness_pass_1(TCGContext *s)
31
{
32
int nb_globals = s->nb_globals;
33
int nb_temps = s->nb_temps;
34
@@ -XXX,XX +XXX,XX @@ static void liveness_pass_1(TCGContext *s)
35
}
36
37
/* Liveness analysis: Convert indirect regs to direct temporaries. */
38
-static bool liveness_pass_2(TCGContext *s)
39
+static bool __attribute__((noinline))
40
+liveness_pass_2(TCGContext *s)
41
{
42
int nb_globals = s->nb_globals;
43
int nb_temps, i;
44
--
45
2.34.1
46
47
diff view generated by jsdifflib
1
From: Leandro Lupori <leandro.lupori@eldorado.org.br>
1
Attempt to reduce the lifetime of TEMP_TB.
2
2
3
PowerPC64 processors handle direct branches better than indirect
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
ones, resulting in less stalled cycles and branch misses.
5
6
However, PPC's tb_target_set_jmp_target() was only using direct
7
branches for 16-bit jumps, while PowerPC64's unconditional branch
8
instructions are able to handle displacements of up to 26 bits.
9
To take advantage of this, now jumps whose displacements fit in
10
between 17 and 26 bits are also converted to direct branches.
11
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Leandro Lupori <leandro.lupori@eldorado.org.br>
14
[rth: Expanded some commentary.]
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
---
5
---
17
tcg/ppc/tcg-target.c.inc | 119 +++++++++++++++++++++++++++++----------
6
tcg/tcg.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
18
1 file changed, 88 insertions(+), 31 deletions(-)
7
1 file changed, 70 insertions(+)
19
8
20
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
9
diff --git a/tcg/tcg.c b/tcg/tcg.c
21
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/ppc/tcg-target.c.inc
11
--- a/tcg/tcg.c
23
+++ b/tcg/ppc/tcg-target.c.inc
12
+++ b/tcg/tcg.c
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
13
@@ -XXX,XX +XXX,XX @@ static void la_cross_call(TCGContext *s, int nt)
25
tcg_out32(s, insn);
14
}
26
}
15
}
27
16
28
+static inline uint64_t make_pair(tcg_insn_unit i1, tcg_insn_unit i2)
17
+/*
18
+ * Liveness analysis: Verify the lifetime of TEMP_TB, and reduce
19
+ * to TEMP_EBB, if possible.
20
+ */
21
+static void __attribute__((noinline))
22
+liveness_pass_0(TCGContext *s)
29
+{
23
+{
30
+ if (HOST_BIG_ENDIAN) {
24
+ void * const multiple_ebb = (void *)(uintptr_t)-1;
31
+ return (uint64_t)i1 << 32 | i2;
25
+ int nb_temps = s->nb_temps;
32
+ }
26
+ TCGOp *op, *ebb;
33
+ return (uint64_t)i2 << 32 | i1;
34
+}
35
+
27
+
36
+static inline void ppc64_replace2(uintptr_t rx, uintptr_t rw,
28
+ for (int i = s->nb_globals; i < nb_temps; ++i) {
37
+ tcg_insn_unit i0, tcg_insn_unit i1)
29
+ s->temps[i].state_ptr = NULL;
38
+{
39
+#if TCG_TARGET_REG_BITS == 64
40
+ qatomic_set((uint64_t *)rw, make_pair(i0, i1));
41
+ flush_idcache_range(rx, rw, 8);
42
+#else
43
+ qemu_build_not_reached();
44
+#endif
45
+}
46
+
47
+static inline void ppc64_replace4(uintptr_t rx, uintptr_t rw,
48
+ tcg_insn_unit i0, tcg_insn_unit i1,
49
+ tcg_insn_unit i2, tcg_insn_unit i3)
50
+{
51
+ uint64_t p[2];
52
+
53
+ p[!HOST_BIG_ENDIAN] = make_pair(i0, i1);
54
+ p[HOST_BIG_ENDIAN] = make_pair(i2, i3);
55
+
56
+ /*
57
+ * There's no convenient way to get the compiler to allocate a pair
58
+ * of registers at an even index, so copy into r6/r7 and clobber.
59
+ */
60
+ asm("mr %%r6, %1\n\t"
61
+ "mr %%r7, %2\n\t"
62
+ "stq %%r6, %0"
63
+ : "=Q"(*(__int128 *)rw) : "r"(p[0]), "r"(p[1]) : "r6", "r7");
64
+ flush_idcache_range(rx, rw, 16);
65
+}
66
+
67
void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
68
uintptr_t jmp_rw, uintptr_t addr)
69
{
70
- if (TCG_TARGET_REG_BITS == 64) {
71
- tcg_insn_unit i1, i2;
72
- intptr_t tb_diff = addr - tc_ptr;
73
- intptr_t br_diff = addr - (jmp_rx + 4);
74
- uint64_t pair;
75
+ tcg_insn_unit i0, i1, i2, i3;
76
+ intptr_t tb_diff = addr - tc_ptr;
77
+ intptr_t br_diff = addr - (jmp_rx + 4);
78
+ intptr_t lo, hi;
79
80
- /* This does not exercise the range of the branch, but we do
81
- still need to be able to load the new value of TCG_REG_TB.
82
- But this does still happen quite often. */
83
- if (tb_diff == (int16_t)tb_diff) {
84
- i1 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, tb_diff);
85
- i2 = B | (br_diff & 0x3fffffc);
86
- } else {
87
- intptr_t lo = (int16_t)tb_diff;
88
- intptr_t hi = (int32_t)(tb_diff - lo);
89
- assert(tb_diff == hi + lo);
90
- i1 = ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, hi >> 16);
91
- i2 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, lo);
92
- }
93
-#if HOST_BIG_ENDIAN
94
- pair = (uint64_t)i1 << 32 | i2;
95
-#else
96
- pair = (uint64_t)i2 << 32 | i1;
97
-#endif
98
-
99
- /* As per the enclosing if, this is ppc64. Avoid the _Static_assert
100
- within qatomic_set that would fail to build a ppc32 host. */
101
- qatomic_set__nocheck((uint64_t *)jmp_rw, pair);
102
- flush_idcache_range(jmp_rx, jmp_rw, 8);
103
- } else {
104
+ if (TCG_TARGET_REG_BITS == 32) {
105
intptr_t diff = addr - jmp_rx;
106
tcg_debug_assert(in_range_b(diff));
107
qatomic_set((uint32_t *)jmp_rw, B | (diff & 0x3fffffc));
108
flush_idcache_range(jmp_rx, jmp_rw, 4);
109
+ return;
110
}
111
+
112
+ /*
113
+ * For 16-bit displacements, we can use a single add + branch.
114
+ * This happens quite often.
115
+ */
116
+ if (tb_diff == (int16_t)tb_diff) {
117
+ i0 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, tb_diff);
118
+ i1 = B | (br_diff & 0x3fffffc);
119
+ ppc64_replace2(jmp_rx, jmp_rw, i0, i1);
120
+ return;
121
+ }
122
+
123
+ lo = (int16_t)tb_diff;
124
+ hi = (int32_t)(tb_diff - lo);
125
+ assert(tb_diff == hi + lo);
126
+ i0 = ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, hi >> 16);
127
+ i1 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, lo);
128
+
129
+ /*
130
+ * Without stq from 2.07, we can only update two insns,
131
+ * and those must be the ones that load the target address.
132
+ */
133
+ if (!have_isa_2_07) {
134
+ ppc64_replace2(jmp_rx, jmp_rw, i0, i1);
135
+ return;
136
+ }
30
+ }
137
+
31
+
138
+ /*
32
+ /*
139
+ * For 26-bit displacements, we can use a direct branch.
33
+ * Represent each EBB by the op at which it begins. In the case of
140
+ * Otherwise we still need the indirect branch, which we
34
+ * the first EBB, this is the first op, otherwise it is a label.
141
+ * must restore after a potential direct branch write.
35
+ * Collect the uses of each TEMP_TB: NULL for unused, EBB for use
36
+ * within a single EBB, else MULTIPLE_EBB.
142
+ */
37
+ */
143
+ br_diff -= 4;
38
+ ebb = QTAILQ_FIRST(&s->ops);
144
+ if (in_range_b(br_diff)) {
39
+ QTAILQ_FOREACH(op, &s->ops, link) {
145
+ i2 = B | (br_diff & 0x3fffffc);
40
+ const TCGOpDef *def;
146
+ i3 = NOP;
41
+ int nb_oargs, nb_iargs;
147
+ } else {
42
+
148
+ i2 = MTSPR | RS(TCG_REG_TB) | CTR;
43
+ switch (op->opc) {
149
+ i3 = BCCTR | BO_ALWAYS;
44
+ case INDEX_op_set_label:
45
+ ebb = op;
46
+ continue;
47
+ case INDEX_op_discard:
48
+ continue;
49
+ case INDEX_op_call:
50
+ nb_oargs = TCGOP_CALLO(op);
51
+ nb_iargs = TCGOP_CALLI(op);
52
+ break;
53
+ default:
54
+ def = &tcg_op_defs[op->opc];
55
+ nb_oargs = def->nb_oargs;
56
+ nb_iargs = def->nb_iargs;
57
+ break;
58
+ }
59
+
60
+ for (int i = 0; i < nb_oargs + nb_iargs; ++i) {
61
+ TCGTemp *ts = arg_temp(op->args[i]);
62
+
63
+ if (ts->kind != TEMP_TB) {
64
+ continue;
65
+ }
66
+ if (ts->state_ptr == NULL) {
67
+ ts->state_ptr = ebb;
68
+ } else if (ts->state_ptr != ebb) {
69
+ ts->state_ptr = multiple_ebb;
70
+ }
71
+ }
150
+ }
72
+ }
151
+ ppc64_replace4(jmp_rx, jmp_rw, i0, i1, i2, i3);
73
+
152
}
74
+ /*
153
75
+ * For TEMP_TB that turned out not to be used beyond one EBB,
154
static void tcg_out_call_int(TCGContext *s, int lk,
76
+ * reduce the liveness to TEMP_EBB.
155
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
77
+ */
156
if (s->tb_jmp_insn_offset) {
78
+ for (int i = s->nb_globals; i < nb_temps; ++i) {
157
/* Direct jump. */
79
+ TCGTemp *ts = &s->temps[i];
158
if (TCG_TARGET_REG_BITS == 64) {
80
+ if (ts->kind == TEMP_TB && ts->state_ptr != multiple_ebb) {
159
- /* Ensure the next insns are 8-byte aligned. */
81
+ ts->kind = TEMP_EBB;
160
- if ((uintptr_t)s->code_ptr & 7) {
82
+ }
161
+ /* Ensure the next insns are 8 or 16-byte aligned. */
83
+ }
162
+ while ((uintptr_t)s->code_ptr & (have_isa_2_07 ? 15 : 7)) {
84
+}
163
tcg_out32(s, NOP);
85
+
164
}
86
/* Liveness analysis : update the opc_arg_life array to tell if a
165
s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
87
given input arguments is dead. Instructions updating dead
88
temporaries are removed. */
89
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, target_ulong pc_start)
90
#endif
91
92
reachable_code_pass(s);
93
+ liveness_pass_0(s);
94
liveness_pass_1(s);
95
96
if (s->nb_indirects > 0) {
166
--
97
--
167
2.34.1
98
2.34.1
99
100
diff view generated by jsdifflib
New patch
1
TEMP_NORMAL is a subset of TEMP_EBB. Promote single basic
2
block temps to single extended basic block.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
include/tcg/tcg.h | 2 --
8
tcg/tcg.c | 19 +++----------------
9
2 files changed, 3 insertions(+), 18 deletions(-)
10
11
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/tcg/tcg.h
14
+++ b/include/tcg/tcg.h
15
@@ -XXX,XX +XXX,XX @@ typedef enum TCGTempVal {
16
} TCGTempVal;
17
18
typedef enum TCGTempKind {
19
- /* Temp is dead at the end of all basic blocks. */
20
- TEMP_NORMAL,
21
/*
22
* Temp is dead at the end of the extended basic block (EBB),
23
* the single-entry multiple-exit region that falls through
24
diff --git a/tcg/tcg.c b/tcg/tcg.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/tcg/tcg.c
27
+++ b/tcg/tcg.c
28
@@ -XXX,XX +XXX,XX @@ TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
29
TCGTemp *tcg_temp_new_internal(TCGType type, bool temp_local)
30
{
31
TCGContext *s = tcg_ctx;
32
- TCGTempKind kind = temp_local ? TEMP_TB : TEMP_NORMAL;
33
+ TCGTempKind kind = temp_local ? TEMP_TB : TEMP_EBB;
34
TCGTemp *ts;
35
int idx, k;
36
37
@@ -XXX,XX +XXX,XX @@ void tcg_temp_free_internal(TCGTemp *ts)
38
* silently ignore free.
39
*/
40
return;
41
- case TEMP_NORMAL:
42
+ case TEMP_EBB:
43
case TEMP_TB:
44
break;
45
default:
46
@@ -XXX,XX +XXX,XX @@ void tcg_temp_free_internal(TCGTemp *ts)
47
#endif
48
49
idx = temp_idx(ts);
50
- k = ts->base_type + (ts->kind == TEMP_NORMAL ? 0 : TCG_TYPE_COUNT);
51
+ k = ts->base_type + (ts->kind == TEMP_EBB ? 0 : TCG_TYPE_COUNT);
52
set_bit(idx, s->free_temps[k].l);
53
}
54
55
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_start(TCGContext *s)
56
break;
57
case TEMP_GLOBAL:
58
break;
59
- case TEMP_NORMAL:
60
case TEMP_EBB:
61
val = TEMP_VAL_DEAD;
62
/* fall through */
63
@@ -XXX,XX +XXX,XX @@ static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
64
snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
65
break;
66
case TEMP_EBB:
67
- snprintf(buf, buf_size, "ebb%d", idx - s->nb_globals);
68
- break;
69
- case TEMP_NORMAL:
70
snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
71
break;
72
case TEMP_CONST:
73
@@ -XXX,XX +XXX,XX @@ static void la_bb_end(TCGContext *s, int ng, int nt)
74
case TEMP_TB:
75
state = TS_DEAD | TS_MEM;
76
break;
77
- case TEMP_NORMAL:
78
case TEMP_EBB:
79
case TEMP_CONST:
80
state = TS_DEAD;
81
@@ -XXX,XX +XXX,XX @@ static void la_bb_sync(TCGContext *s, int ng, int nt)
82
continue;
83
}
84
break;
85
- case TEMP_NORMAL:
86
- s->temps[i].state = TS_DEAD;
87
- break;
88
case TEMP_EBB:
89
case TEMP_CONST:
90
continue;
91
@@ -XXX,XX +XXX,XX @@ static void temp_free_or_dead(TCGContext *s, TCGTemp *ts, int free_or_dead)
92
case TEMP_TB:
93
new_type = TEMP_VAL_MEM;
94
break;
95
- case TEMP_NORMAL:
96
case TEMP_EBB:
97
new_type = free_or_dead < 0 ? TEMP_VAL_MEM : TEMP_VAL_DEAD;
98
break;
99
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
100
case TEMP_TB:
101
temp_save(s, ts, allocated_regs);
102
break;
103
- case TEMP_NORMAL:
104
case TEMP_EBB:
105
/* The liveness analysis already ensures that temps are dead.
106
Keep an tcg_debug_assert for safety. */
107
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_cbranch(TCGContext *s, TCGRegSet allocated_regs)
108
case TEMP_TB:
109
tcg_debug_assert(ts->val_type != TEMP_VAL_REG || ts->mem_coherent);
110
break;
111
- case TEMP_NORMAL:
112
- tcg_debug_assert(ts->val_type == TEMP_VAL_DEAD);
113
- break;
114
case TEMP_EBB:
115
case TEMP_CONST:
116
break;
117
--
118
2.34.1
119
120
diff view generated by jsdifflib
1
This structure will shortly contain more than just
1
While the argument can only be TEMP_EBB or TEMP_TB,
2
data for accessing MMIO. Rename the 'addr' member
2
it's more obvious this way.
3
to 'xlat_section' to more clearly indicate its purpose.
4
3
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
6
---
10
include/exec/cpu-defs.h | 22 ++++----
7
include/tcg/tcg.h | 18 +++++++++---------
11
accel/tcg/cputlb.c | 102 +++++++++++++++++++------------------
8
tcg/tcg.c | 8 ++++----
12
target/arm/mte_helper.c | 14 ++---
9
2 files changed, 13 insertions(+), 13 deletions(-)
13
target/arm/sve_helper.c | 4 +-
14
target/arm/translate-a64.c | 2 +-
15
5 files changed, 73 insertions(+), 71 deletions(-)
16
10
17
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
11
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/cpu-defs.h
13
--- a/include/tcg/tcg.h
20
+++ b/include/exec/cpu-defs.h
14
+++ b/include/tcg/tcg.h
21
@@ -XXX,XX +XXX,XX @@ typedef uint64_t target_ulong;
15
@@ -XXX,XX +XXX,XX @@ void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
22
# endif
16
23
# endif
17
TCGTemp *tcg_global_mem_new_internal(TCGType, TCGv_ptr,
24
18
intptr_t, const char *);
25
+/* Minimalized TLB entry for use by TCG fast path. */
19
-TCGTemp *tcg_temp_new_internal(TCGType, bool);
26
typedef struct CPUTLBEntry {
20
+TCGTemp *tcg_temp_new_internal(TCGType, TCGTempKind);
27
/* bit TARGET_LONG_BITS to TARGET_PAGE_BITS : virtual address
21
void tcg_temp_free_internal(TCGTemp *);
28
bit TARGET_PAGE_BITS-1..4 : Nonzero for accesses that should not
22
TCGv_vec tcg_temp_new_vec(TCGType type);
29
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBEntry {
23
TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match);
30
24
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
31
QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
25
32
26
static inline TCGv_i32 tcg_temp_new_i32(void)
33
-/* The IOTLB is not accessed directly inline by generated TCG code,
27
{
34
- * so the CPUIOTLBEntry layout is not as critical as that of the
28
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, false);
35
- * CPUTLBEntry. (This is also why we don't want to combine the two
29
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, TEMP_EBB);
36
- * structs into one.)
30
return temp_tcgv_i32(t);
37
+/*
31
}
38
+ * The full TLB entry, which is not accessed by generated TCG code,
32
39
+ * so the layout is not as critical as that of CPUTLBEntry. This is
33
static inline TCGv_i32 tcg_temp_local_new_i32(void)
40
+ * also why we don't want to combine the two structs.
34
{
41
*/
35
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, true);
42
-typedef struct CPUIOTLBEntry {
36
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, TEMP_TB);
43
+typedef struct CPUTLBEntryFull {
37
return temp_tcgv_i32(t);
44
/*
38
}
45
- * @addr contains:
39
46
+ * @xlat_section contains:
40
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
47
* - in the lower TARGET_PAGE_BITS, a physical section number
41
48
* - with the lower TARGET_PAGE_BITS masked off, an offset which
42
static inline TCGv_i64 tcg_temp_new_i64(void)
49
* must be added to the virtual address to obtain:
43
{
50
@@ -XXX,XX +XXX,XX @@ typedef struct CPUIOTLBEntry {
44
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, false);
51
* number is PHYS_SECTION_NOTDIRTY or PHYS_SECTION_ROM)
45
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, TEMP_EBB);
52
* + the offset within the target MemoryRegion (otherwise)
46
return temp_tcgv_i64(t);
53
*/
47
}
54
- hwaddr addr;
48
55
+ hwaddr xlat_section;
49
static inline TCGv_i64 tcg_temp_local_new_i64(void)
56
MemTxAttrs attrs;
50
{
57
-} CPUIOTLBEntry;
51
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, true);
58
+} CPUTLBEntryFull;
52
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, TEMP_TB);
59
53
return temp_tcgv_i64(t);
60
/*
54
}
61
* Data elements that are per MMU mode, minus the bits accessed by
55
62
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBDesc {
56
static inline TCGv_i128 tcg_temp_new_i128(void)
63
size_t vindex;
57
{
64
/* The tlb victim table, in two parts. */
58
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, false);
65
CPUTLBEntry vtable[CPU_VTLB_SIZE];
59
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, TEMP_EBB);
66
- CPUIOTLBEntry viotlb[CPU_VTLB_SIZE];
60
return temp_tcgv_i128(t);
67
- /* The iotlb. */
61
}
68
- CPUIOTLBEntry *iotlb;
62
69
+ CPUTLBEntryFull vfulltlb[CPU_VTLB_SIZE];
63
static inline TCGv_i128 tcg_temp_local_new_i128(void)
70
+ CPUTLBEntryFull *fulltlb;
64
{
71
} CPUTLBDesc;
65
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, true);
72
66
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, TEMP_TB);
73
/*
67
return temp_tcgv_i128(t);
74
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
68
}
69
70
@@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr tcg_global_mem_new_ptr(TCGv_ptr reg, intptr_t offset,
71
72
static inline TCGv_ptr tcg_temp_new_ptr(void)
73
{
74
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, false);
75
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_EBB);
76
return temp_tcgv_ptr(t);
77
}
78
79
static inline TCGv_ptr tcg_temp_local_new_ptr(void)
80
{
81
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, true);
82
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_TB);
83
return temp_tcgv_ptr(t);
84
}
85
86
diff --git a/tcg/tcg.c b/tcg/tcg.c
75
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
76
--- a/accel/tcg/cputlb.c
88
--- a/tcg/tcg.c
77
+++ b/accel/tcg/cputlb.c
89
+++ b/tcg/tcg.c
78
@@ -XXX,XX +XXX,XX @@ static void tlb_mmu_resize_locked(CPUTLBDesc *desc, CPUTLBDescFast *fast,
90
@@ -XXX,XX +XXX,XX @@ TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
79
}
91
return ts;
80
81
g_free(fast->table);
82
- g_free(desc->iotlb);
83
+ g_free(desc->fulltlb);
84
85
tlb_window_reset(desc, now, 0);
86
/* desc->n_used_entries is cleared by the caller */
87
fast->mask = (new_size - 1) << CPU_TLB_ENTRY_BITS;
88
fast->table = g_try_new(CPUTLBEntry, new_size);
89
- desc->iotlb = g_try_new(CPUIOTLBEntry, new_size);
90
+ desc->fulltlb = g_try_new(CPUTLBEntryFull, new_size);
91
92
/*
93
* If the allocations fail, try smaller sizes. We just freed some
94
@@ -XXX,XX +XXX,XX @@ static void tlb_mmu_resize_locked(CPUTLBDesc *desc, CPUTLBDescFast *fast,
95
* allocations to fail though, so we progressively reduce the allocation
96
* size, aborting if we cannot even allocate the smallest TLB we support.
97
*/
98
- while (fast->table == NULL || desc->iotlb == NULL) {
99
+ while (fast->table == NULL || desc->fulltlb == NULL) {
100
if (new_size == (1 << CPU_TLB_DYN_MIN_BITS)) {
101
error_report("%s: %s", __func__, strerror(errno));
102
abort();
103
@@ -XXX,XX +XXX,XX @@ static void tlb_mmu_resize_locked(CPUTLBDesc *desc, CPUTLBDescFast *fast,
104
fast->mask = (new_size - 1) << CPU_TLB_ENTRY_BITS;
105
106
g_free(fast->table);
107
- g_free(desc->iotlb);
108
+ g_free(desc->fulltlb);
109
fast->table = g_try_new(CPUTLBEntry, new_size);
110
- desc->iotlb = g_try_new(CPUIOTLBEntry, new_size);
111
+ desc->fulltlb = g_try_new(CPUTLBEntryFull, new_size);
112
}
113
}
92
}
114
93
115
@@ -XXX,XX +XXX,XX @@ static void tlb_mmu_init(CPUTLBDesc *desc, CPUTLBDescFast *fast, int64_t now)
94
-TCGTemp *tcg_temp_new_internal(TCGType type, bool temp_local)
116
desc->n_used_entries = 0;
95
+TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind)
117
fast->mask = (n_entries - 1) << CPU_TLB_ENTRY_BITS;
118
fast->table = g_new(CPUTLBEntry, n_entries);
119
- desc->iotlb = g_new(CPUIOTLBEntry, n_entries);
120
+ desc->fulltlb = g_new(CPUTLBEntryFull, n_entries);
121
tlb_mmu_flush_locked(desc, fast);
122
}
123
124
@@ -XXX,XX +XXX,XX @@ void tlb_destroy(CPUState *cpu)
125
CPUTLBDescFast *fast = &env_tlb(env)->f[i];
126
127
g_free(fast->table);
128
- g_free(desc->iotlb);
129
+ g_free(desc->fulltlb);
130
}
131
}
132
133
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
134
135
/* Evict the old entry into the victim tlb. */
136
copy_tlb_helper_locked(tv, te);
137
- desc->viotlb[vidx] = desc->iotlb[index];
138
+ desc->vfulltlb[vidx] = desc->fulltlb[index];
139
tlb_n_used_entries_dec(env, mmu_idx);
140
}
141
142
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
143
* subtract here is that of the page base, and not the same as the
144
* vaddr we add back in io_readx()/io_writex()/get_page_addr_code().
145
*/
146
- desc->iotlb[index].addr = iotlb - vaddr_page;
147
- desc->iotlb[index].attrs = attrs;
148
+ desc->fulltlb[index].xlat_section = iotlb - vaddr_page;
149
+ desc->fulltlb[index].attrs = attrs;
150
151
/* Now calculate the new entry */
152
tn.addend = addend - vaddr_page;
153
@@ -XXX,XX +XXX,XX @@ static inline void cpu_transaction_failed(CPUState *cpu, hwaddr physaddr,
154
}
155
}
156
157
-static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
158
+static uint64_t io_readx(CPUArchState *env, CPUTLBEntryFull *full,
159
int mmu_idx, target_ulong addr, uintptr_t retaddr,
160
MMUAccessType access_type, MemOp op)
161
{
96
{
162
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
97
TCGContext *s = tcg_ctx;
163
bool locked = false;
98
- TCGTempKind kind = temp_local ? TEMP_TB : TEMP_EBB;
164
MemTxResult r;
99
+ bool temp_local = kind == TEMP_TB;
165
100
TCGTemp *ts;
166
- section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
101
int idx, k;
167
+ section = iotlb_to_section(cpu, full->xlat_section, full->attrs);
102
168
mr = section->mr;
103
@@ -XXX,XX +XXX,XX @@ TCGv_vec tcg_temp_new_vec(TCGType type)
169
- mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
170
+ mr_offset = (full->xlat_section & TARGET_PAGE_MASK) + addr;
171
cpu->mem_io_pc = retaddr;
172
if (!cpu->can_do_io) {
173
cpu_io_recompile(cpu, retaddr);
174
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
175
qemu_mutex_lock_iothread();
176
locked = true;
177
}
178
- r = memory_region_dispatch_read(mr, mr_offset, &val, op, iotlbentry->attrs);
179
+ r = memory_region_dispatch_read(mr, mr_offset, &val, op, full->attrs);
180
if (r != MEMTX_OK) {
181
hwaddr physaddr = mr_offset +
182
section->offset_within_address_space -
183
section->offset_within_region;
184
185
cpu_transaction_failed(cpu, physaddr, addr, memop_size(op), access_type,
186
- mmu_idx, iotlbentry->attrs, r, retaddr);
187
+ mmu_idx, full->attrs, r, retaddr);
188
}
189
if (locked) {
190
qemu_mutex_unlock_iothread();
191
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
192
}
193
194
/*
195
- * Save a potentially trashed IOTLB entry for later lookup by plugin.
196
- * This is read by tlb_plugin_lookup if the iotlb entry doesn't match
197
+ * Save a potentially trashed CPUTLBEntryFull for later lookup by plugin.
198
+ * This is read by tlb_plugin_lookup if the fulltlb entry doesn't match
199
* because of the side effect of io_writex changing memory layout.
200
*/
201
static void save_iotlb_data(CPUState *cs, hwaddr addr,
202
@@ -XXX,XX +XXX,XX @@ static void save_iotlb_data(CPUState *cs, hwaddr addr,
203
#endif
204
}
205
206
-static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
207
+static void io_writex(CPUArchState *env, CPUTLBEntryFull *full,
208
int mmu_idx, uint64_t val, target_ulong addr,
209
uintptr_t retaddr, MemOp op)
210
{
211
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
212
bool locked = false;
213
MemTxResult r;
214
215
- section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
216
+ section = iotlb_to_section(cpu, full->xlat_section, full->attrs);
217
mr = section->mr;
218
- mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
219
+ mr_offset = (full->xlat_section & TARGET_PAGE_MASK) + addr;
220
if (!cpu->can_do_io) {
221
cpu_io_recompile(cpu, retaddr);
222
}
223
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
224
* The memory_region_dispatch may trigger a flush/resize
225
* so for plugins we save the iotlb_data just in case.
226
*/
227
- save_iotlb_data(cpu, iotlbentry->addr, section, mr_offset);
228
+ save_iotlb_data(cpu, full->xlat_section, section, mr_offset);
229
230
if (!qemu_mutex_iothread_locked()) {
231
qemu_mutex_lock_iothread();
232
locked = true;
233
}
234
- r = memory_region_dispatch_write(mr, mr_offset, val, op, iotlbentry->attrs);
235
+ r = memory_region_dispatch_write(mr, mr_offset, val, op, full->attrs);
236
if (r != MEMTX_OK) {
237
hwaddr physaddr = mr_offset +
238
section->offset_within_address_space -
239
section->offset_within_region;
240
241
cpu_transaction_failed(cpu, physaddr, addr, memop_size(op),
242
- MMU_DATA_STORE, mmu_idx, iotlbentry->attrs, r,
243
+ MMU_DATA_STORE, mmu_idx, full->attrs, r,
244
retaddr);
245
}
246
if (locked) {
247
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
248
copy_tlb_helper_locked(vtlb, &tmptlb);
249
qemu_spin_unlock(&env_tlb(env)->c.lock);
250
251
- CPUIOTLBEntry tmpio, *io = &env_tlb(env)->d[mmu_idx].iotlb[index];
252
- CPUIOTLBEntry *vio = &env_tlb(env)->d[mmu_idx].viotlb[vidx];
253
- tmpio = *io; *io = *vio; *vio = tmpio;
254
+ CPUTLBEntryFull *f1 = &env_tlb(env)->d[mmu_idx].fulltlb[index];
255
+ CPUTLBEntryFull *f2 = &env_tlb(env)->d[mmu_idx].vfulltlb[vidx];
256
+ CPUTLBEntryFull tmpf;
257
+ tmpf = *f1; *f1 = *f2; *f2 = tmpf;
258
return true;
259
}
260
}
261
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
262
(ADDR) & TARGET_PAGE_MASK)
263
264
static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size,
265
- CPUIOTLBEntry *iotlbentry, uintptr_t retaddr)
266
+ CPUTLBEntryFull *full, uintptr_t retaddr)
267
{
268
- ram_addr_t ram_addr = mem_vaddr + iotlbentry->addr;
269
+ ram_addr_t ram_addr = mem_vaddr + full->xlat_section;
270
271
trace_memory_notdirty_write_access(mem_vaddr, ram_addr, size);
272
273
@@ -XXX,XX +XXX,XX @@ int probe_access_flags(CPUArchState *env, target_ulong addr,
274
/* Handle clean RAM pages. */
275
if (unlikely(flags & TLB_NOTDIRTY)) {
276
uintptr_t index = tlb_index(env, mmu_idx, addr);
277
- CPUIOTLBEntry *iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
278
+ CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
279
280
- notdirty_write(env_cpu(env), addr, 1, iotlbentry, retaddr);
281
+ notdirty_write(env_cpu(env), addr, 1, full, retaddr);
282
flags &= ~TLB_NOTDIRTY;
283
}
284
285
@@ -XXX,XX +XXX,XX @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
286
287
if (unlikely(flags & (TLB_NOTDIRTY | TLB_WATCHPOINT))) {
288
uintptr_t index = tlb_index(env, mmu_idx, addr);
289
- CPUIOTLBEntry *iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
290
+ CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
291
292
/* Handle watchpoints. */
293
if (flags & TLB_WATCHPOINT) {
294
int wp_access = (access_type == MMU_DATA_STORE
295
? BP_MEM_WRITE : BP_MEM_READ);
296
cpu_check_watchpoint(env_cpu(env), addr, size,
297
- iotlbentry->attrs, wp_access, retaddr);
298
+ full->attrs, wp_access, retaddr);
299
}
300
301
/* Handle clean RAM pages. */
302
if (flags & TLB_NOTDIRTY) {
303
- notdirty_write(env_cpu(env), addr, 1, iotlbentry, retaddr);
304
+ notdirty_write(env_cpu(env), addr, 1, full, retaddr);
305
}
306
}
307
308
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
309
* should have just filled the TLB. The one corner case is io_writex
310
* which can cause TLB flushes and potential resizing of the TLBs
311
* losing the information we need. In those cases we need to recover
312
- * data from a copy of the iotlbentry. As long as this always occurs
313
+ * data from a copy of the CPUTLBEntryFull. As long as this always occurs
314
* from the same thread (which a mem callback will be) this is safe.
315
*/
316
317
@@ -XXX,XX +XXX,XX @@ bool tlb_plugin_lookup(CPUState *cpu, target_ulong addr, int mmu_idx,
318
if (likely(tlb_hit(tlb_addr, addr))) {
319
/* We must have an iotlb entry for MMIO */
320
if (tlb_addr & TLB_MMIO) {
321
- CPUIOTLBEntry *iotlbentry;
322
- iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
323
+ CPUTLBEntryFull *full;
324
+ full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
325
data->is_io = true;
326
- data->v.io.section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
327
- data->v.io.offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
328
+ data->v.io.section =
329
+ iotlb_to_section(cpu, full->xlat_section, full->attrs);
330
+ data->v.io.offset = (full->xlat_section & TARGET_PAGE_MASK) + addr;
331
} else {
332
data->is_io = false;
333
data->v.ram.hostaddr = (void *)((uintptr_t)addr + tlbe->addend);
334
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
335
336
if (unlikely(tlb_addr & TLB_NOTDIRTY)) {
337
notdirty_write(env_cpu(env), addr, size,
338
- &env_tlb(env)->d[mmu_idx].iotlb[index], retaddr);
339
+ &env_tlb(env)->d[mmu_idx].fulltlb[index], retaddr);
340
}
341
342
return hostaddr;
343
@@ -XXX,XX +XXX,XX @@ load_helper(CPUArchState *env, target_ulong addr, MemOpIdx oi,
344
345
/* Handle anything that isn't just a straight memory access. */
346
if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
347
- CPUIOTLBEntry *iotlbentry;
348
+ CPUTLBEntryFull *full;
349
bool need_swap;
350
351
/* For anything that is unaligned, recurse through full_load. */
352
@@ -XXX,XX +XXX,XX @@ load_helper(CPUArchState *env, target_ulong addr, MemOpIdx oi,
353
goto do_unaligned_access;
354
}
355
356
- iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
357
+ full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
358
359
/* Handle watchpoints. */
360
if (unlikely(tlb_addr & TLB_WATCHPOINT)) {
361
/* On watchpoint hit, this will longjmp out. */
362
cpu_check_watchpoint(env_cpu(env), addr, size,
363
- iotlbentry->attrs, BP_MEM_READ, retaddr);
364
+ full->attrs, BP_MEM_READ, retaddr);
365
}
366
367
need_swap = size > 1 && (tlb_addr & TLB_BSWAP);
368
369
/* Handle I/O access. */
370
if (likely(tlb_addr & TLB_MMIO)) {
371
- return io_readx(env, iotlbentry, mmu_idx, addr, retaddr,
372
+ return io_readx(env, full, mmu_idx, addr, retaddr,
373
access_type, op ^ (need_swap * MO_BSWAP));
374
}
375
376
@@ -XXX,XX +XXX,XX @@ store_helper_unaligned(CPUArchState *env, target_ulong addr, uint64_t val,
377
*/
378
if (unlikely(tlb_addr & TLB_WATCHPOINT)) {
379
cpu_check_watchpoint(env_cpu(env), addr, size - size2,
380
- env_tlb(env)->d[mmu_idx].iotlb[index].attrs,
381
+ env_tlb(env)->d[mmu_idx].fulltlb[index].attrs,
382
BP_MEM_WRITE, retaddr);
383
}
384
if (unlikely(tlb_addr2 & TLB_WATCHPOINT)) {
385
cpu_check_watchpoint(env_cpu(env), page2, size2,
386
- env_tlb(env)->d[mmu_idx].iotlb[index2].attrs,
387
+ env_tlb(env)->d[mmu_idx].fulltlb[index2].attrs,
388
BP_MEM_WRITE, retaddr);
389
}
390
391
@@ -XXX,XX +XXX,XX @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
392
393
/* Handle anything that isn't just a straight memory access. */
394
if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
395
- CPUIOTLBEntry *iotlbentry;
396
+ CPUTLBEntryFull *full;
397
bool need_swap;
398
399
/* For anything that is unaligned, recurse through byte stores. */
400
@@ -XXX,XX +XXX,XX @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
401
goto do_unaligned_access;
402
}
403
404
- iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
405
+ full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
406
407
/* Handle watchpoints. */
408
if (unlikely(tlb_addr & TLB_WATCHPOINT)) {
409
/* On watchpoint hit, this will longjmp out. */
410
cpu_check_watchpoint(env_cpu(env), addr, size,
411
- iotlbentry->attrs, BP_MEM_WRITE, retaddr);
412
+ full->attrs, BP_MEM_WRITE, retaddr);
413
}
414
415
need_swap = size > 1 && (tlb_addr & TLB_BSWAP);
416
417
/* Handle I/O access. */
418
if (tlb_addr & TLB_MMIO) {
419
- io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr,
420
+ io_writex(env, full, mmu_idx, val, addr, retaddr,
421
op ^ (need_swap * MO_BSWAP));
422
return;
423
}
424
@@ -XXX,XX +XXX,XX @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
425
426
/* Handle clean RAM pages. */
427
if (tlb_addr & TLB_NOTDIRTY) {
428
- notdirty_write(env_cpu(env), addr, size, iotlbentry, retaddr);
429
+ notdirty_write(env_cpu(env), addr, size, full, retaddr);
430
}
431
432
haddr = (void *)((uintptr_t)addr + entry->addend);
433
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
434
index XXXXXXX..XXXXXXX 100644
435
--- a/target/arm/mte_helper.c
436
+++ b/target/arm/mte_helper.c
437
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
438
return tags + index;
439
#else
440
uintptr_t index;
441
- CPUIOTLBEntry *iotlbentry;
442
+ CPUTLBEntryFull *full;
443
int in_page, flags;
444
ram_addr_t ptr_ra;
445
hwaddr ptr_paddr, tag_paddr, xlat;
446
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
447
assert(!(flags & TLB_INVALID_MASK));
448
449
/*
450
- * Find the iotlbentry for ptr. This *must* be present in the TLB
451
+ * Find the CPUTLBEntryFull for ptr. This *must* be present in the TLB
452
* because we just found the mapping.
453
* TODO: Perhaps there should be a cputlb helper that returns a
454
* matching tlb entry + iotlb entry.
455
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
456
g_assert(tlb_hit(comparator, ptr));
457
}
458
# endif
459
- iotlbentry = &env_tlb(env)->d[ptr_mmu_idx].iotlb[index];
460
+ full = &env_tlb(env)->d[ptr_mmu_idx].fulltlb[index];
461
462
/* If the virtual page MemAttr != Tagged, access unchecked. */
463
- if (!arm_tlb_mte_tagged(&iotlbentry->attrs)) {
464
+ if (!arm_tlb_mte_tagged(&full->attrs)) {
465
return NULL;
466
}
467
468
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
469
int wp = ptr_access == MMU_DATA_LOAD ? BP_MEM_READ : BP_MEM_WRITE;
470
assert(ra != 0);
471
cpu_check_watchpoint(env_cpu(env), ptr, ptr_size,
472
- iotlbentry->attrs, wp, ra);
473
+ full->attrs, wp, ra);
474
}
475
476
/*
477
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
478
tag_paddr = ptr_paddr >> (LOG2_TAG_GRANULE + 1);
479
480
/* Look up the address in tag space. */
481
- tag_asi = iotlbentry->attrs.secure ? ARMASIdx_TagS : ARMASIdx_TagNS;
482
+ tag_asi = full->attrs.secure ? ARMASIdx_TagS : ARMASIdx_TagNS;
483
tag_as = cpu_get_address_space(env_cpu(env), tag_asi);
484
mr = address_space_translate(tag_as, tag_paddr, &xlat, NULL,
485
tag_access == MMU_DATA_STORE,
486
- iotlbentry->attrs);
487
+ full->attrs);
488
489
/*
490
* Note that @mr will never be NULL. If there is nothing in the address
491
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
492
index XXXXXXX..XXXXXXX 100644
493
--- a/target/arm/sve_helper.c
494
+++ b/target/arm/sve_helper.c
495
@@ -XXX,XX +XXX,XX @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
496
g_assert(tlb_hit(comparator, addr));
497
# endif
498
499
- CPUIOTLBEntry *iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
500
- info->attrs = iotlbentry->attrs;
501
+ CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
502
+ info->attrs = full->attrs;
503
}
104
}
504
#endif
105
#endif
505
106
506
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
107
- t = tcg_temp_new_internal(type, 0);
507
index XXXXXXX..XXXXXXX 100644
108
+ t = tcg_temp_new_internal(type, TEMP_EBB);
508
--- a/target/arm/translate-a64.c
109
return temp_tcgv_vec(t);
509
+++ b/target/arm/translate-a64.c
510
@@ -XXX,XX +XXX,XX @@ static bool is_guarded_page(CPUARMState *env, DisasContext *s)
511
* table entry even for that case.
512
*/
513
return (tlb_hit(entry->addr_code, addr) &&
514
- arm_tlb_bti_gp(&env_tlb(env)->d[mmu_idx].iotlb[index].attrs));
515
+ arm_tlb_bti_gp(&env_tlb(env)->d[mmu_idx].fulltlb[index].attrs));
516
#endif
517
}
110
}
111
112
@@ -XXX,XX +XXX,XX @@ TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match)
113
114
tcg_debug_assert(t->temp_allocated != 0);
115
116
- t = tcg_temp_new_internal(t->base_type, 0);
117
+ t = tcg_temp_new_internal(t->base_type, TEMP_EBB);
118
return temp_tcgv_vec(t);
119
}
518
120
519
--
121
--
520
2.34.1
122
2.34.1
521
123
522
124
diff view generated by jsdifflib
New patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
include/exec/gen-icount.h | 4 +---
6
1 file changed, 1 insertion(+), 3 deletions(-)
1
7
8
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
9
index XXXXXXX..XXXXXXX 100644
10
--- a/include/exec/gen-icount.h
11
+++ b/include/exec/gen-icount.h
12
@@ -XXX,XX +XXX,XX @@ static TCGOp *icount_start_insn;
13
14
static inline void gen_io_start(void)
15
{
16
- TCGv_i32 tmp = tcg_const_i32(1);
17
- tcg_gen_st_i32(tmp, cpu_env,
18
+ tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
19
offsetof(ArchCPU, parent_obj.can_do_io) -
20
offsetof(ArchCPU, env));
21
- tcg_temp_free_i32(tmp);
22
}
23
24
static inline void gen_tb_start(const TranslationBlock *tb)
25
--
26
2.34.1
27
28
diff view generated by jsdifflib
New patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
include/tcg/tcg-op.h | 5 +++++
5
1 file changed, 5 insertions(+)
1
6
7
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
8
index XXXXXXX..XXXXXXX 100644
9
--- a/include/tcg/tcg-op.h
10
+++ b/include/tcg/tcg-op.h
11
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_mov_ptr(TCGv_ptr d, TCGv_ptr s)
12
glue(tcg_gen_mov_,PTR)((NAT)d, (NAT)s);
13
}
14
15
+static inline void tcg_gen_movi_ptr(TCGv_ptr d, intptr_t s)
16
+{
17
+ glue(tcg_gen_movi_,PTR)((NAT)d, s);
18
+}
19
+
20
static inline void tcg_gen_brcondi_ptr(TCGCond cond, TCGv_ptr a,
21
intptr_t b, TCGLabel *label)
22
{
23
--
24
2.34.1
25
26
diff view generated by jsdifflib
1
Populate this new method for all targets. Always match
1
TCG internals will want to be able to allocate and reuse
2
the result that would be given by cpu_get_tb_cpu_state,
2
explicitly life-limited temporaries.
3
as we will want these values to correspond in the logs.
4
3
5
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> (target/sparc)
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
6
---
10
Cc: Eduardo Habkost <eduardo@habkost.net> (supporter:Machine core)
7
include/tcg/tcg.h | 28 ++++++++++++++++++++++++++++
11
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com> (supporter:Machine core)
8
1 file changed, 28 insertions(+)
12
Cc: "Philippe Mathieu-Daudé" <f4bug@amsat.org> (reviewer:Machine core)
13
Cc: Yanan Wang <wangyanan55@huawei.com> (reviewer:Machine core)
14
Cc: Michael Rolnik <mrolnik@gmail.com> (maintainer:AVR TCG CPUs)
15
Cc: "Edgar E. Iglesias" <edgar.iglesias@gmail.com> (maintainer:CRIS TCG CPUs)
16
Cc: Taylor Simpson <tsimpson@quicinc.com> (supporter:Hexagon TCG CPUs)
17
Cc: Song Gao <gaosong@loongson.cn> (maintainer:LoongArch TCG CPUs)
18
Cc: Xiaojuan Yang <yangxiaojuan@loongson.cn> (maintainer:LoongArch TCG CPUs)
19
Cc: Laurent Vivier <laurent@vivier.eu> (maintainer:M68K TCG CPUs)
20
Cc: Jiaxun Yang <jiaxun.yang@flygoat.com> (reviewer:MIPS TCG CPUs)
21
Cc: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> (reviewer:MIPS TCG CPUs)
22
Cc: Chris Wulff <crwulff@gmail.com> (maintainer:NiosII TCG CPUs)
23
Cc: Marek Vasut <marex@denx.de> (maintainer:NiosII TCG CPUs)
24
Cc: Stafford Horne <shorne@gmail.com> (odd fixer:OpenRISC TCG CPUs)
25
Cc: Yoshinori Sato <ysato@users.sourceforge.jp> (reviewer:RENESAS RX CPUs)
26
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> (maintainer:SPARC TCG CPUs)
27
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> (maintainer:TriCore TCG CPUs)
28
Cc: Max Filippov <jcmvbkbc@gmail.com> (maintainer:Xtensa TCG CPUs)
29
Cc: qemu-arm@nongnu.org (open list:ARM TCG CPUs)
30
Cc: qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs)
31
Cc: qemu-riscv@nongnu.org (open list:RISC-V TCG CPUs)
32
Cc: qemu-s390x@nongnu.org (open list:S390 TCG CPUs)
33
---
34
include/hw/core/cpu.h | 3 +++
35
target/alpha/cpu.c | 9 +++++++++
36
target/arm/cpu.c | 13 +++++++++++++
37
target/avr/cpu.c | 8 ++++++++
38
target/cris/cpu.c | 8 ++++++++
39
target/hexagon/cpu.c | 8 ++++++++
40
target/hppa/cpu.c | 8 ++++++++
41
target/i386/cpu.c | 9 +++++++++
42
target/loongarch/cpu.c | 9 +++++++++
43
target/m68k/cpu.c | 8 ++++++++
44
target/microblaze/cpu.c | 8 ++++++++
45
target/mips/cpu.c | 8 ++++++++
46
target/nios2/cpu.c | 9 +++++++++
47
target/openrisc/cpu.c | 8 ++++++++
48
target/ppc/cpu_init.c | 8 ++++++++
49
target/riscv/cpu.c | 13 +++++++++++++
50
target/rx/cpu.c | 8 ++++++++
51
target/s390x/cpu.c | 8 ++++++++
52
target/sh4/cpu.c | 8 ++++++++
53
target/sparc/cpu.c | 8 ++++++++
54
target/tricore/cpu.c | 9 +++++++++
55
target/xtensa/cpu.c | 8 ++++++++
56
22 files changed, 186 insertions(+)
57
9
58
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
10
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
59
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
60
--- a/include/hw/core/cpu.h
12
--- a/include/tcg/tcg.h
61
+++ b/include/hw/core/cpu.h
13
+++ b/include/tcg/tcg.h
62
@@ -XXX,XX +XXX,XX @@ struct SysemuCPUOps;
14
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
63
* If the target behaviour here is anything other than "set
15
return temp_tcgv_i32(t);
64
* the PC register to the value passed in" then the target must
65
* also implement the synchronize_from_tb hook.
66
+ * @get_pc: Callback for getting the Program Counter register.
67
+ * As above, with the semantics of the target architecture.
68
* @gdb_read_register: Callback for letting GDB read a register.
69
* @gdb_write_register: Callback for letting GDB write a register.
70
* @gdb_adjust_breakpoint: Callback for adjusting the address of a
71
@@ -XXX,XX +XXX,XX @@ struct CPUClass {
72
void (*dump_state)(CPUState *cpu, FILE *, int flags);
73
int64_t (*get_arch_id)(CPUState *cpu);
74
void (*set_pc)(CPUState *cpu, vaddr value);
75
+ vaddr (*get_pc)(CPUState *cpu);
76
int (*gdb_read_register)(CPUState *cpu, GByteArray *buf, int reg);
77
int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg);
78
vaddr (*gdb_adjust_breakpoint)(CPUState *cpu, vaddr addr);
79
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/alpha/cpu.c
82
+++ b/target/alpha/cpu.c
83
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_set_pc(CPUState *cs, vaddr value)
84
cpu->env.pc = value;
85
}
16
}
86
17
87
+static vaddr alpha_cpu_get_pc(CPUState *cs)
18
+/* Used only by tcg infrastructure: tcg-op.c or plugin-gen.c */
19
+static inline TCGv_i32 tcg_temp_ebb_new_i32(void)
88
+{
20
+{
89
+ AlphaCPU *cpu = ALPHA_CPU(cs);
21
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, TEMP_EBB);
90
+
22
+ return temp_tcgv_i32(t);
91
+ return cpu->env.pc;
92
+}
23
+}
93
+
24
+
94
+
25
static inline TCGv_i32 tcg_temp_new_i32(void)
95
static bool alpha_cpu_has_work(CPUState *cs)
96
{
26
{
97
/* Here we are checking to see if the CPU should wake up from HALT.
27
TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, TEMP_EBB);
98
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
28
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
99
cc->has_work = alpha_cpu_has_work;
29
return temp_tcgv_i64(t);
100
cc->dump_state = alpha_cpu_dump_state;
101
cc->set_pc = alpha_cpu_set_pc;
102
+ cc->get_pc = alpha_cpu_get_pc;
103
cc->gdb_read_register = alpha_cpu_gdb_read_register;
104
cc->gdb_write_register = alpha_cpu_gdb_write_register;
105
#ifndef CONFIG_USER_ONLY
106
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/cpu.c
109
+++ b/target/arm/cpu.c
110
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_set_pc(CPUState *cs, vaddr value)
111
}
112
}
30
}
113
31
114
+static vaddr arm_cpu_get_pc(CPUState *cs)
32
+/* Used only by tcg infrastructure: tcg-op.c or plugin-gen.c */
33
+static inline TCGv_i64 tcg_temp_ebb_new_i64(void)
115
+{
34
+{
116
+ ARMCPU *cpu = ARM_CPU(cs);
35
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, TEMP_EBB);
117
+ CPUARMState *env = &cpu->env;
36
+ return temp_tcgv_i64(t);
118
+
119
+ if (is_a64(env)) {
120
+ return env->pc;
121
+ } else {
122
+ return env->regs[15];
123
+ }
124
+}
37
+}
125
+
38
+
126
#ifdef CONFIG_TCG
39
static inline TCGv_i64 tcg_temp_new_i64(void)
127
void arm_cpu_synchronize_from_tb(CPUState *cs,
40
{
128
const TranslationBlock *tb)
41
TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, TEMP_EBB);
129
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
42
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i64 tcg_temp_local_new_i64(void)
130
cc->has_work = arm_cpu_has_work;
43
return temp_tcgv_i64(t);
131
cc->dump_state = arm_cpu_dump_state;
132
cc->set_pc = arm_cpu_set_pc;
133
+ cc->get_pc = arm_cpu_get_pc;
134
cc->gdb_read_register = arm_cpu_gdb_read_register;
135
cc->gdb_write_register = arm_cpu_gdb_write_register;
136
#ifndef CONFIG_USER_ONLY
137
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/avr/cpu.c
140
+++ b/target/avr/cpu.c
141
@@ -XXX,XX +XXX,XX @@ static void avr_cpu_set_pc(CPUState *cs, vaddr value)
142
cpu->env.pc_w = value / 2; /* internally PC points to words */
143
}
44
}
144
45
145
+static vaddr avr_cpu_get_pc(CPUState *cs)
46
+/* Used only by tcg infrastructure: tcg-op.c or plugin-gen.c */
47
+static inline TCGv_i128 tcg_temp_ebb_new_i128(void)
146
+{
48
+{
147
+ AVRCPU *cpu = AVR_CPU(cs);
49
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, TEMP_EBB);
148
+
50
+ return temp_tcgv_i128(t);
149
+ return cpu->env.pc_w * 2;
150
+}
51
+}
151
+
52
+
152
static bool avr_cpu_has_work(CPUState *cs)
53
static inline TCGv_i128 tcg_temp_new_i128(void)
153
{
54
{
154
AVRCPU *cpu = AVR_CPU(cs);
55
TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, TEMP_EBB);
155
@@ -XXX,XX +XXX,XX @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
56
@@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr tcg_global_mem_new_ptr(TCGv_ptr reg, intptr_t offset,
156
cc->has_work = avr_cpu_has_work;
57
return temp_tcgv_ptr(t);
157
cc->dump_state = avr_cpu_dump_state;
158
cc->set_pc = avr_cpu_set_pc;
159
+ cc->get_pc = avr_cpu_get_pc;
160
dc->vmsd = &vms_avr_cpu;
161
cc->sysemu_ops = &avr_sysemu_ops;
162
cc->disas_set_info = avr_cpu_disas_set_info;
163
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/cris/cpu.c
166
+++ b/target/cris/cpu.c
167
@@ -XXX,XX +XXX,XX @@ static void cris_cpu_set_pc(CPUState *cs, vaddr value)
168
cpu->env.pc = value;
169
}
58
}
170
59
171
+static vaddr cris_cpu_get_pc(CPUState *cs)
60
+/* Used only by tcg infrastructure: tcg-op.c or plugin-gen.c */
61
+static inline TCGv_ptr tcg_temp_ebb_new_ptr(void)
172
+{
62
+{
173
+ CRISCPU *cpu = CRIS_CPU(cs);
63
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_EBB);
174
+
64
+ return temp_tcgv_ptr(t);
175
+ return cpu->env.pc;
176
+}
65
+}
177
+
66
+
178
static bool cris_cpu_has_work(CPUState *cs)
67
static inline TCGv_ptr tcg_temp_new_ptr(void)
179
{
68
{
180
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
69
TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_EBB);
181
@@ -XXX,XX +XXX,XX @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
182
cc->has_work = cris_cpu_has_work;
183
cc->dump_state = cris_cpu_dump_state;
184
cc->set_pc = cris_cpu_set_pc;
185
+ cc->get_pc = cris_cpu_get_pc;
186
cc->gdb_read_register = cris_cpu_gdb_read_register;
187
cc->gdb_write_register = cris_cpu_gdb_write_register;
188
#ifndef CONFIG_USER_ONLY
189
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
190
index XXXXXXX..XXXXXXX 100644
191
--- a/target/hexagon/cpu.c
192
+++ b/target/hexagon/cpu.c
193
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_set_pc(CPUState *cs, vaddr value)
194
env->gpr[HEX_REG_PC] = value;
195
}
196
197
+static vaddr hexagon_cpu_get_pc(CPUState *cs)
198
+{
199
+ HexagonCPU *cpu = HEXAGON_CPU(cs);
200
+ CPUHexagonState *env = &cpu->env;
201
+ return env->gpr[HEX_REG_PC];
202
+}
203
+
204
static void hexagon_cpu_synchronize_from_tb(CPUState *cs,
205
const TranslationBlock *tb)
206
{
207
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_class_init(ObjectClass *c, void *data)
208
cc->has_work = hexagon_cpu_has_work;
209
cc->dump_state = hexagon_dump_state;
210
cc->set_pc = hexagon_cpu_set_pc;
211
+ cc->get_pc = hexagon_cpu_get_pc;
212
cc->gdb_read_register = hexagon_gdb_read_register;
213
cc->gdb_write_register = hexagon_gdb_write_register;
214
cc->gdb_num_core_regs = TOTAL_PER_THREAD_REGS + NUM_VREGS + NUM_QREGS;
215
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/target/hppa/cpu.c
218
+++ b/target/hppa/cpu.c
219
@@ -XXX,XX +XXX,XX @@ static void hppa_cpu_set_pc(CPUState *cs, vaddr value)
220
cpu->env.iaoq_b = value + 4;
221
}
222
223
+static vaddr hppa_cpu_get_pc(CPUState *cs)
224
+{
225
+ HPPACPU *cpu = HPPA_CPU(cs);
226
+
227
+ return cpu->env.iaoq_f;
228
+}
229
+
230
static void hppa_cpu_synchronize_from_tb(CPUState *cs,
231
const TranslationBlock *tb)
232
{
233
@@ -XXX,XX +XXX,XX @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
234
cc->has_work = hppa_cpu_has_work;
235
cc->dump_state = hppa_cpu_dump_state;
236
cc->set_pc = hppa_cpu_set_pc;
237
+ cc->get_pc = hppa_cpu_get_pc;
238
cc->gdb_read_register = hppa_cpu_gdb_read_register;
239
cc->gdb_write_register = hppa_cpu_gdb_write_register;
240
#ifndef CONFIG_USER_ONLY
241
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
242
index XXXXXXX..XXXXXXX 100644
243
--- a/target/i386/cpu.c
244
+++ b/target/i386/cpu.c
245
@@ -XXX,XX +XXX,XX @@ static void x86_cpu_set_pc(CPUState *cs, vaddr value)
246
cpu->env.eip = value;
247
}
248
249
+static vaddr x86_cpu_get_pc(CPUState *cs)
250
+{
251
+ X86CPU *cpu = X86_CPU(cs);
252
+
253
+ /* Match cpu_get_tb_cpu_state. */
254
+ return cpu->env.eip + cpu->env.segs[R_CS].base;
255
+}
256
+
257
int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request)
258
{
259
X86CPU *cpu = X86_CPU(cs);
260
@@ -XXX,XX +XXX,XX @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
261
cc->has_work = x86_cpu_has_work;
262
cc->dump_state = x86_cpu_dump_state;
263
cc->set_pc = x86_cpu_set_pc;
264
+ cc->get_pc = x86_cpu_get_pc;
265
cc->gdb_read_register = x86_cpu_gdb_read_register;
266
cc->gdb_write_register = x86_cpu_gdb_write_register;
267
cc->get_arch_id = x86_cpu_get_arch_id;
268
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
269
index XXXXXXX..XXXXXXX 100644
270
--- a/target/loongarch/cpu.c
271
+++ b/target/loongarch/cpu.c
272
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
273
env->pc = value;
274
}
275
276
+static vaddr loongarch_cpu_get_pc(CPUState *cs)
277
+{
278
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
279
+ CPULoongArchState *env = &cpu->env;
280
+
281
+ return env->pc;
282
+}
283
+
284
#ifndef CONFIG_USER_ONLY
285
#include "hw/loongarch/virt.h"
286
287
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
288
cc->has_work = loongarch_cpu_has_work;
289
cc->dump_state = loongarch_cpu_dump_state;
290
cc->set_pc = loongarch_cpu_set_pc;
291
+ cc->get_pc = loongarch_cpu_get_pc;
292
#ifndef CONFIG_USER_ONLY
293
dc->vmsd = &vmstate_loongarch_cpu;
294
cc->sysemu_ops = &loongarch_sysemu_ops;
295
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
296
index XXXXXXX..XXXXXXX 100644
297
--- a/target/m68k/cpu.c
298
+++ b/target/m68k/cpu.c
299
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_set_pc(CPUState *cs, vaddr value)
300
cpu->env.pc = value;
301
}
302
303
+static vaddr m68k_cpu_get_pc(CPUState *cs)
304
+{
305
+ M68kCPU *cpu = M68K_CPU(cs);
306
+
307
+ return cpu->env.pc;
308
+}
309
+
310
static bool m68k_cpu_has_work(CPUState *cs)
311
{
312
return cs->interrupt_request & CPU_INTERRUPT_HARD;
313
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
314
cc->has_work = m68k_cpu_has_work;
315
cc->dump_state = m68k_cpu_dump_state;
316
cc->set_pc = m68k_cpu_set_pc;
317
+ cc->get_pc = m68k_cpu_get_pc;
318
cc->gdb_read_register = m68k_cpu_gdb_read_register;
319
cc->gdb_write_register = m68k_cpu_gdb_write_register;
320
#if defined(CONFIG_SOFTMMU)
321
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
322
index XXXXXXX..XXXXXXX 100644
323
--- a/target/microblaze/cpu.c
324
+++ b/target/microblaze/cpu.c
325
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_set_pc(CPUState *cs, vaddr value)
326
cpu->env.iflags = 0;
327
}
328
329
+static vaddr mb_cpu_get_pc(CPUState *cs)
330
+{
331
+ MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
332
+
333
+ return cpu->env.pc;
334
+}
335
+
336
static void mb_cpu_synchronize_from_tb(CPUState *cs,
337
const TranslationBlock *tb)
338
{
339
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
340
341
cc->dump_state = mb_cpu_dump_state;
342
cc->set_pc = mb_cpu_set_pc;
343
+ cc->get_pc = mb_cpu_get_pc;
344
cc->gdb_read_register = mb_cpu_gdb_read_register;
345
cc->gdb_write_register = mb_cpu_gdb_write_register;
346
347
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
348
index XXXXXXX..XXXXXXX 100644
349
--- a/target/mips/cpu.c
350
+++ b/target/mips/cpu.c
351
@@ -XXX,XX +XXX,XX @@ static void mips_cpu_set_pc(CPUState *cs, vaddr value)
352
mips_env_set_pc(&cpu->env, value);
353
}
354
355
+static vaddr mips_cpu_get_pc(CPUState *cs)
356
+{
357
+ MIPSCPU *cpu = MIPS_CPU(cs);
358
+
359
+ return cpu->env.active_tc.PC;
360
+}
361
+
362
static bool mips_cpu_has_work(CPUState *cs)
363
{
364
MIPSCPU *cpu = MIPS_CPU(cs);
365
@@ -XXX,XX +XXX,XX @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
366
cc->has_work = mips_cpu_has_work;
367
cc->dump_state = mips_cpu_dump_state;
368
cc->set_pc = mips_cpu_set_pc;
369
+ cc->get_pc = mips_cpu_get_pc;
370
cc->gdb_read_register = mips_cpu_gdb_read_register;
371
cc->gdb_write_register = mips_cpu_gdb_write_register;
372
#ifndef CONFIG_USER_ONLY
373
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
374
index XXXXXXX..XXXXXXX 100644
375
--- a/target/nios2/cpu.c
376
+++ b/target/nios2/cpu.c
377
@@ -XXX,XX +XXX,XX @@ static void nios2_cpu_set_pc(CPUState *cs, vaddr value)
378
env->pc = value;
379
}
380
381
+static vaddr nios2_cpu_get_pc(CPUState *cs)
382
+{
383
+ Nios2CPU *cpu = NIOS2_CPU(cs);
384
+ CPUNios2State *env = &cpu->env;
385
+
386
+ return env->pc;
387
+}
388
+
389
static bool nios2_cpu_has_work(CPUState *cs)
390
{
391
return cs->interrupt_request & CPU_INTERRUPT_HARD;
392
@@ -XXX,XX +XXX,XX @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
393
cc->has_work = nios2_cpu_has_work;
394
cc->dump_state = nios2_cpu_dump_state;
395
cc->set_pc = nios2_cpu_set_pc;
396
+ cc->get_pc = nios2_cpu_get_pc;
397
cc->disas_set_info = nios2_cpu_disas_set_info;
398
#ifndef CONFIG_USER_ONLY
399
cc->sysemu_ops = &nios2_sysemu_ops;
400
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
401
index XXXXXXX..XXXXXXX 100644
402
--- a/target/openrisc/cpu.c
403
+++ b/target/openrisc/cpu.c
404
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
405
cpu->env.dflag = 0;
406
}
407
408
+static vaddr openrisc_cpu_get_pc(CPUState *cs)
409
+{
410
+ OpenRISCCPU *cpu = OPENRISC_CPU(cs);
411
+
412
+ return cpu->env.pc;
413
+}
414
+
415
static void openrisc_cpu_synchronize_from_tb(CPUState *cs,
416
const TranslationBlock *tb)
417
{
418
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
419
cc->has_work = openrisc_cpu_has_work;
420
cc->dump_state = openrisc_cpu_dump_state;
421
cc->set_pc = openrisc_cpu_set_pc;
422
+ cc->get_pc = openrisc_cpu_get_pc;
423
cc->gdb_read_register = openrisc_cpu_gdb_read_register;
424
cc->gdb_write_register = openrisc_cpu_gdb_write_register;
425
#ifndef CONFIG_USER_ONLY
426
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
427
index XXXXXXX..XXXXXXX 100644
428
--- a/target/ppc/cpu_init.c
429
+++ b/target/ppc/cpu_init.c
430
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
431
cpu->env.nip = value;
432
}
433
434
+static vaddr ppc_cpu_get_pc(CPUState *cs)
435
+{
436
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
437
+
438
+ return cpu->env.nip;
439
+}
440
+
441
static bool ppc_cpu_has_work(CPUState *cs)
442
{
443
PowerPCCPU *cpu = POWERPC_CPU(cs);
444
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
445
cc->has_work = ppc_cpu_has_work;
446
cc->dump_state = ppc_cpu_dump_state;
447
cc->set_pc = ppc_cpu_set_pc;
448
+ cc->get_pc = ppc_cpu_get_pc;
449
cc->gdb_read_register = ppc_cpu_gdb_read_register;
450
cc->gdb_write_register = ppc_cpu_gdb_write_register;
451
#ifndef CONFIG_USER_ONLY
452
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
453
index XXXXXXX..XXXXXXX 100644
454
--- a/target/riscv/cpu.c
455
+++ b/target/riscv/cpu.c
456
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
457
}
458
}
459
460
+static vaddr riscv_cpu_get_pc(CPUState *cs)
461
+{
462
+ RISCVCPU *cpu = RISCV_CPU(cs);
463
+ CPURISCVState *env = &cpu->env;
464
+
465
+ /* Match cpu_get_tb_cpu_state. */
466
+ if (env->xl == MXL_RV32) {
467
+ return env->pc & UINT32_MAX;
468
+ }
469
+ return env->pc;
470
+}
471
+
472
static void riscv_cpu_synchronize_from_tb(CPUState *cs,
473
const TranslationBlock *tb)
474
{
475
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
476
cc->has_work = riscv_cpu_has_work;
477
cc->dump_state = riscv_cpu_dump_state;
478
cc->set_pc = riscv_cpu_set_pc;
479
+ cc->get_pc = riscv_cpu_get_pc;
480
cc->gdb_read_register = riscv_cpu_gdb_read_register;
481
cc->gdb_write_register = riscv_cpu_gdb_write_register;
482
cc->gdb_num_core_regs = 33;
483
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
484
index XXXXXXX..XXXXXXX 100644
485
--- a/target/rx/cpu.c
486
+++ b/target/rx/cpu.c
487
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_set_pc(CPUState *cs, vaddr value)
488
cpu->env.pc = value;
489
}
490
491
+static vaddr rx_cpu_get_pc(CPUState *cs)
492
+{
493
+ RXCPU *cpu = RX_CPU(cs);
494
+
495
+ return cpu->env.pc;
496
+}
497
+
498
static void rx_cpu_synchronize_from_tb(CPUState *cs,
499
const TranslationBlock *tb)
500
{
501
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
502
cc->has_work = rx_cpu_has_work;
503
cc->dump_state = rx_cpu_dump_state;
504
cc->set_pc = rx_cpu_set_pc;
505
+ cc->get_pc = rx_cpu_get_pc;
506
507
#ifndef CONFIG_USER_ONLY
508
cc->sysemu_ops = &rx_sysemu_ops;
509
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
510
index XXXXXXX..XXXXXXX 100644
511
--- a/target/s390x/cpu.c
512
+++ b/target/s390x/cpu.c
513
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_set_pc(CPUState *cs, vaddr value)
514
cpu->env.psw.addr = value;
515
}
516
517
+static vaddr s390_cpu_get_pc(CPUState *cs)
518
+{
519
+ S390CPU *cpu = S390_CPU(cs);
520
+
521
+ return cpu->env.psw.addr;
522
+}
523
+
524
static bool s390_cpu_has_work(CPUState *cs)
525
{
526
S390CPU *cpu = S390_CPU(cs);
527
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
528
cc->has_work = s390_cpu_has_work;
529
cc->dump_state = s390_cpu_dump_state;
530
cc->set_pc = s390_cpu_set_pc;
531
+ cc->get_pc = s390_cpu_get_pc;
532
cc->gdb_read_register = s390_cpu_gdb_read_register;
533
cc->gdb_write_register = s390_cpu_gdb_write_register;
534
#ifndef CONFIG_USER_ONLY
535
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
536
index XXXXXXX..XXXXXXX 100644
537
--- a/target/sh4/cpu.c
538
+++ b/target/sh4/cpu.c
539
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_set_pc(CPUState *cs, vaddr value)
540
cpu->env.pc = value;
541
}
542
543
+static vaddr superh_cpu_get_pc(CPUState *cs)
544
+{
545
+ SuperHCPU *cpu = SUPERH_CPU(cs);
546
+
547
+ return cpu->env.pc;
548
+}
549
+
550
static void superh_cpu_synchronize_from_tb(CPUState *cs,
551
const TranslationBlock *tb)
552
{
553
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
554
cc->has_work = superh_cpu_has_work;
555
cc->dump_state = superh_cpu_dump_state;
556
cc->set_pc = superh_cpu_set_pc;
557
+ cc->get_pc = superh_cpu_get_pc;
558
cc->gdb_read_register = superh_cpu_gdb_read_register;
559
cc->gdb_write_register = superh_cpu_gdb_write_register;
560
#ifndef CONFIG_USER_ONLY
561
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
562
index XXXXXXX..XXXXXXX 100644
563
--- a/target/sparc/cpu.c
564
+++ b/target/sparc/cpu.c
565
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_set_pc(CPUState *cs, vaddr value)
566
cpu->env.npc = value + 4;
567
}
568
569
+static vaddr sparc_cpu_get_pc(CPUState *cs)
570
+{
571
+ SPARCCPU *cpu = SPARC_CPU(cs);
572
+
573
+ return cpu->env.pc;
574
+}
575
+
576
static void sparc_cpu_synchronize_from_tb(CPUState *cs,
577
const TranslationBlock *tb)
578
{
579
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
580
cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
581
#endif
582
cc->set_pc = sparc_cpu_set_pc;
583
+ cc->get_pc = sparc_cpu_get_pc;
584
cc->gdb_read_register = sparc_cpu_gdb_read_register;
585
cc->gdb_write_register = sparc_cpu_gdb_write_register;
586
#ifndef CONFIG_USER_ONLY
587
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
588
index XXXXXXX..XXXXXXX 100644
589
--- a/target/tricore/cpu.c
590
+++ b/target/tricore/cpu.c
591
@@ -XXX,XX +XXX,XX @@ static void tricore_cpu_set_pc(CPUState *cs, vaddr value)
592
env->PC = value & ~(target_ulong)1;
593
}
594
595
+static vaddr tricore_cpu_get_pc(CPUState *cs)
596
+{
597
+ TriCoreCPU *cpu = TRICORE_CPU(cs);
598
+ CPUTriCoreState *env = &cpu->env;
599
+
600
+ return env->PC;
601
+}
602
+
603
static void tricore_cpu_synchronize_from_tb(CPUState *cs,
604
const TranslationBlock *tb)
605
{
606
@@ -XXX,XX +XXX,XX @@ static void tricore_cpu_class_init(ObjectClass *c, void *data)
607
608
cc->dump_state = tricore_cpu_dump_state;
609
cc->set_pc = tricore_cpu_set_pc;
610
+ cc->get_pc = tricore_cpu_get_pc;
611
cc->sysemu_ops = &tricore_sysemu_ops;
612
cc->tcg_ops = &tricore_tcg_ops;
613
}
614
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
615
index XXXXXXX..XXXXXXX 100644
616
--- a/target/xtensa/cpu.c
617
+++ b/target/xtensa/cpu.c
618
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_set_pc(CPUState *cs, vaddr value)
619
cpu->env.pc = value;
620
}
621
622
+static vaddr xtensa_cpu_get_pc(CPUState *cs)
623
+{
624
+ XtensaCPU *cpu = XTENSA_CPU(cs);
625
+
626
+ return cpu->env.pc;
627
+}
628
+
629
static bool xtensa_cpu_has_work(CPUState *cs)
630
{
631
#ifndef CONFIG_USER_ONLY
632
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
633
cc->has_work = xtensa_cpu_has_work;
634
cc->dump_state = xtensa_cpu_dump_state;
635
cc->set_pc = xtensa_cpu_set_pc;
636
+ cc->get_pc = xtensa_cpu_get_pc;
637
cc->gdb_read_register = xtensa_cpu_gdb_read_register;
638
cc->gdb_write_register = xtensa_cpu_gdb_write_register;
639
cc->gdb_stop_before_watchpoint = true;
640
--
70
--
641
2.34.1
71
2.34.1
642
72
643
73
diff view generated by jsdifflib
New patch
1
All of these have obvious and quite local scope.
1
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/tcg-op-gvec.c | 186 ++++++++++++++++-----------------
7
tcg/tcg-op.c | 258 +++++++++++++++++++++++-----------------------
8
tcg/tcg.c | 2 +-
9
3 files changed, 223 insertions(+), 223 deletions(-)
10
11
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/tcg-op-gvec.c
14
+++ b/tcg/tcg-op-gvec.c
15
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_2_ool(uint32_t dofs, uint32_t aofs,
16
TCGv_ptr a0, a1;
17
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
18
19
- a0 = tcg_temp_new_ptr();
20
- a1 = tcg_temp_new_ptr();
21
+ a0 = tcg_temp_ebb_new_ptr();
22
+ a1 = tcg_temp_ebb_new_ptr();
23
24
tcg_gen_addi_ptr(a0, cpu_env, dofs);
25
tcg_gen_addi_ptr(a1, cpu_env, aofs);
26
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_2i_ool(uint32_t dofs, uint32_t aofs, TCGv_i64 c,
27
TCGv_ptr a0, a1;
28
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
29
30
- a0 = tcg_temp_new_ptr();
31
- a1 = tcg_temp_new_ptr();
32
+ a0 = tcg_temp_ebb_new_ptr();
33
+ a1 = tcg_temp_ebb_new_ptr();
34
35
tcg_gen_addi_ptr(a0, cpu_env, dofs);
36
tcg_gen_addi_ptr(a1, cpu_env, aofs);
37
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_3_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
38
TCGv_ptr a0, a1, a2;
39
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
40
41
- a0 = tcg_temp_new_ptr();
42
- a1 = tcg_temp_new_ptr();
43
- a2 = tcg_temp_new_ptr();
44
+ a0 = tcg_temp_ebb_new_ptr();
45
+ a1 = tcg_temp_ebb_new_ptr();
46
+ a2 = tcg_temp_ebb_new_ptr();
47
48
tcg_gen_addi_ptr(a0, cpu_env, dofs);
49
tcg_gen_addi_ptr(a1, cpu_env, aofs);
50
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_4_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
51
TCGv_ptr a0, a1, a2, a3;
52
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
53
54
- a0 = tcg_temp_new_ptr();
55
- a1 = tcg_temp_new_ptr();
56
- a2 = tcg_temp_new_ptr();
57
- a3 = tcg_temp_new_ptr();
58
+ a0 = tcg_temp_ebb_new_ptr();
59
+ a1 = tcg_temp_ebb_new_ptr();
60
+ a2 = tcg_temp_ebb_new_ptr();
61
+ a3 = tcg_temp_ebb_new_ptr();
62
63
tcg_gen_addi_ptr(a0, cpu_env, dofs);
64
tcg_gen_addi_ptr(a1, cpu_env, aofs);
65
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_5_ool(uint32_t dofs, uint32_t aofs, uint32_t bofs,
66
TCGv_ptr a0, a1, a2, a3, a4;
67
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
68
69
- a0 = tcg_temp_new_ptr();
70
- a1 = tcg_temp_new_ptr();
71
- a2 = tcg_temp_new_ptr();
72
- a3 = tcg_temp_new_ptr();
73
- a4 = tcg_temp_new_ptr();
74
+ a0 = tcg_temp_ebb_new_ptr();
75
+ a1 = tcg_temp_ebb_new_ptr();
76
+ a2 = tcg_temp_ebb_new_ptr();
77
+ a3 = tcg_temp_ebb_new_ptr();
78
+ a4 = tcg_temp_ebb_new_ptr();
79
80
tcg_gen_addi_ptr(a0, cpu_env, dofs);
81
tcg_gen_addi_ptr(a1, cpu_env, aofs);
82
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_2_ptr(uint32_t dofs, uint32_t aofs,
83
TCGv_ptr a0, a1;
84
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
85
86
- a0 = tcg_temp_new_ptr();
87
- a1 = tcg_temp_new_ptr();
88
+ a0 = tcg_temp_ebb_new_ptr();
89
+ a1 = tcg_temp_ebb_new_ptr();
90
91
tcg_gen_addi_ptr(a0, cpu_env, dofs);
92
tcg_gen_addi_ptr(a1, cpu_env, aofs);
93
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_3_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
94
TCGv_ptr a0, a1, a2;
95
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
96
97
- a0 = tcg_temp_new_ptr();
98
- a1 = tcg_temp_new_ptr();
99
- a2 = tcg_temp_new_ptr();
100
+ a0 = tcg_temp_ebb_new_ptr();
101
+ a1 = tcg_temp_ebb_new_ptr();
102
+ a2 = tcg_temp_ebb_new_ptr();
103
104
tcg_gen_addi_ptr(a0, cpu_env, dofs);
105
tcg_gen_addi_ptr(a1, cpu_env, aofs);
106
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_4_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
107
TCGv_ptr a0, a1, a2, a3;
108
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
109
110
- a0 = tcg_temp_new_ptr();
111
- a1 = tcg_temp_new_ptr();
112
- a2 = tcg_temp_new_ptr();
113
- a3 = tcg_temp_new_ptr();
114
+ a0 = tcg_temp_ebb_new_ptr();
115
+ a1 = tcg_temp_ebb_new_ptr();
116
+ a2 = tcg_temp_ebb_new_ptr();
117
+ a3 = tcg_temp_ebb_new_ptr();
118
119
tcg_gen_addi_ptr(a0, cpu_env, dofs);
120
tcg_gen_addi_ptr(a1, cpu_env, aofs);
121
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_5_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
122
TCGv_ptr a0, a1, a2, a3, a4;
123
TCGv_i32 desc = tcg_constant_i32(simd_desc(oprsz, maxsz, data));
124
125
- a0 = tcg_temp_new_ptr();
126
- a1 = tcg_temp_new_ptr();
127
- a2 = tcg_temp_new_ptr();
128
- a3 = tcg_temp_new_ptr();
129
- a4 = tcg_temp_new_ptr();
130
+ a0 = tcg_temp_ebb_new_ptr();
131
+ a1 = tcg_temp_ebb_new_ptr();
132
+ a2 = tcg_temp_ebb_new_ptr();
133
+ a3 = tcg_temp_ebb_new_ptr();
134
+ a4 = tcg_temp_ebb_new_ptr();
135
136
tcg_gen_addi_ptr(a0, cpu_env, dofs);
137
tcg_gen_addi_ptr(a1, cpu_env, aofs);
138
@@ -XXX,XX +XXX,XX @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz,
139
be simple enough. */
140
if (TCG_TARGET_REG_BITS == 64
141
&& (vece != MO_32 || !check_size_impl(oprsz, 4))) {
142
- t_64 = tcg_temp_new_i64();
143
+ t_64 = tcg_temp_ebb_new_i64();
144
tcg_gen_extu_i32_i64(t_64, in_32);
145
tcg_gen_dup_i64(vece, t_64, t_64);
146
} else {
147
- t_32 = tcg_temp_new_i32();
148
+ t_32 = tcg_temp_ebb_new_i32();
149
tcg_gen_dup_i32(vece, t_32, in_32);
150
}
151
} else if (in_64) {
152
/* We are given a 64-bit variable input. */
153
- t_64 = tcg_temp_new_i64();
154
+ t_64 = tcg_temp_ebb_new_i64();
155
tcg_gen_dup_i64(vece, t_64, in_64);
156
} else {
157
/* We are given a constant input. */
158
@@ -XXX,XX +XXX,XX @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz,
159
}
160
161
/* Otherwise implement out of line. */
162
- t_ptr = tcg_temp_new_ptr();
163
+ t_ptr = tcg_temp_ebb_new_ptr();
164
tcg_gen_addi_ptr(t_ptr, cpu_env, dofs);
165
166
/*
167
@@ -XXX,XX +XXX,XX @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz,
168
if (in_32) {
169
t_val = in_32;
170
} else if (in_64) {
171
- t_val = tcg_temp_new_i32();
172
+ t_val = tcg_temp_ebb_new_i32();
173
tcg_gen_extrl_i64_i32(t_val, in_64);
174
} else {
175
t_val = tcg_constant_i32(in_c);
176
@@ -XXX,XX +XXX,XX @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz,
177
if (in_32) {
178
fns[vece](t_ptr, t_desc, in_32);
179
} else if (in_64) {
180
- t_32 = tcg_temp_new_i32();
181
+ t_32 = tcg_temp_ebb_new_i32();
182
tcg_gen_extrl_i64_i32(t_32, in_64);
183
fns[vece](t_ptr, t_desc, t_32);
184
tcg_temp_free_i32(t_32);
185
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, uint32_t aofs,
186
do_dup_store(type, dofs, oprsz, maxsz, t_vec);
187
tcg_temp_free_vec(t_vec);
188
} else if (vece <= MO_32) {
189
- TCGv_i32 in = tcg_temp_new_i32();
190
+ TCGv_i32 in = tcg_temp_ebb_new_i32();
191
switch (vece) {
192
case MO_8:
193
tcg_gen_ld8u_i32(in, cpu_env, aofs);
194
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, uint32_t aofs,
195
do_dup(vece, dofs, oprsz, maxsz, in, NULL, 0);
196
tcg_temp_free_i32(in);
197
} else {
198
- TCGv_i64 in = tcg_temp_new_i64();
199
+ TCGv_i64 in = tcg_temp_ebb_new_i64();
200
tcg_gen_ld_i64(in, cpu_env, aofs);
201
do_dup(vece, dofs, oprsz, maxsz, NULL, in, 0);
202
tcg_temp_free_i64(in);
203
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, uint32_t aofs,
204
}
205
tcg_temp_free_vec(in);
206
} else {
207
- TCGv_i64 in0 = tcg_temp_new_i64();
208
- TCGv_i64 in1 = tcg_temp_new_i64();
209
+ TCGv_i64 in0 = tcg_temp_ebb_new_i64();
210
+ TCGv_i64 in1 = tcg_temp_ebb_new_i64();
211
212
tcg_gen_ld_i64(in0, cpu_env, aofs);
213
tcg_gen_ld_i64(in1, cpu_env, aofs + 8);
214
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, uint32_t aofs,
215
int j;
216
217
for (j = 0; j < 4; ++j) {
218
- in[j] = tcg_temp_new_i64();
219
+ in[j] = tcg_temp_ebb_new_i64();
220
tcg_gen_ld_i64(in[j], cpu_env, aofs + j * 8);
221
}
222
for (i = (aofs == dofs) * 32; i < oprsz; i += 32) {
223
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_not(unsigned vece, uint32_t dofs, uint32_t aofs,
224
the 64-bit operation. */
225
static void gen_addv_mask(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b, TCGv_i64 m)
226
{
227
- TCGv_i64 t1 = tcg_temp_new_i64();
228
- TCGv_i64 t2 = tcg_temp_new_i64();
229
- TCGv_i64 t3 = tcg_temp_new_i64();
230
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
231
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
232
+ TCGv_i64 t3 = tcg_temp_ebb_new_i64();
233
234
tcg_gen_andc_i64(t1, a, m);
235
tcg_gen_andc_i64(t2, b, m);
236
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_add8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
237
void tcg_gen_vec_add8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
238
{
239
TCGv_i32 m = tcg_constant_i32((int32_t)dup_const(MO_8, 0x80));
240
- TCGv_i32 t1 = tcg_temp_new_i32();
241
- TCGv_i32 t2 = tcg_temp_new_i32();
242
- TCGv_i32 t3 = tcg_temp_new_i32();
243
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
244
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
245
+ TCGv_i32 t3 = tcg_temp_ebb_new_i32();
246
247
tcg_gen_andc_i32(t1, a, m);
248
tcg_gen_andc_i32(t2, b, m);
249
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_add16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
250
251
void tcg_gen_vec_add16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
252
{
253
- TCGv_i32 t1 = tcg_temp_new_i32();
254
- TCGv_i32 t2 = tcg_temp_new_i32();
255
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
256
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
257
258
tcg_gen_andi_i32(t1, a, ~0xffff);
259
tcg_gen_add_i32(t2, a, b);
260
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_add16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
261
262
void tcg_gen_vec_add32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
263
{
264
- TCGv_i64 t1 = tcg_temp_new_i64();
265
- TCGv_i64 t2 = tcg_temp_new_i64();
266
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
267
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
268
269
tcg_gen_andi_i64(t1, a, ~0xffffffffull);
270
tcg_gen_add_i64(t2, a, b);
271
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_subs(unsigned vece, uint32_t dofs, uint32_t aofs,
272
Compare gen_addv_mask above. */
273
static void gen_subv_mask(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b, TCGv_i64 m)
274
{
275
- TCGv_i64 t1 = tcg_temp_new_i64();
276
- TCGv_i64 t2 = tcg_temp_new_i64();
277
- TCGv_i64 t3 = tcg_temp_new_i64();
278
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
279
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
280
+ TCGv_i64 t3 = tcg_temp_ebb_new_i64();
281
282
tcg_gen_or_i64(t1, a, m);
283
tcg_gen_andc_i64(t2, b, m);
284
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_sub8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
285
void tcg_gen_vec_sub8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
286
{
287
TCGv_i32 m = tcg_constant_i32((int32_t)dup_const(MO_8, 0x80));
288
- TCGv_i32 t1 = tcg_temp_new_i32();
289
- TCGv_i32 t2 = tcg_temp_new_i32();
290
- TCGv_i32 t3 = tcg_temp_new_i32();
291
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
292
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
293
+ TCGv_i32 t3 = tcg_temp_ebb_new_i32();
294
295
tcg_gen_or_i32(t1, a, m);
296
tcg_gen_andc_i32(t2, b, m);
297
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_sub16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
298
299
void tcg_gen_vec_sub16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
300
{
301
- TCGv_i32 t1 = tcg_temp_new_i32();
302
- TCGv_i32 t2 = tcg_temp_new_i32();
303
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
304
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
305
306
tcg_gen_andi_i32(t1, b, ~0xffff);
307
tcg_gen_sub_i32(t2, a, b);
308
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_sub16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
309
310
void tcg_gen_vec_sub32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
311
{
312
- TCGv_i64 t1 = tcg_temp_new_i64();
313
- TCGv_i64 t2 = tcg_temp_new_i64();
314
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
315
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
316
317
tcg_gen_andi_i64(t1, b, ~0xffffffffull);
318
tcg_gen_sub_i64(t2, a, b);
319
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_umax(unsigned vece, uint32_t dofs, uint32_t aofs,
320
Compare gen_subv_mask above. */
321
static void gen_negv_mask(TCGv_i64 d, TCGv_i64 b, TCGv_i64 m)
322
{
323
- TCGv_i64 t2 = tcg_temp_new_i64();
324
- TCGv_i64 t3 = tcg_temp_new_i64();
325
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
326
+ TCGv_i64 t3 = tcg_temp_ebb_new_i64();
327
328
tcg_gen_andc_i64(t3, m, b);
329
tcg_gen_andc_i64(t2, b, m);
330
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_neg16_i64(TCGv_i64 d, TCGv_i64 b)
331
332
void tcg_gen_vec_neg32_i64(TCGv_i64 d, TCGv_i64 b)
333
{
334
- TCGv_i64 t1 = tcg_temp_new_i64();
335
- TCGv_i64 t2 = tcg_temp_new_i64();
336
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
337
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
338
339
tcg_gen_andi_i64(t1, b, ~0xffffffffull);
340
tcg_gen_neg_i64(t2, b);
341
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_neg(unsigned vece, uint32_t dofs, uint32_t aofs,
342
343
static void gen_absv_mask(TCGv_i64 d, TCGv_i64 b, unsigned vece)
344
{
345
- TCGv_i64 t = tcg_temp_new_i64();
346
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
347
int nbit = 8 << vece;
348
349
/* Create -1 for each negative element. */
350
@@ -XXX,XX +XXX,XX @@ static const GVecGen2s gop_ands = {
351
void tcg_gen_gvec_ands(unsigned vece, uint32_t dofs, uint32_t aofs,
352
TCGv_i64 c, uint32_t oprsz, uint32_t maxsz)
353
{
354
- TCGv_i64 tmp = tcg_temp_new_i64();
355
+ TCGv_i64 tmp = tcg_temp_ebb_new_i64();
356
tcg_gen_dup_i64(vece, tmp, c);
357
tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, tmp, &gop_ands);
358
tcg_temp_free_i64(tmp);
359
@@ -XXX,XX +XXX,XX @@ static const GVecGen2s gop_xors = {
360
void tcg_gen_gvec_xors(unsigned vece, uint32_t dofs, uint32_t aofs,
361
TCGv_i64 c, uint32_t oprsz, uint32_t maxsz)
362
{
363
- TCGv_i64 tmp = tcg_temp_new_i64();
364
+ TCGv_i64 tmp = tcg_temp_ebb_new_i64();
365
tcg_gen_dup_i64(vece, tmp, c);
366
tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, tmp, &gop_xors);
367
tcg_temp_free_i64(tmp);
368
@@ -XXX,XX +XXX,XX @@ static const GVecGen2s gop_ors = {
369
void tcg_gen_gvec_ors(unsigned vece, uint32_t dofs, uint32_t aofs,
370
TCGv_i64 c, uint32_t oprsz, uint32_t maxsz)
371
{
372
- TCGv_i64 tmp = tcg_temp_new_i64();
373
+ TCGv_i64 tmp = tcg_temp_ebb_new_i64();
374
tcg_gen_dup_i64(vece, tmp, c);
375
tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, tmp, &gop_ors);
376
tcg_temp_free_i64(tmp);
377
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_sar8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t c)
378
{
379
uint64_t s_mask = dup_const(MO_8, 0x80 >> c);
380
uint64_t c_mask = dup_const(MO_8, 0xff >> c);
381
- TCGv_i64 s = tcg_temp_new_i64();
382
+ TCGv_i64 s = tcg_temp_ebb_new_i64();
383
384
tcg_gen_shri_i64(d, a, c);
385
tcg_gen_andi_i64(s, d, s_mask); /* isolate (shifted) sign bit */
386
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_sar16i_i64(TCGv_i64 d, TCGv_i64 a, int64_t c)
387
{
388
uint64_t s_mask = dup_const(MO_16, 0x8000 >> c);
389
uint64_t c_mask = dup_const(MO_16, 0xffff >> c);
390
- TCGv_i64 s = tcg_temp_new_i64();
391
+ TCGv_i64 s = tcg_temp_ebb_new_i64();
392
393
tcg_gen_shri_i64(d, a, c);
394
tcg_gen_andi_i64(s, d, s_mask); /* isolate (shifted) sign bit */
395
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_sar8i_i32(TCGv_i32 d, TCGv_i32 a, int32_t c)
396
{
397
uint32_t s_mask = dup_const(MO_8, 0x80 >> c);
398
uint32_t c_mask = dup_const(MO_8, 0xff >> c);
399
- TCGv_i32 s = tcg_temp_new_i32();
400
+ TCGv_i32 s = tcg_temp_ebb_new_i32();
401
402
tcg_gen_shri_i32(d, a, c);
403
tcg_gen_andi_i32(s, d, s_mask); /* isolate (shifted) sign bit */
404
@@ -XXX,XX +XXX,XX @@ void tcg_gen_vec_sar16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t c)
405
{
406
uint32_t s_mask = dup_const(MO_16, 0x8000 >> c);
407
uint32_t c_mask = dup_const(MO_16, 0xffff >> c);
408
- TCGv_i32 s = tcg_temp_new_i32();
409
+ TCGv_i32 s = tcg_temp_ebb_new_i32();
410
411
tcg_gen_shri_i32(d, a, c);
412
tcg_gen_andi_i32(s, d, s_mask); /* isolate (shifted) sign bit */
413
@@ -XXX,XX +XXX,XX @@ do_gvec_shifts(unsigned vece, uint32_t dofs, uint32_t aofs, TCGv_i32 shift,
414
TCGv_vec v_shift = tcg_temp_new_vec(type);
415
416
if (vece == MO_64) {
417
- TCGv_i64 sh64 = tcg_temp_new_i64();
418
+ TCGv_i64 sh64 = tcg_temp_ebb_new_i64();
419
tcg_gen_extu_i32_i64(sh64, shift);
420
tcg_gen_dup_i64_vec(MO_64, v_shift, sh64);
421
tcg_temp_free_i64(sh64);
422
@@ -XXX,XX +XXX,XX @@ do_gvec_shifts(unsigned vece, uint32_t dofs, uint32_t aofs, TCGv_i32 shift,
423
if (vece == MO_32 && check_size_impl(oprsz, 4)) {
424
expand_2s_i32(dofs, aofs, oprsz, shift, false, g->fni4);
425
} else if (vece == MO_64 && check_size_impl(oprsz, 8)) {
426
- TCGv_i64 sh64 = tcg_temp_new_i64();
427
+ TCGv_i64 sh64 = tcg_temp_ebb_new_i64();
428
tcg_gen_extu_i32_i64(sh64, shift);
429
expand_2s_i64(dofs, aofs, oprsz, sh64, false, g->fni8);
430
tcg_temp_free_i64(sh64);
431
} else {
432
- TCGv_ptr a0 = tcg_temp_new_ptr();
433
- TCGv_ptr a1 = tcg_temp_new_ptr();
434
- TCGv_i32 desc = tcg_temp_new_i32();
435
+ TCGv_ptr a0 = tcg_temp_ebb_new_ptr();
436
+ TCGv_ptr a1 = tcg_temp_ebb_new_ptr();
437
+ TCGv_i32 desc = tcg_temp_ebb_new_i32();
438
439
tcg_gen_shli_i32(desc, shift, SIMD_DATA_SHIFT);
440
tcg_gen_ori_i32(desc, desc, simd_desc(oprsz, maxsz, 0));
441
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_shlv_mod_vec(unsigned vece, TCGv_vec d,
442
443
static void tcg_gen_shl_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
444
{
445
- TCGv_i32 t = tcg_temp_new_i32();
446
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
447
448
tcg_gen_andi_i32(t, b, 31);
449
tcg_gen_shl_i32(d, a, t);
450
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_shl_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
451
452
static void tcg_gen_shl_mod_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
453
{
454
- TCGv_i64 t = tcg_temp_new_i64();
455
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
456
457
tcg_gen_andi_i64(t, b, 63);
458
tcg_gen_shl_i64(d, a, t);
459
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_shrv_mod_vec(unsigned vece, TCGv_vec d,
460
461
static void tcg_gen_shr_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
462
{
463
- TCGv_i32 t = tcg_temp_new_i32();
464
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
465
466
tcg_gen_andi_i32(t, b, 31);
467
tcg_gen_shr_i32(d, a, t);
468
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_shr_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
469
470
static void tcg_gen_shr_mod_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
471
{
472
- TCGv_i64 t = tcg_temp_new_i64();
473
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
474
475
tcg_gen_andi_i64(t, b, 63);
476
tcg_gen_shr_i64(d, a, t);
477
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_sarv_mod_vec(unsigned vece, TCGv_vec d,
478
479
static void tcg_gen_sar_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
480
{
481
- TCGv_i32 t = tcg_temp_new_i32();
482
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
483
484
tcg_gen_andi_i32(t, b, 31);
485
tcg_gen_sar_i32(d, a, t);
486
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_sar_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
487
488
static void tcg_gen_sar_mod_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
489
{
490
- TCGv_i64 t = tcg_temp_new_i64();
491
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
492
493
tcg_gen_andi_i64(t, b, 63);
494
tcg_gen_sar_i64(d, a, t);
495
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_rotlv_mod_vec(unsigned vece, TCGv_vec d,
496
497
static void tcg_gen_rotl_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
498
{
499
- TCGv_i32 t = tcg_temp_new_i32();
500
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
501
502
tcg_gen_andi_i32(t, b, 31);
503
tcg_gen_rotl_i32(d, a, t);
504
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_rotl_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
505
506
static void tcg_gen_rotl_mod_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
507
{
508
- TCGv_i64 t = tcg_temp_new_i64();
509
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
510
511
tcg_gen_andi_i64(t, b, 63);
512
tcg_gen_rotl_i64(d, a, t);
513
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_rotrv_mod_vec(unsigned vece, TCGv_vec d,
514
515
static void tcg_gen_rotr_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
516
{
517
- TCGv_i32 t = tcg_temp_new_i32();
518
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
519
520
tcg_gen_andi_i32(t, b, 31);
521
tcg_gen_rotr_i32(d, a, t);
522
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_rotr_mod_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
523
524
static void tcg_gen_rotr_mod_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
525
{
526
- TCGv_i64 t = tcg_temp_new_i64();
527
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
528
529
tcg_gen_andi_i64(t, b, 63);
530
tcg_gen_rotr_i64(d, a, t);
531
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_rotrv(unsigned vece, uint32_t dofs, uint32_t aofs,
532
static void expand_cmp_i32(uint32_t dofs, uint32_t aofs, uint32_t bofs,
533
uint32_t oprsz, TCGCond cond)
534
{
535
- TCGv_i32 t0 = tcg_temp_new_i32();
536
- TCGv_i32 t1 = tcg_temp_new_i32();
537
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
538
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
539
uint32_t i;
540
541
for (i = 0; i < oprsz; i += 4) {
542
@@ -XXX,XX +XXX,XX @@ static void expand_cmp_i32(uint32_t dofs, uint32_t aofs, uint32_t bofs,
543
static void expand_cmp_i64(uint32_t dofs, uint32_t aofs, uint32_t bofs,
544
uint32_t oprsz, TCGCond cond)
545
{
546
- TCGv_i64 t0 = tcg_temp_new_i64();
547
- TCGv_i64 t1 = tcg_temp_new_i64();
548
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
549
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
550
uint32_t i;
551
552
for (i = 0; i < oprsz; i += 8) {
553
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_cmp(TCGCond cond, unsigned vece, uint32_t dofs,
554
555
static void tcg_gen_bitsel_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b, TCGv_i64 c)
556
{
557
- TCGv_i64 t = tcg_temp_new_i64();
558
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
559
560
tcg_gen_and_i64(t, b, a);
561
tcg_gen_andc_i64(d, c, a);
562
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
563
index XXXXXXX..XXXXXXX 100644
564
--- a/tcg/tcg-op.c
565
+++ b/tcg/tcg-op.c
566
@@ -XXX,XX +XXX,XX @@ void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
567
if (TCG_TARGET_HAS_div_i32) {
568
tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
569
} else if (TCG_TARGET_HAS_div2_i32) {
570
- TCGv_i32 t0 = tcg_temp_new_i32();
571
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
572
tcg_gen_sari_i32(t0, arg1, 31);
573
tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
574
tcg_temp_free_i32(t0);
575
@@ -XXX,XX +XXX,XX @@ void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
576
if (TCG_TARGET_HAS_rem_i32) {
577
tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
578
} else if (TCG_TARGET_HAS_div_i32) {
579
- TCGv_i32 t0 = tcg_temp_new_i32();
580
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
581
tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
582
tcg_gen_mul_i32(t0, t0, arg2);
583
tcg_gen_sub_i32(ret, arg1, t0);
584
tcg_temp_free_i32(t0);
585
} else if (TCG_TARGET_HAS_div2_i32) {
586
- TCGv_i32 t0 = tcg_temp_new_i32();
587
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
588
tcg_gen_sari_i32(t0, arg1, 31);
589
tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
590
tcg_temp_free_i32(t0);
591
@@ -XXX,XX +XXX,XX @@ void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
592
if (TCG_TARGET_HAS_div_i32) {
593
tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
594
} else if (TCG_TARGET_HAS_div2_i32) {
595
- TCGv_i32 t0 = tcg_temp_new_i32();
596
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
597
tcg_gen_movi_i32(t0, 0);
598
tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
599
tcg_temp_free_i32(t0);
600
@@ -XXX,XX +XXX,XX @@ void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
601
if (TCG_TARGET_HAS_rem_i32) {
602
tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
603
} else if (TCG_TARGET_HAS_div_i32) {
604
- TCGv_i32 t0 = tcg_temp_new_i32();
605
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
606
tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
607
tcg_gen_mul_i32(t0, t0, arg2);
608
tcg_gen_sub_i32(ret, arg1, t0);
609
tcg_temp_free_i32(t0);
610
} else if (TCG_TARGET_HAS_div2_i32) {
611
- TCGv_i32 t0 = tcg_temp_new_i32();
612
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
613
tcg_gen_movi_i32(t0, 0);
614
tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
615
tcg_temp_free_i32(t0);
616
@@ -XXX,XX +XXX,XX @@ void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
617
if (TCG_TARGET_HAS_andc_i32) {
618
tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
619
} else {
620
- TCGv_i32 t0 = tcg_temp_new_i32();
621
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
622
tcg_gen_not_i32(t0, arg2);
623
tcg_gen_and_i32(ret, arg1, t0);
624
tcg_temp_free_i32(t0);
625
@@ -XXX,XX +XXX,XX @@ void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
626
if (TCG_TARGET_HAS_orc_i32) {
627
tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
628
} else {
629
- TCGv_i32 t0 = tcg_temp_new_i32();
630
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
631
tcg_gen_not_i32(t0, arg2);
632
tcg_gen_or_i32(ret, arg1, t0);
633
tcg_temp_free_i32(t0);
634
@@ -XXX,XX +XXX,XX @@ void tcg_gen_clz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
635
if (TCG_TARGET_HAS_clz_i32) {
636
tcg_gen_op3_i32(INDEX_op_clz_i32, ret, arg1, arg2);
637
} else if (TCG_TARGET_HAS_clz_i64) {
638
- TCGv_i64 t1 = tcg_temp_new_i64();
639
- TCGv_i64 t2 = tcg_temp_new_i64();
640
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
641
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
642
tcg_gen_extu_i32_i64(t1, arg1);
643
tcg_gen_extu_i32_i64(t2, arg2);
644
tcg_gen_addi_i64(t2, t2, 32);
645
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
646
if (TCG_TARGET_HAS_ctz_i32) {
647
tcg_gen_op3_i32(INDEX_op_ctz_i32, ret, arg1, arg2);
648
} else if (TCG_TARGET_HAS_ctz_i64) {
649
- TCGv_i64 t1 = tcg_temp_new_i64();
650
- TCGv_i64 t2 = tcg_temp_new_i64();
651
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
652
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
653
tcg_gen_extu_i32_i64(t1, arg1);
654
tcg_gen_extu_i32_i64(t2, arg2);
655
tcg_gen_ctz_i64(t1, t1, t2);
656
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
657
|| TCG_TARGET_HAS_ctpop_i64
658
|| TCG_TARGET_HAS_clz_i32
659
|| TCG_TARGET_HAS_clz_i64) {
660
- TCGv_i32 z, t = tcg_temp_new_i32();
661
+ TCGv_i32 z, t = tcg_temp_ebb_new_i32();
662
663
if (TCG_TARGET_HAS_ctpop_i32 || TCG_TARGET_HAS_ctpop_i64) {
664
tcg_gen_subi_i32(t, arg1, 1);
665
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
666
{
667
if (!TCG_TARGET_HAS_ctz_i32 && TCG_TARGET_HAS_ctpop_i32 && arg2 == 32) {
668
/* This equivalence has the advantage of not requiring a fixup. */
669
- TCGv_i32 t = tcg_temp_new_i32();
670
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
671
tcg_gen_subi_i32(t, arg1, 1);
672
tcg_gen_andc_i32(t, t, arg1);
673
tcg_gen_ctpop_i32(ret, t);
674
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
675
void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg)
676
{
677
if (TCG_TARGET_HAS_clz_i32) {
678
- TCGv_i32 t = tcg_temp_new_i32();
679
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
680
tcg_gen_sari_i32(t, arg, 31);
681
tcg_gen_xor_i32(t, t, arg);
682
tcg_gen_clzi_i32(t, t, 32);
683
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ctpop_i32(TCGv_i32 ret, TCGv_i32 arg1)
684
if (TCG_TARGET_HAS_ctpop_i32) {
685
tcg_gen_op2_i32(INDEX_op_ctpop_i32, ret, arg1);
686
} else if (TCG_TARGET_HAS_ctpop_i64) {
687
- TCGv_i64 t = tcg_temp_new_i64();
688
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
689
tcg_gen_extu_i32_i64(t, arg1);
690
tcg_gen_ctpop_i64(t, t);
691
tcg_gen_extrl_i64_i32(ret, t);
692
@@ -XXX,XX +XXX,XX @@ void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
693
} else {
694
TCGv_i32 t0, t1;
695
696
- t0 = tcg_temp_new_i32();
697
- t1 = tcg_temp_new_i32();
698
+ t0 = tcg_temp_ebb_new_i32();
699
+ t1 = tcg_temp_ebb_new_i32();
700
tcg_gen_shl_i32(t0, arg1, arg2);
701
tcg_gen_subfi_i32(t1, 32, arg2);
702
tcg_gen_shr_i32(t1, arg1, t1);
703
@@ -XXX,XX +XXX,XX @@ void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
704
tcg_gen_rotl_i32(ret, arg1, tcg_constant_i32(arg2));
705
} else {
706
TCGv_i32 t0, t1;
707
- t0 = tcg_temp_new_i32();
708
- t1 = tcg_temp_new_i32();
709
+ t0 = tcg_temp_ebb_new_i32();
710
+ t1 = tcg_temp_ebb_new_i32();
711
tcg_gen_shli_i32(t0, arg1, arg2);
712
tcg_gen_shri_i32(t1, arg1, 32 - arg2);
713
tcg_gen_or_i32(ret, t0, t1);
714
@@ -XXX,XX +XXX,XX @@ void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
715
} else {
716
TCGv_i32 t0, t1;
717
718
- t0 = tcg_temp_new_i32();
719
- t1 = tcg_temp_new_i32();
720
+ t0 = tcg_temp_ebb_new_i32();
721
+ t1 = tcg_temp_ebb_new_i32();
722
tcg_gen_shr_i32(t0, arg1, arg2);
723
tcg_gen_subfi_i32(t1, 32, arg2);
724
tcg_gen_shl_i32(t1, arg1, t1);
725
@@ -XXX,XX +XXX,XX @@ void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
726
return;
727
}
728
729
- t1 = tcg_temp_new_i32();
730
+ t1 = tcg_temp_ebb_new_i32();
731
732
if (TCG_TARGET_HAS_extract2_i32) {
733
if (ofs + len == 32) {
734
@@ -XXX,XX +XXX,XX @@ void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
735
} else if (TCG_TARGET_HAS_extract2_i32) {
736
tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs);
737
} else {
738
- TCGv_i32 t0 = tcg_temp_new_i32();
739
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
740
tcg_gen_shri_i32(t0, al, ofs);
741
tcg_gen_deposit_i32(ret, t0, ah, 32 - ofs, ofs);
742
tcg_temp_free_i32(t0);
743
@@ -XXX,XX +XXX,XX @@ void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
744
} else if (TCG_TARGET_HAS_movcond_i32) {
745
tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
746
} else {
747
- TCGv_i32 t0 = tcg_temp_new_i32();
748
- TCGv_i32 t1 = tcg_temp_new_i32();
749
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
750
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
751
tcg_gen_setcond_i32(cond, t0, c1, c2);
752
tcg_gen_neg_i32(t0, t0);
753
tcg_gen_and_i32(t1, v1, t0);
754
@@ -XXX,XX +XXX,XX @@ void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
755
if (TCG_TARGET_HAS_add2_i32) {
756
tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
757
} else {
758
- TCGv_i64 t0 = tcg_temp_new_i64();
759
- TCGv_i64 t1 = tcg_temp_new_i64();
760
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
761
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
762
tcg_gen_concat_i32_i64(t0, al, ah);
763
tcg_gen_concat_i32_i64(t1, bl, bh);
764
tcg_gen_add_i64(t0, t0, t1);
765
@@ -XXX,XX +XXX,XX @@ void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
766
if (TCG_TARGET_HAS_sub2_i32) {
767
tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
768
} else {
769
- TCGv_i64 t0 = tcg_temp_new_i64();
770
- TCGv_i64 t1 = tcg_temp_new_i64();
771
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
772
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
773
tcg_gen_concat_i32_i64(t0, al, ah);
774
tcg_gen_concat_i32_i64(t1, bl, bh);
775
tcg_gen_sub_i64(t0, t0, t1);
776
@@ -XXX,XX +XXX,XX @@ void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
777
if (TCG_TARGET_HAS_mulu2_i32) {
778
tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
779
} else if (TCG_TARGET_HAS_muluh_i32) {
780
- TCGv_i32 t = tcg_temp_new_i32();
781
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
782
tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
783
tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
784
tcg_gen_mov_i32(rl, t);
785
tcg_temp_free_i32(t);
786
} else if (TCG_TARGET_REG_BITS == 64) {
787
- TCGv_i64 t0 = tcg_temp_new_i64();
788
- TCGv_i64 t1 = tcg_temp_new_i64();
789
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
790
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
791
tcg_gen_extu_i32_i64(t0, arg1);
792
tcg_gen_extu_i32_i64(t1, arg2);
793
tcg_gen_mul_i64(t0, t0, t1);
794
@@ -XXX,XX +XXX,XX @@ void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
795
if (TCG_TARGET_HAS_muls2_i32) {
796
tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
797
} else if (TCG_TARGET_HAS_mulsh_i32) {
798
- TCGv_i32 t = tcg_temp_new_i32();
799
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
800
tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
801
tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
802
tcg_gen_mov_i32(rl, t);
803
tcg_temp_free_i32(t);
804
} else if (TCG_TARGET_REG_BITS == 32) {
805
- TCGv_i32 t0 = tcg_temp_new_i32();
806
- TCGv_i32 t1 = tcg_temp_new_i32();
807
- TCGv_i32 t2 = tcg_temp_new_i32();
808
- TCGv_i32 t3 = tcg_temp_new_i32();
809
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
810
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
811
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
812
+ TCGv_i32 t3 = tcg_temp_ebb_new_i32();
813
tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
814
/* Adjust for negative inputs. */
815
tcg_gen_sari_i32(t2, arg1, 31);
816
@@ -XXX,XX +XXX,XX @@ void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
817
tcg_temp_free_i32(t2);
818
tcg_temp_free_i32(t3);
819
} else {
820
- TCGv_i64 t0 = tcg_temp_new_i64();
821
- TCGv_i64 t1 = tcg_temp_new_i64();
822
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
823
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
824
tcg_gen_ext_i32_i64(t0, arg1);
825
tcg_gen_ext_i32_i64(t1, arg2);
826
tcg_gen_mul_i64(t0, t0, t1);
827
@@ -XXX,XX +XXX,XX @@ void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
828
void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
829
{
830
if (TCG_TARGET_REG_BITS == 32) {
831
- TCGv_i32 t0 = tcg_temp_new_i32();
832
- TCGv_i32 t1 = tcg_temp_new_i32();
833
- TCGv_i32 t2 = tcg_temp_new_i32();
834
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
835
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
836
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
837
tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
838
/* Adjust for negative input for the signed arg1. */
839
tcg_gen_sari_i32(t2, arg1, 31);
840
@@ -XXX,XX +XXX,XX @@ void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
841
tcg_temp_free_i32(t1);
842
tcg_temp_free_i32(t2);
843
} else {
844
- TCGv_i64 t0 = tcg_temp_new_i64();
845
- TCGv_i64 t1 = tcg_temp_new_i64();
846
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
847
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
848
tcg_gen_ext_i32_i64(t0, arg1);
849
tcg_gen_extu_i32_i64(t1, arg2);
850
tcg_gen_mul_i64(t0, t0, t1);
851
@@ -XXX,XX +XXX,XX @@ void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags)
852
if (TCG_TARGET_HAS_bswap16_i32) {
853
tcg_gen_op3i_i32(INDEX_op_bswap16_i32, ret, arg, flags);
854
} else {
855
- TCGv_i32 t0 = tcg_temp_new_i32();
856
- TCGv_i32 t1 = tcg_temp_new_i32();
857
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
858
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
859
860
tcg_gen_shri_i32(t0, arg, 8);
861
if (!(flags & TCG_BSWAP_IZ)) {
862
@@ -XXX,XX +XXX,XX @@ void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
863
if (TCG_TARGET_HAS_bswap32_i32) {
864
tcg_gen_op3i_i32(INDEX_op_bswap32_i32, ret, arg, 0);
865
} else {
866
- TCGv_i32 t0 = tcg_temp_new_i32();
867
- TCGv_i32 t1 = tcg_temp_new_i32();
868
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
869
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
870
TCGv_i32 t2 = tcg_constant_i32(0x00ff00ff);
871
872
/* arg = abcd */
873
@@ -XXX,XX +XXX,XX @@ void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
874
875
void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a)
876
{
877
- TCGv_i32 t = tcg_temp_new_i32();
878
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
879
880
tcg_gen_sari_i32(t, a, 31);
881
tcg_gen_xor_i32(ret, a, t);
882
@@ -XXX,XX +XXX,XX @@ void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
883
TCGv_i64 t0;
884
TCGv_i32 t1;
885
886
- t0 = tcg_temp_new_i64();
887
- t1 = tcg_temp_new_i32();
888
+ t0 = tcg_temp_ebb_new_i64();
889
+ t1 = tcg_temp_ebb_new_i32();
890
891
tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0),
892
TCGV_LOW(arg1), TCGV_LOW(arg2));
893
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
894
tcg_gen_extract2_i32(TCGV_HIGH(ret),
895
TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
896
} else {
897
- TCGv_i32 t0 = tcg_temp_new_i32();
898
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
899
tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
900
tcg_gen_deposit_i32(TCGV_HIGH(ret), t0,
901
TCGV_HIGH(arg1), c, 32 - c);
902
@@ -XXX,XX +XXX,XX @@ void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
903
if (TCG_TARGET_HAS_div_i64) {
904
tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
905
} else if (TCG_TARGET_HAS_div2_i64) {
906
- TCGv_i64 t0 = tcg_temp_new_i64();
907
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
908
tcg_gen_sari_i64(t0, arg1, 63);
909
tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
910
tcg_temp_free_i64(t0);
911
@@ -XXX,XX +XXX,XX @@ void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
912
if (TCG_TARGET_HAS_rem_i64) {
913
tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
914
} else if (TCG_TARGET_HAS_div_i64) {
915
- TCGv_i64 t0 = tcg_temp_new_i64();
916
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
917
tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
918
tcg_gen_mul_i64(t0, t0, arg2);
919
tcg_gen_sub_i64(ret, arg1, t0);
920
tcg_temp_free_i64(t0);
921
} else if (TCG_TARGET_HAS_div2_i64) {
922
- TCGv_i64 t0 = tcg_temp_new_i64();
923
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
924
tcg_gen_sari_i64(t0, arg1, 63);
925
tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
926
tcg_temp_free_i64(t0);
927
@@ -XXX,XX +XXX,XX @@ void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
928
if (TCG_TARGET_HAS_div_i64) {
929
tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
930
} else if (TCG_TARGET_HAS_div2_i64) {
931
- TCGv_i64 t0 = tcg_temp_new_i64();
932
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
933
tcg_gen_movi_i64(t0, 0);
934
tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
935
tcg_temp_free_i64(t0);
936
@@ -XXX,XX +XXX,XX @@ void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
937
if (TCG_TARGET_HAS_rem_i64) {
938
tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
939
} else if (TCG_TARGET_HAS_div_i64) {
940
- TCGv_i64 t0 = tcg_temp_new_i64();
941
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
942
tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
943
tcg_gen_mul_i64(t0, t0, arg2);
944
tcg_gen_sub_i64(ret, arg1, t0);
945
tcg_temp_free_i64(t0);
946
} else if (TCG_TARGET_HAS_div2_i64) {
947
- TCGv_i64 t0 = tcg_temp_new_i64();
948
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
949
tcg_gen_movi_i64(t0, 0);
950
tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
951
tcg_temp_free_i64(t0);
952
@@ -XXX,XX +XXX,XX @@ void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
953
} else if (TCG_TARGET_HAS_bswap16_i64) {
954
tcg_gen_op3i_i64(INDEX_op_bswap16_i64, ret, arg, flags);
955
} else {
956
- TCGv_i64 t0 = tcg_temp_new_i64();
957
- TCGv_i64 t1 = tcg_temp_new_i64();
958
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
959
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
960
961
tcg_gen_shri_i64(t0, arg, 8);
962
if (!(flags & TCG_BSWAP_IZ)) {
963
@@ -XXX,XX +XXX,XX @@ void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
964
} else if (TCG_TARGET_HAS_bswap32_i64) {
965
tcg_gen_op3i_i64(INDEX_op_bswap32_i64, ret, arg, flags);
966
} else {
967
- TCGv_i64 t0 = tcg_temp_new_i64();
968
- TCGv_i64 t1 = tcg_temp_new_i64();
969
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
970
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
971
TCGv_i64 t2 = tcg_constant_i64(0x00ff00ff);
972
973
/* arg = xxxxabcd */
974
@@ -XXX,XX +XXX,XX @@ void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
975
{
976
if (TCG_TARGET_REG_BITS == 32) {
977
TCGv_i32 t0, t1;
978
- t0 = tcg_temp_new_i32();
979
- t1 = tcg_temp_new_i32();
980
+ t0 = tcg_temp_ebb_new_i32();
981
+ t1 = tcg_temp_ebb_new_i32();
982
983
tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
984
tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
985
@@ -XXX,XX +XXX,XX @@ void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
986
} else if (TCG_TARGET_HAS_bswap64_i64) {
987
tcg_gen_op3i_i64(INDEX_op_bswap64_i64, ret, arg, 0);
988
} else {
989
- TCGv_i64 t0 = tcg_temp_new_i64();
990
- TCGv_i64 t1 = tcg_temp_new_i64();
991
- TCGv_i64 t2 = tcg_temp_new_i64();
992
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
993
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
994
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
995
996
/* arg = abcdefgh */
997
tcg_gen_movi_i64(t2, 0x00ff00ff00ff00ffull);
998
@@ -XXX,XX +XXX,XX @@ void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
999
void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg)
1000
{
1001
uint64_t m = 0x0000ffff0000ffffull;
1002
- TCGv_i64 t0 = tcg_temp_new_i64();
1003
- TCGv_i64 t1 = tcg_temp_new_i64();
1004
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1005
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1006
1007
/* See include/qemu/bitops.h, hswap64. */
1008
tcg_gen_rotli_i64(t1, arg, 32);
1009
@@ -XXX,XX +XXX,XX @@ void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1010
} else if (TCG_TARGET_HAS_andc_i64) {
1011
tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
1012
} else {
1013
- TCGv_i64 t0 = tcg_temp_new_i64();
1014
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1015
tcg_gen_not_i64(t0, arg2);
1016
tcg_gen_and_i64(ret, arg1, t0);
1017
tcg_temp_free_i64(t0);
1018
@@ -XXX,XX +XXX,XX @@ void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1019
} else if (TCG_TARGET_HAS_orc_i64) {
1020
tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
1021
} else {
1022
- TCGv_i64 t0 = tcg_temp_new_i64();
1023
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1024
tcg_gen_not_i64(t0, arg2);
1025
tcg_gen_or_i64(ret, arg1, t0);
1026
tcg_temp_free_i64(t0);
1027
@@ -XXX,XX +XXX,XX @@ void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
1028
if (TCG_TARGET_REG_BITS == 32
1029
&& TCG_TARGET_HAS_clz_i32
1030
&& arg2 <= 0xffffffffu) {
1031
- TCGv_i32 t = tcg_temp_new_i32();
1032
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
1033
tcg_gen_clzi_i32(t, TCGV_LOW(arg1), arg2 - 32);
1034
tcg_gen_addi_i32(t, t, 32);
1035
tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t);
1036
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1037
if (TCG_TARGET_HAS_ctz_i64) {
1038
tcg_gen_op3_i64(INDEX_op_ctz_i64, ret, arg1, arg2);
1039
} else if (TCG_TARGET_HAS_ctpop_i64 || TCG_TARGET_HAS_clz_i64) {
1040
- TCGv_i64 z, t = tcg_temp_new_i64();
1041
+ TCGv_i64 z, t = tcg_temp_ebb_new_i64();
1042
1043
if (TCG_TARGET_HAS_ctpop_i64) {
1044
tcg_gen_subi_i64(t, arg1, 1);
1045
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
1046
if (TCG_TARGET_REG_BITS == 32
1047
&& TCG_TARGET_HAS_ctz_i32
1048
&& arg2 <= 0xffffffffu) {
1049
- TCGv_i32 t32 = tcg_temp_new_i32();
1050
+ TCGv_i32 t32 = tcg_temp_ebb_new_i32();
1051
tcg_gen_ctzi_i32(t32, TCGV_HIGH(arg1), arg2 - 32);
1052
tcg_gen_addi_i32(t32, t32, 32);
1053
tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32);
1054
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
1055
&& TCG_TARGET_HAS_ctpop_i64
1056
&& arg2 == 64) {
1057
/* This equivalence has the advantage of not requiring a fixup. */
1058
- TCGv_i64 t = tcg_temp_new_i64();
1059
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
1060
tcg_gen_subi_i64(t, arg1, 1);
1061
tcg_gen_andc_i64(t, t, arg1);
1062
tcg_gen_ctpop_i64(ret, t);
1063
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
1064
void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg)
1065
{
1066
if (TCG_TARGET_HAS_clz_i64 || TCG_TARGET_HAS_clz_i32) {
1067
- TCGv_i64 t = tcg_temp_new_i64();
1068
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
1069
tcg_gen_sari_i64(t, arg, 63);
1070
tcg_gen_xor_i64(t, t, arg);
1071
tcg_gen_clzi_i64(t, t, 64);
1072
@@ -XXX,XX +XXX,XX @@ void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1073
tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
1074
} else {
1075
TCGv_i64 t0, t1;
1076
- t0 = tcg_temp_new_i64();
1077
- t1 = tcg_temp_new_i64();
1078
+ t0 = tcg_temp_ebb_new_i64();
1079
+ t1 = tcg_temp_ebb_new_i64();
1080
tcg_gen_shl_i64(t0, arg1, arg2);
1081
tcg_gen_subfi_i64(t1, 64, arg2);
1082
tcg_gen_shr_i64(t1, arg1, t1);
1083
@@ -XXX,XX +XXX,XX @@ void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1084
tcg_gen_rotl_i64(ret, arg1, tcg_constant_i64(arg2));
1085
} else {
1086
TCGv_i64 t0, t1;
1087
- t0 = tcg_temp_new_i64();
1088
- t1 = tcg_temp_new_i64();
1089
+ t0 = tcg_temp_ebb_new_i64();
1090
+ t1 = tcg_temp_ebb_new_i64();
1091
tcg_gen_shli_i64(t0, arg1, arg2);
1092
tcg_gen_shri_i64(t1, arg1, 64 - arg2);
1093
tcg_gen_or_i64(ret, t0, t1);
1094
@@ -XXX,XX +XXX,XX @@ void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1095
tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
1096
} else {
1097
TCGv_i64 t0, t1;
1098
- t0 = tcg_temp_new_i64();
1099
- t1 = tcg_temp_new_i64();
1100
+ t0 = tcg_temp_ebb_new_i64();
1101
+ t1 = tcg_temp_ebb_new_i64();
1102
tcg_gen_shr_i64(t0, arg1, arg2);
1103
tcg_gen_subfi_i64(t1, 64, arg2);
1104
tcg_gen_shl_i64(t1, arg1, t1);
1105
@@ -XXX,XX +XXX,XX @@ void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
1106
}
1107
}
1108
1109
- t1 = tcg_temp_new_i64();
1110
+ t1 = tcg_temp_ebb_new_i64();
1111
1112
if (TCG_TARGET_HAS_extract2_i64) {
1113
if (ofs + len == 64) {
1114
@@ -XXX,XX +XXX,XX @@ void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
1115
tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32);
1116
return;
1117
} else if (len > 32) {
1118
- TCGv_i32 t = tcg_temp_new_i32();
1119
+ TCGv_i32 t = tcg_temp_ebb_new_i32();
1120
/* Extract the bits for the high word normally. */
1121
tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32);
1122
/* Shift the field down for the low part. */
1123
@@ -XXX,XX +XXX,XX @@ void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
1124
} else if (TCG_TARGET_HAS_extract2_i64) {
1125
tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs);
1126
} else {
1127
- TCGv_i64 t0 = tcg_temp_new_i64();
1128
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1129
tcg_gen_shri_i64(t0, al, ofs);
1130
tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs);
1131
tcg_temp_free_i64(t0);
1132
@@ -XXX,XX +XXX,XX @@ void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
1133
} else if (cond == TCG_COND_NEVER) {
1134
tcg_gen_mov_i64(ret, v2);
1135
} else if (TCG_TARGET_REG_BITS == 32) {
1136
- TCGv_i32 t0 = tcg_temp_new_i32();
1137
- TCGv_i32 t1 = tcg_temp_new_i32();
1138
+ TCGv_i32 t0 = tcg_temp_ebb_new_i32();
1139
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
1140
tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
1141
TCGV_LOW(c1), TCGV_HIGH(c1),
1142
TCGV_LOW(c2), TCGV_HIGH(c2), cond);
1143
@@ -XXX,XX +XXX,XX @@ void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
1144
} else if (TCG_TARGET_HAS_movcond_i64) {
1145
tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
1146
} else {
1147
- TCGv_i64 t0 = tcg_temp_new_i64();
1148
- TCGv_i64 t1 = tcg_temp_new_i64();
1149
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1150
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1151
tcg_gen_setcond_i64(cond, t0, c1, c2);
1152
tcg_gen_neg_i64(t0, t0);
1153
tcg_gen_and_i64(t1, v1, t0);
1154
@@ -XXX,XX +XXX,XX @@ void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
1155
if (TCG_TARGET_HAS_add2_i64) {
1156
tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
1157
} else {
1158
- TCGv_i64 t0 = tcg_temp_new_i64();
1159
- TCGv_i64 t1 = tcg_temp_new_i64();
1160
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1161
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1162
tcg_gen_add_i64(t0, al, bl);
1163
tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
1164
tcg_gen_add_i64(rh, ah, bh);
1165
@@ -XXX,XX +XXX,XX @@ void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
1166
if (TCG_TARGET_HAS_sub2_i64) {
1167
tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
1168
} else {
1169
- TCGv_i64 t0 = tcg_temp_new_i64();
1170
- TCGv_i64 t1 = tcg_temp_new_i64();
1171
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1172
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1173
tcg_gen_sub_i64(t0, al, bl);
1174
tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
1175
tcg_gen_sub_i64(rh, ah, bh);
1176
@@ -XXX,XX +XXX,XX @@ void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
1177
if (TCG_TARGET_HAS_mulu2_i64) {
1178
tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
1179
} else if (TCG_TARGET_HAS_muluh_i64) {
1180
- TCGv_i64 t = tcg_temp_new_i64();
1181
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
1182
tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
1183
tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
1184
tcg_gen_mov_i64(rl, t);
1185
tcg_temp_free_i64(t);
1186
} else {
1187
- TCGv_i64 t0 = tcg_temp_new_i64();
1188
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1189
tcg_gen_mul_i64(t0, arg1, arg2);
1190
gen_helper_muluh_i64(rh, arg1, arg2);
1191
tcg_gen_mov_i64(rl, t0);
1192
@@ -XXX,XX +XXX,XX @@ void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
1193
if (TCG_TARGET_HAS_muls2_i64) {
1194
tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
1195
} else if (TCG_TARGET_HAS_mulsh_i64) {
1196
- TCGv_i64 t = tcg_temp_new_i64();
1197
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
1198
tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
1199
tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
1200
tcg_gen_mov_i64(rl, t);
1201
tcg_temp_free_i64(t);
1202
} else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) {
1203
- TCGv_i64 t0 = tcg_temp_new_i64();
1204
- TCGv_i64 t1 = tcg_temp_new_i64();
1205
- TCGv_i64 t2 = tcg_temp_new_i64();
1206
- TCGv_i64 t3 = tcg_temp_new_i64();
1207
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1208
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1209
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
1210
+ TCGv_i64 t3 = tcg_temp_ebb_new_i64();
1211
tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
1212
/* Adjust for negative inputs. */
1213
tcg_gen_sari_i64(t2, arg1, 63);
1214
@@ -XXX,XX +XXX,XX @@ void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
1215
tcg_temp_free_i64(t2);
1216
tcg_temp_free_i64(t3);
1217
} else {
1218
- TCGv_i64 t0 = tcg_temp_new_i64();
1219
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1220
tcg_gen_mul_i64(t0, arg1, arg2);
1221
gen_helper_mulsh_i64(rh, arg1, arg2);
1222
tcg_gen_mov_i64(rl, t0);
1223
@@ -XXX,XX +XXX,XX @@ void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
1224
1225
void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
1226
{
1227
- TCGv_i64 t0 = tcg_temp_new_i64();
1228
- TCGv_i64 t1 = tcg_temp_new_i64();
1229
- TCGv_i64 t2 = tcg_temp_new_i64();
1230
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1231
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1232
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
1233
tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
1234
/* Adjust for negative input for the signed arg1. */
1235
tcg_gen_sari_i64(t2, arg1, 63);
1236
@@ -XXX,XX +XXX,XX @@ void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
1237
1238
void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a)
1239
{
1240
- TCGv_i64 t = tcg_temp_new_i64();
1241
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
1242
1243
tcg_gen_sari_i64(t, a, 63);
1244
tcg_gen_xor_i64(ret, a, t);
1245
@@ -XXX,XX +XXX,XX @@ void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
1246
tcg_gen_op2(INDEX_op_extrh_i64_i32,
1247
tcgv_i32_arg(ret), tcgv_i64_arg(arg));
1248
} else {
1249
- TCGv_i64 t = tcg_temp_new_i64();
1250
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
1251
tcg_gen_shri_i64(t, arg, 32);
1252
tcg_gen_mov_i32(ret, (TCGv_i32)t);
1253
tcg_temp_free_i64(t);
1254
@@ -XXX,XX +XXX,XX @@ void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
1255
return;
1256
}
1257
1258
- tmp = tcg_temp_new_i64();
1259
+ tmp = tcg_temp_ebb_new_i64();
1260
/* These extensions are only needed for type correctness.
1261
We may be able to do better given target specific information. */
1262
tcg_gen_extu_i32_i64(tmp, high);
1263
@@ -XXX,XX +XXX,XX @@ void tcg_gen_lookup_and_goto_ptr(void)
1264
}
1265
1266
plugin_gen_disable_mem_helpers();
1267
- ptr = tcg_temp_new_ptr();
1268
+ ptr = tcg_temp_ebb_new_ptr();
1269
gen_helper_lookup_tb_ptr(ptr, cpu_env);
1270
tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr));
1271
tcg_temp_free_ptr(ptr);
1272
@@ -XXX,XX +XXX,XX @@ void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, MemOp memop)
1273
oi = make_memop_idx(memop, idx);
1274
1275
if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
1276
- swap = tcg_temp_new_i32();
1277
+ swap = tcg_temp_ebb_new_i32();
1278
switch (memop & MO_SIZE) {
1279
case MO_16:
1280
tcg_gen_bswap16_i32(swap, val, 0);
1281
@@ -XXX,XX +XXX,XX @@ void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, MemOp memop)
1282
oi = make_memop_idx(memop, idx);
1283
1284
if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
1285
- swap = tcg_temp_new_i64();
1286
+ swap = tcg_temp_ebb_new_i64();
1287
switch (memop & MO_SIZE) {
1288
case MO_16:
1289
tcg_gen_bswap16_i64(swap, val, 0);
1290
@@ -XXX,XX +XXX,XX @@ void tcg_gen_qemu_st_i128(TCGv_i128 val, TCGv addr, TCGArg idx, MemOp memop)
1291
1292
addr_p8 = tcg_temp_new();
1293
if ((mop[0] ^ memop) & MO_BSWAP) {
1294
- TCGv_i64 t = tcg_temp_new_i64();
1295
+ TCGv_i64 t = tcg_temp_ebb_new_i64();
1296
1297
tcg_gen_bswap64_i64(t, x);
1298
gen_ldst_i64(INDEX_op_qemu_st_i64, t, addr, mop[0], idx);
1299
@@ -XXX,XX +XXX,XX @@ static void * const table_cmpxchg[(MO_SIZE | MO_BSWAP) + 1] = {
1300
void tcg_gen_nonatomic_cmpxchg_i32(TCGv_i32 retv, TCGv addr, TCGv_i32 cmpv,
1301
TCGv_i32 newv, TCGArg idx, MemOp memop)
1302
{
1303
- TCGv_i32 t1 = tcg_temp_new_i32();
1304
- TCGv_i32 t2 = tcg_temp_new_i32();
1305
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
1306
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
1307
1308
tcg_gen_ext_i32(t2, cmpv, memop & MO_SIZE);
1309
1310
@@ -XXX,XX +XXX,XX @@ void tcg_gen_nonatomic_cmpxchg_i64(TCGv_i64 retv, TCGv addr, TCGv_i64 cmpv,
1311
return;
1312
}
1313
1314
- t1 = tcg_temp_new_i64();
1315
- t2 = tcg_temp_new_i64();
1316
+ t1 = tcg_temp_ebb_new_i64();
1317
+ t2 = tcg_temp_ebb_new_i64();
1318
1319
tcg_gen_ext_i64(t2, cmpv, memop & MO_SIZE);
1320
1321
@@ -XXX,XX +XXX,XX @@ void tcg_gen_atomic_cmpxchg_i64(TCGv_i64 retv, TCGv addr, TCGv_i64 cmpv,
1322
tcg_gen_movi_i32(TCGV_HIGH(retv), 0);
1323
}
1324
} else {
1325
- TCGv_i32 c32 = tcg_temp_new_i32();
1326
- TCGv_i32 n32 = tcg_temp_new_i32();
1327
- TCGv_i32 r32 = tcg_temp_new_i32();
1328
+ TCGv_i32 c32 = tcg_temp_ebb_new_i32();
1329
+ TCGv_i32 n32 = tcg_temp_ebb_new_i32();
1330
+ TCGv_i32 r32 = tcg_temp_ebb_new_i32();
1331
1332
tcg_gen_extrl_i64_i32(c32, cmpv);
1333
tcg_gen_extrl_i64_i32(n32, newv);
1334
@@ -XXX,XX +XXX,XX @@ void tcg_gen_nonatomic_cmpxchg_i128(TCGv_i128 retv, TCGv addr, TCGv_i128 cmpv,
1335
1336
gen(retv, cpu_env, addr, cmpv, newv, tcg_constant_i32(oi));
1337
} else {
1338
- TCGv_i128 oldv = tcg_temp_new_i128();
1339
- TCGv_i128 tmpv = tcg_temp_new_i128();
1340
- TCGv_i64 t0 = tcg_temp_new_i64();
1341
- TCGv_i64 t1 = tcg_temp_new_i64();
1342
+ TCGv_i128 oldv = tcg_temp_ebb_new_i128();
1343
+ TCGv_i128 tmpv = tcg_temp_ebb_new_i128();
1344
+ TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1345
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1346
TCGv_i64 z = tcg_constant_i64(0);
1347
1348
tcg_gen_qemu_ld_i128(oldv, addr, idx, memop);
1349
@@ -XXX,XX +XXX,XX @@ static void do_nonatomic_op_i32(TCGv_i32 ret, TCGv addr, TCGv_i32 val,
1350
TCGArg idx, MemOp memop, bool new_val,
1351
void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
1352
{
1353
- TCGv_i32 t1 = tcg_temp_new_i32();
1354
- TCGv_i32 t2 = tcg_temp_new_i32();
1355
+ TCGv_i32 t1 = tcg_temp_ebb_new_i32();
1356
+ TCGv_i32 t2 = tcg_temp_ebb_new_i32();
1357
1358
memop = tcg_canonicalize_memop(memop, 0, 0);
1359
1360
@@ -XXX,XX +XXX,XX @@ static void do_nonatomic_op_i64(TCGv_i64 ret, TCGv addr, TCGv_i64 val,
1361
TCGArg idx, MemOp memop, bool new_val,
1362
void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64))
1363
{
1364
- TCGv_i64 t1 = tcg_temp_new_i64();
1365
- TCGv_i64 t2 = tcg_temp_new_i64();
1366
+ TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1367
+ TCGv_i64 t2 = tcg_temp_ebb_new_i64();
1368
1369
memop = tcg_canonicalize_memop(memop, 1, 0);
1370
1371
@@ -XXX,XX +XXX,XX @@ static void do_atomic_op_i64(TCGv_i64 ret, TCGv addr, TCGv_i64 val,
1372
tcg_gen_movi_i64(ret, 0);
1373
#endif /* CONFIG_ATOMIC64 */
1374
} else {
1375
- TCGv_i32 v32 = tcg_temp_new_i32();
1376
- TCGv_i32 r32 = tcg_temp_new_i32();
1377
+ TCGv_i32 v32 = tcg_temp_ebb_new_i32();
1378
+ TCGv_i32 r32 = tcg_temp_ebb_new_i32();
1379
1380
tcg_gen_extrl_i64_i32(v32, val);
1381
do_atomic_op_i32(r32, addr, v32, idx, memop & ~MO_SIGN, table);
1382
diff --git a/tcg/tcg.c b/tcg/tcg.c
1383
index XXXXXXX..XXXXXXX 100644
1384
--- a/tcg/tcg.c
1385
+++ b/tcg/tcg.c
1386
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
1387
case TCG_CALL_ARG_EXTEND_U:
1388
case TCG_CALL_ARG_EXTEND_S:
1389
{
1390
- TCGv_i64 temp = tcg_temp_new_i64();
1391
+ TCGv_i64 temp = tcg_temp_ebb_new_i64();
1392
TCGv_i32 orig = temp_tcgv_i32(ts);
1393
1394
if (loc->kind == TCG_CALL_ARG_EXTEND_S) {
1395
--
1396
2.34.1
1397
1398
diff view generated by jsdifflib
New patch
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
tcg/tcg-op-gvec.c | 3 +--
6
1 file changed, 1 insertion(+), 2 deletions(-)
1
7
8
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/tcg/tcg-op-gvec.c
11
+++ b/tcg/tcg-op-gvec.c
12
@@ -XXX,XX +XXX,XX @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz,
13
* stores through to memset.
14
*/
15
if (oprsz == maxsz && vece == MO_8) {
16
- TCGv_ptr t_size = tcg_const_ptr(oprsz);
17
+ TCGv_ptr t_size = tcg_constant_ptr(oprsz);
18
TCGv_i32 t_val;
19
20
if (in_32) {
21
@@ -XXX,XX +XXX,XX @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t oprsz,
22
if (in_64) {
23
tcg_temp_free_i32(t_val);
24
}
25
- tcg_temp_free_ptr(t_size);
26
tcg_temp_free_ptr(t_ptr);
27
return;
28
}
29
--
30
2.34.1
31
32
diff view generated by jsdifflib
New patch
1
All of these uses have quite local scope.
2
Avoid tcg_const_*, because we haven't added a corresponding
3
interface for TEMP_EBB. Use explicit tcg_gen_movi_* instead.
1
4
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
accel/tcg/plugin-gen.c | 24 ++++++++++++++----------
9
1 file changed, 14 insertions(+), 10 deletions(-)
10
11
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/plugin-gen.c
14
+++ b/accel/tcg/plugin-gen.c
15
@@ -XXX,XX +XXX,XX @@ void HELPER(plugin_vcpu_mem_cb)(unsigned int vcpu_index,
16
17
static void do_gen_mem_cb(TCGv vaddr, uint32_t info)
18
{
19
- TCGv_i32 cpu_index = tcg_temp_new_i32();
20
- TCGv_i32 meminfo = tcg_const_i32(info);
21
- TCGv_i64 vaddr64 = tcg_temp_new_i64();
22
- TCGv_ptr udata = tcg_const_ptr(NULL);
23
+ TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
24
+ TCGv_i32 meminfo = tcg_temp_ebb_new_i32();
25
+ TCGv_i64 vaddr64 = tcg_temp_ebb_new_i64();
26
+ TCGv_ptr udata = tcg_temp_ebb_new_ptr();
27
28
+ tcg_gen_movi_i32(meminfo, info);
29
+ tcg_gen_movi_ptr(udata, 0);
30
tcg_gen_ld_i32(cpu_index, cpu_env,
31
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
32
tcg_gen_extu_tl_i64(vaddr64, vaddr);
33
@@ -XXX,XX +XXX,XX @@ static void do_gen_mem_cb(TCGv vaddr, uint32_t info)
34
35
static void gen_empty_udata_cb(void)
36
{
37
- TCGv_i32 cpu_index = tcg_temp_new_i32();
38
- TCGv_ptr udata = tcg_const_ptr(NULL); /* will be overwritten later */
39
+ TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
40
+ TCGv_ptr udata = tcg_temp_ebb_new_ptr();
41
42
+ tcg_gen_movi_ptr(udata, 0);
43
tcg_gen_ld_i32(cpu_index, cpu_env,
44
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
45
gen_helper_plugin_vcpu_udata_cb(cpu_index, udata);
46
@@ -XXX,XX +XXX,XX @@ static void gen_empty_udata_cb(void)
47
*/
48
static void gen_empty_inline_cb(void)
49
{
50
- TCGv_i64 val = tcg_temp_new_i64();
51
- TCGv_ptr ptr = tcg_const_ptr(NULL); /* overwritten later */
52
+ TCGv_i64 val = tcg_temp_ebb_new_i64();
53
+ TCGv_ptr ptr = tcg_temp_ebb_new_ptr();
54
55
+ tcg_gen_movi_ptr(ptr, 0);
56
tcg_gen_ld_i64(val, ptr, 0);
57
/* pass an immediate != 0 so that it doesn't get optimized away */
58
tcg_gen_addi_i64(val, val, 0xdeadface);
59
@@ -XXX,XX +XXX,XX @@ static void gen_empty_mem_cb(TCGv addr, uint32_t info)
60
*/
61
static void gen_empty_mem_helper(void)
62
{
63
- TCGv_ptr ptr;
64
+ TCGv_ptr ptr = tcg_temp_ebb_new_ptr();
65
66
- ptr = tcg_const_ptr(NULL);
67
+ tcg_gen_movi_ptr(ptr, 0);
68
tcg_gen_st_ptr(ptr, cpu_env, offsetof(CPUState, plugin_mem_cbs) -
69
offsetof(ArchCPU, env));
70
tcg_temp_free_ptr(ptr);
71
--
72
2.34.1
73
74
diff view generated by jsdifflib
1
Use the pc coming from db->pc_first rather than the TB.
1
Here we are creating a temp whose value needs to be replaced,
2
but always storing NULL into CPUState.plugin_mem_cbs.
3
Use tcg_constant_ptr(0) explicitly.
2
4
3
Use the cached host_addr rather than re-computing for the
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
first page. We still need a separate lookup for the second
5
page because it won't be computed for DisasContextBase until
6
the translator actually performs a read from the page.
7
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
7
---
11
include/exec/plugin-gen.h | 7 ++++---
8
accel/tcg/plugin-gen.c | 8 ++------
12
accel/tcg/plugin-gen.c | 22 +++++++++++-----------
9
1 file changed, 2 insertions(+), 6 deletions(-)
13
accel/tcg/translator.c | 2 +-
14
3 files changed, 16 insertions(+), 15 deletions(-)
15
10
16
diff --git a/include/exec/plugin-gen.h b/include/exec/plugin-gen.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/exec/plugin-gen.h
19
+++ b/include/exec/plugin-gen.h
20
@@ -XXX,XX +XXX,XX @@ struct DisasContextBase;
21
22
#ifdef CONFIG_PLUGIN
23
24
-bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool supress);
25
+bool plugin_gen_tb_start(CPUState *cpu, const struct DisasContextBase *db,
26
+ bool supress);
27
void plugin_gen_tb_end(CPUState *cpu);
28
void plugin_gen_insn_start(CPUState *cpu, const struct DisasContextBase *db);
29
void plugin_gen_insn_end(void);
30
@@ -XXX,XX +XXX,XX @@ static inline void plugin_insn_append(abi_ptr pc, const void *from, size_t size)
31
32
#else /* !CONFIG_PLUGIN */
33
34
-static inline
35
-bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool supress)
36
+static inline bool
37
+plugin_gen_tb_start(CPUState *cpu, const struct DisasContextBase *db, bool sup)
38
{
39
return false;
40
}
41
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
11
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
42
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
43
--- a/accel/tcg/plugin-gen.c
13
--- a/accel/tcg/plugin-gen.c
44
+++ b/accel/tcg/plugin-gen.c
14
+++ b/accel/tcg/plugin-gen.c
45
@@ -XXX,XX +XXX,XX @@ static void plugin_gen_inject(const struct qemu_plugin_tb *plugin_tb)
15
@@ -XXX,XX +XXX,XX @@ static void inject_mem_disable_helper(struct qemu_plugin_insn *plugin_insn,
46
pr_ops();
16
/* called before finishing a TB with exit_tb, goto_tb or goto_ptr */
17
void plugin_gen_disable_mem_helpers(void)
18
{
19
- TCGv_ptr ptr;
20
-
21
/*
22
* We could emit the clearing unconditionally and be done. However, this can
23
* be wasteful if for instance plugins don't track memory accesses, or if
24
@@ -XXX,XX +XXX,XX @@ void plugin_gen_disable_mem_helpers(void)
25
if (!tcg_ctx->plugin_tb->mem_helper) {
26
return;
27
}
28
- ptr = tcg_const_ptr(NULL);
29
- tcg_gen_st_ptr(ptr, cpu_env, offsetof(CPUState, plugin_mem_cbs) -
30
- offsetof(ArchCPU, env));
31
- tcg_temp_free_ptr(ptr);
32
+ tcg_gen_st_ptr(tcg_constant_ptr(NULL), cpu_env,
33
+ offsetof(CPUState, plugin_mem_cbs) - offsetof(ArchCPU, env));
47
}
34
}
48
35
49
-bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool mem_only)
36
static void plugin_gen_tb_udata(const struct qemu_plugin_tb *ptb,
50
+bool plugin_gen_tb_start(CPUState *cpu, const DisasContextBase *db,
51
+ bool mem_only)
52
{
53
bool ret = false;
54
55
@@ -XXX,XX +XXX,XX @@ bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool mem_onl
56
57
ret = true;
58
59
- ptb->vaddr = tb->pc;
60
+ ptb->vaddr = db->pc_first;
61
ptb->vaddr2 = -1;
62
- get_page_addr_code_hostp(cpu->env_ptr, tb->pc, &ptb->haddr1);
63
+ ptb->haddr1 = db->host_addr[0];
64
ptb->haddr2 = NULL;
65
ptb->mem_only = mem_only;
66
67
@@ -XXX,XX +XXX,XX @@ void plugin_gen_insn_start(CPUState *cpu, const DisasContextBase *db)
68
* Note that we skip this when haddr1 == NULL, e.g. when we're
69
* fetching instructions from a region not backed by RAM.
70
*/
71
- if (likely(ptb->haddr1 != NULL && ptb->vaddr2 == -1) &&
72
- unlikely((db->pc_next & TARGET_PAGE_MASK) !=
73
- (db->pc_first & TARGET_PAGE_MASK))) {
74
- get_page_addr_code_hostp(cpu->env_ptr, db->pc_next,
75
- &ptb->haddr2);
76
- ptb->vaddr2 = db->pc_next;
77
- }
78
- if (likely(ptb->vaddr2 == -1)) {
79
+ if (ptb->haddr1 == NULL) {
80
+ pinsn->haddr = NULL;
81
+ } else if (is_same_page(db, db->pc_next)) {
82
pinsn->haddr = ptb->haddr1 + pinsn->vaddr - ptb->vaddr;
83
} else {
84
+ if (ptb->vaddr2 == -1) {
85
+ ptb->vaddr2 = TARGET_PAGE_ALIGN(db->pc_first);
86
+ get_page_addr_code_hostp(cpu->env_ptr, ptb->vaddr2, &ptb->haddr2);
87
+ }
88
pinsn->haddr = ptb->haddr2 + pinsn->vaddr - ptb->vaddr2;
89
}
90
}
91
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/accel/tcg/translator.c
94
+++ b/accel/tcg/translator.c
95
@@ -XXX,XX +XXX,XX @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
96
ops->tb_start(db, cpu);
97
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
98
99
- plugin_enabled = plugin_gen_tb_start(cpu, tb, cflags & CF_MEMI_ONLY);
100
+ plugin_enabled = plugin_gen_tb_start(cpu, db, cflags & CF_MEMI_ONLY);
101
102
while (true) {
103
db->num_insns++;
104
--
37
--
105
2.34.1
38
2.34.1
106
39
107
40
diff view generated by jsdifflib
1
This bitmap is created and discarded immediately.
1
Reusing TEMP_TB interferes with detecting whether the
2
We gain nothing by its existence.
2
temp can be adjusted to TEMP_EBB.
3
3
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-Id: <20220822232338.1727934-2-richard.henderson@linaro.org>
7
---
6
---
8
accel/tcg/translate-all.c | 78 ++-------------------------------------
7
include/tcg/tcg.h | 2 +-
9
1 file changed, 4 insertions(+), 74 deletions(-)
8
tcg/tcg.c | 101 ++++++++++++++++++++++++----------------------
9
2 files changed, 53 insertions(+), 50 deletions(-)
10
10
11
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
11
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/translate-all.c
13
--- a/include/tcg/tcg.h
14
+++ b/accel/tcg/translate-all.c
14
+++ b/include/tcg/tcg.h
15
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
16
#define assert_memory_lock() tcg_debug_assert(have_mmap_lock())
17
#endif
16
#endif
18
17
19
-#define SMC_BITMAP_USE_THRESHOLD 10
18
GHashTable *const_table[TCG_TYPE_COUNT];
20
-
19
- TCGTempSet free_temps[TCG_TYPE_COUNT * 2];
21
typedef struct PageDesc {
20
+ TCGTempSet free_temps[TCG_TYPE_COUNT];
22
/* list of TBs intersecting this ram page */
21
TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
23
uintptr_t first_tb;
22
24
-#ifdef CONFIG_SOFTMMU
23
QTAILQ_HEAD(, TCGOp) ops, free_ops;
25
- /* in order to optimize self modifying code, we count the number
24
diff --git a/tcg/tcg.c b/tcg/tcg.c
26
- of lookups we do to a given page to use a bitmap */
25
index XXXXXXX..XXXXXXX 100644
27
- unsigned long *code_bitmap;
26
--- a/tcg/tcg.c
28
- unsigned int code_write_count;
27
+++ b/tcg/tcg.c
29
-#else
28
@@ -XXX,XX +XXX,XX @@ TCGTemp *tcg_global_mem_new_internal(TCGType type, TCGv_ptr base,
30
+#ifdef CONFIG_USER_ONLY
29
TCGTemp *tcg_temp_new_internal(TCGType type, TCGTempKind kind)
31
unsigned long flags;
32
void *target_data;
33
#endif
34
-#ifndef CONFIG_USER_ONLY
35
+#ifdef CONFIG_SOFTMMU
36
QemuSpin lock;
37
#endif
38
} PageDesc;
39
@@ -XXX,XX +XXX,XX @@ void tb_htable_init(void)
40
qht_init(&tb_ctx.htable, tb_cmp, CODE_GEN_HTABLE_SIZE, mode);
41
}
42
43
-/* call with @p->lock held */
44
-static inline void invalidate_page_bitmap(PageDesc *p)
45
-{
46
- assert_page_locked(p);
47
-#ifdef CONFIG_SOFTMMU
48
- g_free(p->code_bitmap);
49
- p->code_bitmap = NULL;
50
- p->code_write_count = 0;
51
-#endif
52
-}
53
-
54
/* Set to NULL all the 'first_tb' fields in all PageDescs. */
55
static void page_flush_tb_1(int level, void **lp)
56
{
30
{
57
@@ -XXX,XX +XXX,XX @@ static void page_flush_tb_1(int level, void **lp)
31
TCGContext *s = tcg_ctx;
58
for (i = 0; i < V_L2_SIZE; ++i) {
32
- bool temp_local = kind == TEMP_TB;
59
page_lock(&pd[i]);
33
TCGTemp *ts;
60
pd[i].first_tb = (uintptr_t)NULL;
34
- int idx, k;
61
- invalidate_page_bitmap(pd + i);
35
+ int n;
62
page_unlock(&pd[i]);
36
37
- k = type + (temp_local ? TCG_TYPE_COUNT : 0);
38
- idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS);
39
- if (idx < TCG_MAX_TEMPS) {
40
- /* There is already an available temp with the right type. */
41
- clear_bit(idx, s->free_temps[k].l);
42
+ if (kind == TEMP_EBB) {
43
+ int idx = find_first_bit(s->free_temps[type].l, TCG_MAX_TEMPS);
44
45
- ts = &s->temps[idx];
46
- ts->temp_allocated = 1;
47
- tcg_debug_assert(ts->base_type == type);
48
- tcg_debug_assert(ts->kind == kind);
49
- } else {
50
- int i, n;
51
+ if (idx < TCG_MAX_TEMPS) {
52
+ /* There is already an available temp with the right type. */
53
+ clear_bit(idx, s->free_temps[type].l);
54
55
- switch (type) {
56
- case TCG_TYPE_I32:
57
- case TCG_TYPE_V64:
58
- case TCG_TYPE_V128:
59
- case TCG_TYPE_V256:
60
- n = 1;
61
- break;
62
- case TCG_TYPE_I64:
63
- n = 64 / TCG_TARGET_REG_BITS;
64
- break;
65
- case TCG_TYPE_I128:
66
- n = 128 / TCG_TARGET_REG_BITS;
67
- break;
68
- default:
69
- g_assert_not_reached();
70
+ ts = &s->temps[idx];
71
+ ts->temp_allocated = 1;
72
+ tcg_debug_assert(ts->base_type == type);
73
+ tcg_debug_assert(ts->kind == kind);
74
+ goto done;
63
}
75
}
64
} else {
76
+ } else {
65
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
77
+ tcg_debug_assert(kind == TEMP_TB);
66
if (rm_from_page_list) {
78
+ }
67
p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
79
68
tb_page_remove(p, tb);
80
- ts = tcg_temp_alloc(s);
69
- invalidate_page_bitmap(p);
81
- ts->base_type = type;
70
if (tb->page_addr[1] != -1) {
82
- ts->temp_allocated = 1;
71
p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
83
- ts->kind = kind;
72
tb_page_remove(p, tb);
84
+ switch (type) {
73
- invalidate_page_bitmap(p);
85
+ case TCG_TYPE_I32:
86
+ case TCG_TYPE_V64:
87
+ case TCG_TYPE_V128:
88
+ case TCG_TYPE_V256:
89
+ n = 1;
90
+ break;
91
+ case TCG_TYPE_I64:
92
+ n = 64 / TCG_TARGET_REG_BITS;
93
+ break;
94
+ case TCG_TYPE_I128:
95
+ n = 128 / TCG_TARGET_REG_BITS;
96
+ break;
97
+ default:
98
+ g_assert_not_reached();
99
+ }
100
101
- if (n == 1) {
102
- ts->type = type;
103
- } else {
104
- ts->type = TCG_TYPE_REG;
105
+ ts = tcg_temp_alloc(s);
106
+ ts->base_type = type;
107
+ ts->temp_allocated = 1;
108
+ ts->kind = kind;
109
110
- for (i = 1; i < n; ++i) {
111
- TCGTemp *ts2 = tcg_temp_alloc(s);
112
+ if (n == 1) {
113
+ ts->type = type;
114
+ } else {
115
+ ts->type = TCG_TYPE_REG;
116
117
- tcg_debug_assert(ts2 == ts + i);
118
- ts2->base_type = type;
119
- ts2->type = TCG_TYPE_REG;
120
- ts2->temp_allocated = 1;
121
- ts2->temp_subindex = i;
122
- ts2->kind = kind;
123
- }
124
+ for (int i = 1; i < n; ++i) {
125
+ TCGTemp *ts2 = tcg_temp_alloc(s);
126
+
127
+ tcg_debug_assert(ts2 == ts + i);
128
+ ts2->base_type = type;
129
+ ts2->type = TCG_TYPE_REG;
130
+ ts2->temp_allocated = 1;
131
+ ts2->temp_subindex = i;
132
+ ts2->kind = kind;
74
}
133
}
75
}
134
}
76
135
77
@@ -XXX,XX +XXX,XX @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
136
+ done:
78
}
137
#if defined(CONFIG_DEBUG_TCG)
138
s->temps_in_use++;
139
#endif
140
@@ -XXX,XX +XXX,XX @@ TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match)
141
void tcg_temp_free_internal(TCGTemp *ts)
142
{
143
TCGContext *s = tcg_ctx;
144
- int k, idx;
145
146
switch (ts->kind) {
147
case TEMP_CONST:
148
@@ -XXX,XX +XXX,XX @@ void tcg_temp_free_internal(TCGTemp *ts)
149
s->temps_in_use--;
150
#endif
151
152
- idx = temp_idx(ts);
153
- k = ts->base_type + (ts->kind == TEMP_EBB ? 0 : TCG_TYPE_COUNT);
154
- set_bit(idx, s->free_temps[k].l);
155
+ if (ts->kind == TEMP_EBB) {
156
+ int idx = temp_idx(ts);
157
+ set_bit(idx, s->free_temps[ts->base_type].l);
158
+ }
79
}
159
}
80
160
81
-#ifdef CONFIG_SOFTMMU
161
TCGTemp *tcg_constant_internal(TCGType type, int64_t val)
82
-/* call with @p->lock held */
83
-static void build_page_bitmap(PageDesc *p)
84
-{
85
- int n, tb_start, tb_end;
86
- TranslationBlock *tb;
87
-
88
- assert_page_locked(p);
89
- p->code_bitmap = bitmap_new(TARGET_PAGE_SIZE);
90
-
91
- PAGE_FOR_EACH_TB(p, tb, n) {
92
- /* NOTE: this is subtle as a TB may span two physical pages */
93
- if (n == 0) {
94
- /* NOTE: tb_end may be after the end of the page, but
95
- it is not a problem */
96
- tb_start = tb->pc & ~TARGET_PAGE_MASK;
97
- tb_end = tb_start + tb->size;
98
- if (tb_end > TARGET_PAGE_SIZE) {
99
- tb_end = TARGET_PAGE_SIZE;
100
- }
101
- } else {
102
- tb_start = 0;
103
- tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
104
- }
105
- bitmap_set(p->code_bitmap, tb_start, tb_end - tb_start);
106
- }
107
-}
108
-#endif
109
-
110
/* add the tb in the target page and protect it if necessary
111
*
112
* Called with mmap_lock held for user-mode emulation.
113
@@ -XXX,XX +XXX,XX @@ static inline void tb_page_add(PageDesc *p, TranslationBlock *tb,
114
page_already_protected = p->first_tb != (uintptr_t)NULL;
115
#endif
116
p->first_tb = (uintptr_t)tb | n;
117
- invalidate_page_bitmap(p);
118
119
#if defined(CONFIG_USER_ONLY)
120
/* translator_loop() must have made all TB pages non-writable */
121
@@ -XXX,XX +XXX,XX @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
122
/* remove TB from the page(s) if we couldn't insert it */
123
if (unlikely(existing_tb)) {
124
tb_page_remove(p, tb);
125
- invalidate_page_bitmap(p);
126
if (p2) {
127
tb_page_remove(p2, tb);
128
- invalidate_page_bitmap(p2);
129
}
130
tb = existing_tb;
131
}
132
@@ -XXX,XX +XXX,XX @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
133
#if !defined(CONFIG_USER_ONLY)
134
/* if no code remaining, no need to continue to use slow writes */
135
if (!p->first_tb) {
136
- invalidate_page_bitmap(p);
137
tlb_unprotect_code(start);
138
}
139
#endif
140
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_page_fast(struct page_collection *pages,
141
}
142
143
assert_page_locked(p);
144
- if (!p->code_bitmap &&
145
- ++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD) {
146
- build_page_bitmap(p);
147
- }
148
- if (p->code_bitmap) {
149
- unsigned int nr;
150
- unsigned long b;
151
-
152
- nr = start & ~TARGET_PAGE_MASK;
153
- b = p->code_bitmap[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG - 1));
154
- if (b & ((1 << len) - 1)) {
155
- goto do_invalidate;
156
- }
157
- } else {
158
- do_invalidate:
159
- tb_invalidate_phys_page_range__locked(pages, p, start, start + len,
160
- retaddr);
161
- }
162
+ tb_invalidate_phys_page_range__locked(pages, p, start, start + len,
163
+ retaddr);
164
}
165
#else
166
/* Called with mmap_lock held. If pc is not 0 then it indicates the
167
--
162
--
168
2.34.1
163
2.34.1
169
164
170
165
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Guest front-ends now get temps that span the lifetime of
2
the translation block by default, which avoids accidentally
3
using the temp across branches and invalidating the data.
2
4
3
Before: 35.912 s ± 0.168 s
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
After: 35.565 s ± 0.087 s
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-Id: <20220811151413.3350684-5-alex.bennee@linaro.org>
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Message-Id: <20220923084803.498337-5-clg@kaod.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
7
---
13
accel/tcg/cputlb.c | 15 ++++++---------
8
include/tcg/tcg.h | 8 ++++----
14
1 file changed, 6 insertions(+), 9 deletions(-)
9
1 file changed, 4 insertions(+), 4 deletions(-)
15
10
16
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
11
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/accel/tcg/cputlb.c
13
--- a/include/tcg/tcg.h
19
+++ b/accel/tcg/cputlb.c
14
+++ b/include/tcg/tcg.h
20
@@ -XXX,XX +XXX,XX @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
15
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 tcg_temp_ebb_new_i32(void)
21
static void tlb_fill(CPUState *cpu, target_ulong addr, int size,
16
22
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
17
static inline TCGv_i32 tcg_temp_new_i32(void)
23
{
18
{
24
- CPUClass *cc = CPU_GET_CLASS(cpu);
19
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, TEMP_EBB);
25
bool ok;
20
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, TEMP_TB);
26
21
return temp_tcgv_i32(t);
27
/*
28
* This is not a probe, so only valid return is success; failure
29
* should result in exception + longjmp to the cpu loop.
30
*/
31
- ok = cc->tcg_ops->tlb_fill(cpu, addr, size,
32
- access_type, mmu_idx, false, retaddr);
33
+ ok = cpu->cc->tcg_ops->tlb_fill(cpu, addr, size,
34
+ access_type, mmu_idx, false, retaddr);
35
assert(ok);
36
}
22
}
37
23
38
@@ -XXX,XX +XXX,XX @@ static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
24
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i64 tcg_temp_ebb_new_i64(void)
39
MMUAccessType access_type,
25
40
int mmu_idx, uintptr_t retaddr)
26
static inline TCGv_i64 tcg_temp_new_i64(void)
41
{
27
{
42
- CPUClass *cc = CPU_GET_CLASS(cpu);
28
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, TEMP_EBB);
43
-
29
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, TEMP_TB);
44
- cc->tcg_ops->do_unaligned_access(cpu, addr, access_type, mmu_idx, retaddr);
30
return temp_tcgv_i64(t);
45
+ cpu->cc->tcg_ops->do_unaligned_access(cpu, addr, access_type,
46
+ mmu_idx, retaddr);
47
}
31
}
48
32
49
static inline void cpu_transaction_failed(CPUState *cpu, hwaddr physaddr,
33
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i128 tcg_temp_ebb_new_i128(void)
50
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
34
51
if (!tlb_hit_page(tlb_addr, page_addr)) {
35
static inline TCGv_i128 tcg_temp_new_i128(void)
52
if (!victim_tlb_hit(env, mmu_idx, index, elt_ofs, page_addr)) {
36
{
53
CPUState *cs = env_cpu(env);
37
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, TEMP_EBB);
54
- CPUClass *cc = CPU_GET_CLASS(cs);
38
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, TEMP_TB);
55
39
return temp_tcgv_i128(t);
56
- if (!cc->tcg_ops->tlb_fill(cs, addr, fault_size, access_type,
40
}
57
- mmu_idx, nonfault, retaddr)) {
41
58
+ if (!cs->cc->tcg_ops->tlb_fill(cs, addr, fault_size, access_type,
42
@@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr tcg_temp_ebb_new_ptr(void)
59
+ mmu_idx, nonfault, retaddr)) {
43
60
/* Non-faulting page table read failed. */
44
static inline TCGv_ptr tcg_temp_new_ptr(void)
61
*phost = NULL;
45
{
62
return TLB_INVALID_MASK;
46
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_EBB);
47
+ TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_TB);
48
return temp_tcgv_ptr(t);
49
}
50
63
--
51
--
64
2.34.1
52
2.34.1
65
53
66
54
diff view generated by jsdifflib
New patch
1
Since we now get TEMP_TB temporaries by default, we no longer
2
need to make copies across these loops. These were the only
3
uses of new_tmp_a64_local(), so remove that as well.
1
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/arm/tcg/translate-a64.h | 1 -
9
target/arm/tcg/translate-a64.c | 6 ------
10
target/arm/tcg/translate-sve.c | 32 --------------------------------
11
3 files changed, 39 deletions(-)
12
13
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/tcg/translate-a64.h
16
+++ b/target/arm/tcg/translate-a64.h
17
@@ -XXX,XX +XXX,XX @@
18
#define TARGET_ARM_TRANSLATE_A64_H
19
20
TCGv_i64 new_tmp_a64(DisasContext *s);
21
-TCGv_i64 new_tmp_a64_local(DisasContext *s);
22
TCGv_i64 new_tmp_a64_zero(DisasContext *s);
23
TCGv_i64 cpu_reg(DisasContext *s, int reg);
24
TCGv_i64 cpu_reg_sp(DisasContext *s, int reg);
25
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/tcg/translate-a64.c
28
+++ b/target/arm/tcg/translate-a64.c
29
@@ -XXX,XX +XXX,XX @@ TCGv_i64 new_tmp_a64(DisasContext *s)
30
return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_new_i64();
31
}
32
33
-TCGv_i64 new_tmp_a64_local(DisasContext *s)
34
-{
35
- assert(s->tmp_a64_count < TMP_A64_MAX);
36
- return s->tmp_a64[s->tmp_a64_count++] = tcg_temp_local_new_i64();
37
-}
38
-
39
TCGv_i64 new_tmp_a64_zero(DisasContext *s)
40
{
41
TCGv_i64 t = new_tmp_a64(s);
42
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/tcg/translate-sve.c
45
+++ b/target/arm/tcg/translate-sve.c
46
@@ -XXX,XX +XXX,XX @@ void gen_sve_ldr(DisasContext *s, TCGv_ptr base, int vofs,
47
TCGLabel *loop = gen_new_label();
48
TCGv_ptr tp, i = tcg_const_local_ptr(0);
49
50
- /* Copy the clean address into a local temp, live across the loop. */
51
- t0 = clean_addr;
52
- clean_addr = new_tmp_a64_local(s);
53
- tcg_gen_mov_i64(clean_addr, t0);
54
-
55
- if (base != cpu_env) {
56
- TCGv_ptr b = tcg_temp_local_new_ptr();
57
- tcg_gen_mov_ptr(b, base);
58
- base = b;
59
- }
60
-
61
gen_set_label(loop);
62
63
t0 = tcg_temp_new_i64();
64
@@ -XXX,XX +XXX,XX @@ void gen_sve_ldr(DisasContext *s, TCGv_ptr base, int vofs,
65
66
tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
67
tcg_temp_free_ptr(i);
68
-
69
- if (base != cpu_env) {
70
- tcg_temp_free_ptr(base);
71
- assert(len_remain == 0);
72
- }
73
}
74
75
/*
76
@@ -XXX,XX +XXX,XX @@ void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
77
TCGLabel *loop = gen_new_label();
78
TCGv_ptr tp, i = tcg_const_local_ptr(0);
79
80
- /* Copy the clean address into a local temp, live across the loop. */
81
- t0 = clean_addr;
82
- clean_addr = new_tmp_a64_local(s);
83
- tcg_gen_mov_i64(clean_addr, t0);
84
-
85
- if (base != cpu_env) {
86
- TCGv_ptr b = tcg_temp_local_new_ptr();
87
- tcg_gen_mov_ptr(b, base);
88
- base = b;
89
- }
90
-
91
gen_set_label(loop);
92
93
t0 = tcg_temp_new_i64();
94
@@ -XXX,XX +XXX,XX @@ void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
95
96
tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
97
tcg_temp_free_ptr(i);
98
-
99
- if (base != cpu_env) {
100
- tcg_temp_free_ptr(base);
101
- assert(len_remain == 0);
102
- }
103
}
104
105
/* Predicate register stores can be any multiple of 2. */
106
--
107
2.34.1
diff view generated by jsdifflib
New patch
1
Since tcg_temp_new_* is now identical, use those.
1
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/arm/tcg/translate-sve.c | 6 +++---
7
target/arm/tcg/translate.c | 6 +++---
8
2 files changed, 6 insertions(+), 6 deletions(-)
9
10
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/tcg/translate-sve.c
13
+++ b/target/arm/tcg/translate-sve.c
14
@@ -XXX,XX +XXX,XX @@ static bool do_clast_vector(DisasContext *s, arg_rprr_esz *a, bool before)
15
return true;
16
}
17
18
- last = tcg_temp_local_new_i32();
19
+ last = tcg_temp_new_i32();
20
over = gen_new_label();
21
22
find_last_active(s, last, esz, a->pg);
23
@@ -XXX,XX +XXX,XX @@ void gen_sve_ldr(DisasContext *s, TCGv_ptr base, int vofs,
24
tcg_temp_free_i64(t0);
25
} else {
26
TCGLabel *loop = gen_new_label();
27
- TCGv_ptr tp, i = tcg_const_local_ptr(0);
28
+ TCGv_ptr tp, i = tcg_const_ptr(0);
29
30
gen_set_label(loop);
31
32
@@ -XXX,XX +XXX,XX @@ void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
33
tcg_temp_free_i64(t0);
34
} else {
35
TCGLabel *loop = gen_new_label();
36
- TCGv_ptr tp, i = tcg_const_local_ptr(0);
37
+ TCGv_ptr tp, i = tcg_const_ptr(0);
38
39
gen_set_label(loop);
40
41
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/tcg/translate.c
44
+++ b/target/arm/tcg/translate.c
45
@@ -XXX,XX +XXX,XX @@ static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
46
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
47
}
48
49
- addr = tcg_temp_local_new_i32();
50
+ addr = tcg_temp_new_i32();
51
load_reg_var(s, addr, a->rn);
52
tcg_gen_addi_i32(addr, addr, a->imm);
53
54
@@ -XXX,XX +XXX,XX @@ static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
55
return true;
56
}
57
58
- addr = tcg_temp_local_new_i32();
59
+ addr = tcg_temp_new_i32();
60
load_reg_var(s, addr, a->rn);
61
tcg_gen_addi_i32(addr, addr, a->imm);
62
63
@@ -XXX,XX +XXX,XX @@ static bool trans_LE(DisasContext *s, arg_LE *a)
64
* Decrement by 1 << (4 - LTPSIZE). We need to use a TCG local
65
* so that decr stays live after the brcondi.
66
*/
67
- TCGv_i32 decr = tcg_temp_local_new_i32();
68
+ TCGv_i32 decr = tcg_temp_new_i32();
69
TCGv_i32 ltpsize = load_cpu_field(v7m.ltpsize);
70
tcg_gen_sub_i32(decr, tcg_constant_i32(4), ltpsize);
71
tcg_gen_shl_i32(decr, tcg_constant_i32(1), decr);
72
--
73
2.34.1
74
75
diff view generated by jsdifflib
New patch
1
Since tcg_temp_new is now identical, use that.
1
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/cris/translate.c | 6 +++---
7
target/cris/translate_v10.c.inc | 10 +++++-----
8
2 files changed, 8 insertions(+), 8 deletions(-)
9
10
diff --git a/target/cris/translate.c b/target/cris/translate.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/cris/translate.c
13
+++ b/target/cris/translate.c
14
@@ -XXX,XX +XXX,XX @@ static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
15
LOG_DIS("bound.%c $r%u, $r%u\n",
16
memsize_char(size), dc->op1, dc->op2);
17
cris_cc_mask(dc, CC_MASK_NZ);
18
- l0 = tcg_temp_local_new();
19
+ l0 = tcg_temp_new();
20
dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
21
cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
22
tcg_temp_free(l0);
23
@@ -XXX,XX +XXX,XX @@ static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
24
dc->op1, dc->postinc ? "+]" : "]",
25
dc->op2);
26
27
- l[0] = tcg_temp_local_new();
28
- l[1] = tcg_temp_local_new();
29
+ l[0] = tcg_temp_new();
30
+ l[1] = tcg_temp_new();
31
insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
32
cris_cc_mask(dc, CC_MASK_NZ);
33
cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
34
diff --git a/target/cris/translate_v10.c.inc b/target/cris/translate_v10.c.inc
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/cris/translate_v10.c.inc
37
+++ b/target/cris/translate_v10.c.inc
38
@@ -XXX,XX +XXX,XX @@ static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
39
unsigned int size, int mem_index)
40
{
41
TCGLabel *l1 = gen_new_label();
42
- TCGv taddr = tcg_temp_local_new();
43
- TCGv tval = tcg_temp_local_new();
44
- TCGv t1 = tcg_temp_local_new();
45
+ TCGv taddr = tcg_temp_new();
46
+ TCGv tval = tcg_temp_new();
47
+ TCGv t1 = tcg_temp_new();
48
dc->postinc = 0;
49
cris_evaluate_flags(dc);
50
51
@@ -XXX,XX +XXX,XX @@ static void dec10_reg_bound(DisasContext *dc, int size)
52
{
53
TCGv t;
54
55
- t = tcg_temp_local_new();
56
+ t = tcg_temp_new();
57
t_gen_zext(t, cpu_R[dc->src], size);
58
cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
59
tcg_temp_free(t);
60
@@ -XXX,XX +XXX,XX @@ static int dec10_ind_bound(CPUCRISState *env, DisasContext *dc,
61
int rd = dc->dst;
62
TCGv t;
63
64
- t = tcg_temp_local_new();
65
+ t = tcg_temp_new();
66
insn_len += dec10_prep_move_m(env, dc, 0, size, t);
67
cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4);
68
if (dc->dst == 15) {
69
--
70
2.34.1
71
72
diff view generated by jsdifflib
New patch
1
1
Since tcg_temp_new_* is now identical, use those.
2
3
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
target/hexagon/idef-parser/README.rst | 4 ++--
8
target/hexagon/gen_tcg.h | 4 ++--
9
target/hexagon/genptr.c | 16 ++++++++--------
10
target/hexagon/idef-parser/parser-helpers.c | 4 ++--
11
target/hexagon/translate.c | 2 +-
12
target/hexagon/README | 8 ++++----
13
target/hexagon/gen_tcg_funcs.py | 18 +++++++-----------
14
7 files changed, 26 insertions(+), 30 deletions(-)
15
16
diff --git a/target/hexagon/idef-parser/README.rst b/target/hexagon/idef-parser/README.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/hexagon/idef-parser/README.rst
19
+++ b/target/hexagon/idef-parser/README.rst
20
@@ -XXX,XX +XXX,XX @@ generators the previous declarations are mapped to
21
22
::
23
24
- int var1; -> TCGv_i32 var1 = tcg_temp_local_new_i32();
25
+ int var1; -> TCGv_i32 var1 = tcg_temp_new_i32();
26
27
- int var2 = 0; -> TCGv_i32 var1 = tcg_temp_local_new_i32();
28
+ int var2 = 0; -> TCGv_i32 var1 = tcg_temp_new_i32();
29
tcg_gen_movi_i32(j, ((int64_t) 0ULL));
30
31
which are later automatically freed at the end of the function they're declared
32
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/hexagon/gen_tcg.h
35
+++ b/target/hexagon/gen_tcg.h
36
@@ -XXX,XX +XXX,XX @@
37
*/
38
#define fGEN_TCG_PRED_LOAD(GET_EA, PRED, SIZE, SIGN) \
39
do { \
40
- TCGv LSB = tcg_temp_local_new(); \
41
+ TCGv LSB = tcg_temp_new(); \
42
TCGLabel *label = gen_new_label(); \
43
tcg_gen_movi_tl(EA, 0); \
44
PRED; \
45
@@ -XXX,XX +XXX,XX @@
46
/* Predicated loads into a register pair */
47
#define fGEN_TCG_PRED_LOAD_PAIR(GET_EA, PRED) \
48
do { \
49
- TCGv LSB = tcg_temp_local_new(); \
50
+ TCGv LSB = tcg_temp_new(); \
51
TCGLabel *label = gen_new_label(); \
52
tcg_gen_movi_tl(EA, 0); \
53
PRED; \
54
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/hexagon/genptr.c
57
+++ b/target/hexagon/genptr.c
58
@@ -XXX,XX +XXX,XX @@ static void gen_cond_call(DisasContext *ctx, TCGv pred,
59
TCGCond cond, int pc_off)
60
{
61
TCGv next_PC;
62
- TCGv lsb = tcg_temp_local_new();
63
+ TCGv lsb = tcg_temp_new();
64
TCGLabel *skip = gen_new_label();
65
tcg_gen_andi_tl(lsb, pred, 1);
66
gen_write_new_pc_pcrel(ctx, pc_off, cond, lsb);
67
@@ -XXX,XX +XXX,XX @@ static void gen_cond_call(DisasContext *ctx, TCGv pred,
68
69
static void gen_endloop0(DisasContext *ctx)
70
{
71
- TCGv lpcfg = tcg_temp_local_new();
72
+ TCGv lpcfg = tcg_temp_new();
73
74
GET_USR_FIELD(USR_LPCFG, lpcfg);
75
76
@@ -XXX,XX +XXX,XX @@ static void gen_sar(TCGv dst, TCGv src, TCGv shift_amt)
77
/* Bidirectional shift right with saturation */
78
static void gen_asr_r_r_sat(TCGv RdV, TCGv RsV, TCGv RtV)
79
{
80
- TCGv shift_amt = tcg_temp_local_new();
81
+ TCGv shift_amt = tcg_temp_new();
82
TCGLabel *positive = gen_new_label();
83
TCGLabel *done = gen_new_label();
84
85
@@ -XXX,XX +XXX,XX @@ static void gen_asr_r_r_sat(TCGv RdV, TCGv RsV, TCGv RtV)
86
/* Bidirectional shift left with saturation */
87
static void gen_asl_r_r_sat(TCGv RdV, TCGv RsV, TCGv RtV)
88
{
89
- TCGv shift_amt = tcg_temp_local_new();
90
+ TCGv shift_amt = tcg_temp_new();
91
TCGLabel *positive = gen_new_label();
92
TCGLabel *done = gen_new_label();
93
94
@@ -XXX,XX +XXX,XX @@ static void gen_log_vreg_write(DisasContext *ctx, intptr_t srcoff, int num,
95
intptr_t dstoff;
96
97
if (is_predicated) {
98
- TCGv cancelled = tcg_temp_local_new();
99
+ TCGv cancelled = tcg_temp_new();
100
label_end = gen_new_label();
101
102
/* Don't do anything if the slot was cancelled */
103
@@ -XXX,XX +XXX,XX @@ static void gen_log_qreg_write(intptr_t srcoff, int num, int vnew,
104
intptr_t dstoff;
105
106
if (is_predicated) {
107
- TCGv cancelled = tcg_temp_local_new();
108
+ TCGv cancelled = tcg_temp_new();
109
label_end = gen_new_label();
110
111
/* Don't do anything if the slot was cancelled */
112
@@ -XXX,XX +XXX,XX @@ void gen_satu_i64_ovfl(TCGv ovfl, TCGv_i64 dest, TCGv_i64 source, int width)
113
/* Implements the fADDSAT64 macro in TCG */
114
void gen_add_sat_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
115
{
116
- TCGv_i64 sum = tcg_temp_local_new_i64();
117
+ TCGv_i64 sum = tcg_temp_new_i64();
118
TCGv_i64 xor = tcg_temp_new_i64();
119
TCGv_i64 cond1 = tcg_temp_new_i64();
120
- TCGv_i64 cond2 = tcg_temp_local_new_i64();
121
+ TCGv_i64 cond2 = tcg_temp_new_i64();
122
TCGv_i64 cond3 = tcg_temp_new_i64();
123
TCGv_i64 mask = tcg_constant_i64(0x8000000000000000ULL);
124
TCGv_i64 max_pos = tcg_constant_i64(0x7FFFFFFFFFFFFFFFLL);
125
diff --git a/target/hexagon/idef-parser/parser-helpers.c b/target/hexagon/idef-parser/parser-helpers.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/hexagon/idef-parser/parser-helpers.c
128
+++ b/target/hexagon/idef-parser/parser-helpers.c
129
@@ -XXX,XX +XXX,XX @@ HexValue gen_tmp_local(Context *c,
130
rvalue.is_manual = false;
131
rvalue.tmp.index = c->inst.tmp_count;
132
OUT(c, locp, "TCGv_i", &bit_width, " tmp_", &c->inst.tmp_count,
133
- " = tcg_temp_local_new_i", &bit_width, "();\n");
134
+ " = tcg_temp_new_i", &bit_width, "();\n");
135
c->inst.tmp_count++;
136
return rvalue;
137
}
138
@@ -XXX,XX +XXX,XX @@ void gen_varid_allocate(Context *c,
139
new_var.signedness = signedness;
140
141
EMIT_HEAD(c, "TCGv_%s %s", bit_suffix, varid->var.name->str);
142
- EMIT_HEAD(c, " = tcg_temp_local_new_%s();\n", bit_suffix);
143
+ EMIT_HEAD(c, " = tcg_temp_new_%s();\n", bit_suffix);
144
g_array_append_val(c->inst.allocated, new_var);
145
}
146
147
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/target/hexagon/translate.c
150
+++ b/target/hexagon/translate.c
151
@@ -XXX,XX +XXX,XX @@ void process_store(DisasContext *ctx, int slot_num)
152
tcg_temp_free(cancelled);
153
}
154
{
155
- TCGv address = tcg_temp_local_new();
156
+ TCGv address = tcg_temp_new();
157
tcg_gen_mov_tl(address, hex_store_addr[slot_num]);
158
159
/*
160
diff --git a/target/hexagon/README b/target/hexagon/README
161
index XXXXXXX..XXXXXXX 100644
162
--- a/target/hexagon/README
163
+++ b/target/hexagon/README
164
@@ -XXX,XX +XXX,XX @@ tcg_funcs_generated.c.inc
165
Insn *insn,
166
Packet *pkt)
167
{
168
- TCGv RdV = tcg_temp_local_new();
169
+ TCGv RdV = tcg_temp_new();
170
const int RdN = insn->regno[0];
171
TCGv RsV = hex_gpr[insn->regno[1]];
172
TCGv RtV = hex_gpr[insn->regno[2]];
173
@@ -XXX,XX +XXX,XX @@ istruction.
174
const int VdN = insn->regno[0];
175
const intptr_t VdV_off =
176
ctx_future_vreg_off(ctx, VdN, 1, true);
177
- TCGv_ptr VdV = tcg_temp_local_new_ptr();
178
+ TCGv_ptr VdV = tcg_temp_new_ptr();
179
tcg_gen_addi_ptr(VdV, cpu_env, VdV_off);
180
const int VuN = insn->regno[1];
181
const intptr_t VuV_off =
182
vreg_src_off(ctx, VuN);
183
- TCGv_ptr VuV = tcg_temp_local_new_ptr();
184
+ TCGv_ptr VuV = tcg_temp_new_ptr();
185
const int VvN = insn->regno[2];
186
const intptr_t VvV_off =
187
vreg_src_off(ctx, VvN);
188
- TCGv_ptr VvV = tcg_temp_local_new_ptr();
189
+ TCGv_ptr VvV = tcg_temp_new_ptr();
190
tcg_gen_addi_ptr(VuV, cpu_env, VuV_off);
191
tcg_gen_addi_ptr(VvV, cpu_env, VvV_off);
192
TCGv slot = tcg_constant_tl(insn->slot);
193
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
194
index XXXXXXX..XXXXXXX 100755
195
--- a/target/hexagon/gen_tcg_funcs.py
196
+++ b/target/hexagon/gen_tcg_funcs.py
197
@@ -XXX,XX +XXX,XX @@
198
## Helpers for gen_tcg_func
199
##
200
def gen_decl_ea_tcg(f, tag):
201
- if ('A_CONDEXEC' in hex_common.attribdict[tag] or
202
- 'A_LOAD' in hex_common.attribdict[tag]):
203
- f.write(" TCGv EA = tcg_temp_local_new();\n")
204
- else:
205
- f.write(" TCGv EA = tcg_temp_new();\n")
206
+ f.write(" TCGv EA = tcg_temp_new();\n")
207
208
def gen_free_ea_tcg(f):
209
f.write(" tcg_temp_free(EA);\n")
210
211
def genptr_decl_pair_writable(f, tag, regtype, regid, regno):
212
regN="%s%sN" % (regtype,regid)
213
- f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \
214
+ f.write(" TCGv_i64 %s%sV = tcg_temp_new_i64();\n" % \
215
(regtype, regid))
216
if (regtype == "C"):
217
f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
218
@@ -XXX,XX +XXX,XX @@ def genptr_decl_pair_writable(f, tag, regtype, regid, regno):
219
220
def genptr_decl_writable(f, tag, regtype, regid, regno):
221
regN="%s%sN" % (regtype,regid)
222
- f.write(" TCGv %s%sV = tcg_temp_local_new();\n" % \
223
+ f.write(" TCGv %s%sV = tcg_temp_new();\n" % \
224
(regtype, regid))
225
if (regtype == "C"):
226
f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
227
@@ -XXX,XX +XXX,XX @@ def genptr_decl(f, tag, regtype, regid, regno):
228
regN="%s%sN" % (regtype,regid)
229
if (regtype == "R"):
230
if (regid in {"ss", "tt"}):
231
- f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \
232
+ f.write(" TCGv_i64 %s%sV = tcg_temp_new_i64();\n" % \
233
(regtype, regid))
234
f.write(" const int %s = insn->regno[%d];\n" % \
235
(regN, regno))
236
@@ -XXX,XX +XXX,XX @@ def genptr_decl(f, tag, regtype, regid, regno):
237
print("Bad register parse: ", regtype, regid)
238
elif (regtype == "C"):
239
if (regid == "ss"):
240
- f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \
241
+ f.write(" TCGv_i64 %s%sV = tcg_temp_new_i64();\n" % \
242
(regtype, regid))
243
f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
244
(regN, regno))
245
elif (regid == "dd"):
246
genptr_decl_pair_writable(f, tag, regtype, regid, regno)
247
elif (regid == "s"):
248
- f.write(" TCGv %s%sV = tcg_temp_local_new();\n" % \
249
+ f.write(" TCGv %s%sV = tcg_temp_new();\n" % \
250
(regtype, regid))
251
f.write(" const int %s%sN = insn->regno[%d] + HEX_REG_SA0;\n" % \
252
(regtype, regid, regno))
253
@@ -XXX,XX +XXX,XX @@ def genptr_dst_write_opn(f,regtype, regid, tag):
254
## We produce:
255
## static void generate_A2_add(DisasContext *ctx)
256
## {
257
-## TCGv RdV = tcg_temp_local_new();
258
+## TCGv RdV = tcg_temp_new();
259
## const int RdN = insn->regno[0];
260
## TCGv RsV = hex_gpr[insn->regno[1]];
261
## TCGv RtV = hex_gpr[insn->regno[2]];
262
--
263
2.34.1
264
265
diff view generated by jsdifflib
New patch
1
This is now equivalent to gen_tmp.
1
2
3
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
target/hexagon/idef-parser/parser-helpers.c | 24 ++-------------------
8
1 file changed, 2 insertions(+), 22 deletions(-)
9
10
diff --git a/target/hexagon/idef-parser/parser-helpers.c b/target/hexagon/idef-parser/parser-helpers.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/hexagon/idef-parser/parser-helpers.c
13
+++ b/target/hexagon/idef-parser/parser-helpers.c
14
@@ -XXX,XX +XXX,XX @@ HexValue gen_tmp(Context *c,
15
return rvalue;
16
}
17
18
-HexValue gen_tmp_local(Context *c,
19
- YYLTYPE *locp,
20
- unsigned bit_width,
21
- HexSignedness signedness)
22
-{
23
- HexValue rvalue;
24
- assert(bit_width == 32 || bit_width == 64);
25
- memset(&rvalue, 0, sizeof(HexValue));
26
- rvalue.type = TEMP;
27
- rvalue.bit_width = bit_width;
28
- rvalue.signedness = signedness;
29
- rvalue.is_dotnew = false;
30
- rvalue.is_manual = false;
31
- rvalue.tmp.index = c->inst.tmp_count;
32
- OUT(c, locp, "TCGv_i", &bit_width, " tmp_", &c->inst.tmp_count,
33
- " = tcg_temp_new_i", &bit_width, "();\n");
34
- c->inst.tmp_count++;
35
- return rvalue;
36
-}
37
-
38
HexValue gen_tmp_value(Context *c,
39
YYLTYPE *locp,
40
const char *value,
41
@@ -XXX,XX +XXX,XX @@ HexValue gen_rvalue_sat(Context *c, YYLTYPE *locp, HexSat *sat,
42
assert_signedness(c, locp, sat->signedness);
43
44
unsigned_str = (sat->signedness == UNSIGNED) ? "u" : "";
45
- res = gen_tmp_local(c, locp, value->bit_width, sat->signedness);
46
- ovfl = gen_tmp_local(c, locp, 32, sat->signedness);
47
+ res = gen_tmp(c, locp, value->bit_width, sat->signedness);
48
+ ovfl = gen_tmp(c, locp, 32, sat->signedness);
49
OUT(c, locp, "gen_sat", unsigned_str, "_", bit_suffix, "_ovfl(");
50
OUT(c, locp, &ovfl, ", ", &res, ", ", value, ", ", &width->imm.value,
51
");\n");
52
--
53
2.34.1
54
55
diff view generated by jsdifflib
New patch
1
This wasn't actually used at all, just some unused
2
macro re-definitions.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
target/hppa/translate.c | 3 ---
8
1 file changed, 3 deletions(-)
9
10
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/hppa/translate.c
13
+++ b/target/hppa/translate.c
14
@@ -XXX,XX +XXX,XX @@
15
#undef TCGv
16
#undef tcg_temp_new
17
#undef tcg_global_mem_new
18
-#undef tcg_temp_local_new
19
#undef tcg_temp_free
20
21
#if TARGET_LONG_BITS == 64
22
@@ -XXX,XX +XXX,XX @@
23
24
#define tcg_temp_new tcg_temp_new_i64
25
#define tcg_global_mem_new tcg_global_mem_new_i64
26
-#define tcg_temp_local_new tcg_temp_local_new_i64
27
#define tcg_temp_free tcg_temp_free_i64
28
29
#define tcg_gen_movi_reg tcg_gen_movi_i64
30
@@ -XXX,XX +XXX,XX @@
31
#define TCGv_reg TCGv_i32
32
#define tcg_temp_new tcg_temp_new_i32
33
#define tcg_global_mem_new tcg_global_mem_new_i32
34
-#define tcg_temp_local_new tcg_temp_local_new_i32
35
#define tcg_temp_free tcg_temp_free_i32
36
37
#define tcg_gen_movi_reg tcg_gen_movi_i32
38
--
39
2.34.1
40
41
diff view generated by jsdifflib
New patch
1
Since tcg_temp_new is now identical, use that.
2
In some cases we can avoid a copy from A0 or T0.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
target/i386/tcg/translate.c | 27 +++++++++------------------
8
1 file changed, 9 insertions(+), 18 deletions(-)
9
10
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/i386/tcg/translate.c
13
+++ b/target/i386/tcg/translate.c
14
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
15
if (mod == 3) {
16
goto illegal_op;
17
}
18
- a0 = tcg_temp_local_new();
19
- t0 = tcg_temp_local_new();
20
+ a0 = s->A0;
21
+ t0 = s->T0;
22
label1 = gen_new_label();
23
24
- tcg_gen_mov_tl(a0, s->A0);
25
- tcg_gen_mov_tl(t0, s->T0);
26
-
27
gen_set_label(label1);
28
t1 = tcg_temp_new();
29
t2 = tcg_temp_new();
30
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
31
tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
32
33
tcg_temp_free(t2);
34
- tcg_temp_free(a0);
35
tcg_gen_neg_tl(s->T0, t0);
36
- tcg_temp_free(t0);
37
} else {
38
tcg_gen_neg_tl(s->T0, s->T0);
39
if (mod != 3) {
40
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
41
#endif
42
{
43
TCGLabel *label1;
44
- TCGv t0, t1, t2, a0;
45
+ TCGv t0, t1, t2;
46
47
if (!PE(s) || VM86(s))
48
goto illegal_op;
49
- t0 = tcg_temp_local_new();
50
- t1 = tcg_temp_local_new();
51
- t2 = tcg_temp_local_new();
52
+ t0 = tcg_temp_new();
53
+ t1 = tcg_temp_new();
54
+ t2 = tcg_temp_new();
55
ot = MO_16;
56
modrm = x86_ldub_code(env, s);
57
reg = (modrm >> 3) & 7;
58
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
59
if (mod != 3) {
60
gen_lea_modrm(env, s, modrm);
61
gen_op_ld_v(s, ot, t0, s->A0);
62
- a0 = tcg_temp_local_new();
63
- tcg_gen_mov_tl(a0, s->A0);
64
} else {
65
gen_op_mov_v_reg(s, ot, t0, rm);
66
- a0 = NULL;
67
}
68
gen_op_mov_v_reg(s, ot, t1, reg);
69
tcg_gen_andi_tl(s->tmp0, t0, 3);
70
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
71
tcg_gen_movi_tl(t2, CC_Z);
72
gen_set_label(label1);
73
if (mod != 3) {
74
- gen_op_st_v(s, ot, t0, a0);
75
- tcg_temp_free(a0);
76
+ gen_op_st_v(s, ot, t0, s->A0);
77
} else {
78
gen_op_mov_reg_v(s, ot, rm, t0);
79
}
80
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
81
modrm = x86_ldub_code(env, s);
82
reg = ((modrm >> 3) & 7) | REX_R(s);
83
gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
84
- t0 = tcg_temp_local_new();
85
+ t0 = tcg_temp_new();
86
gen_update_cc_op(s);
87
if (b == 0x102) {
88
gen_helper_lar(t0, cpu_env, s->T0);
89
@@ -XXX,XX +XXX,XX @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
90
dc->tmp2_i32 = tcg_temp_new_i32();
91
dc->tmp3_i32 = tcg_temp_new_i32();
92
dc->tmp4 = tcg_temp_new();
93
- dc->cc_srcT = tcg_temp_local_new();
94
+ dc->cc_srcT = tcg_temp_new();
95
}
96
97
static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
98
--
99
2.34.1
100
101
diff view generated by jsdifflib
New patch
1
Since tcg_temp_new is now identical, use that.
1
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/mips/tcg/translate.c | 57 ++++++------------------
7
target/mips/tcg/nanomips_translate.c.inc | 4 +-
8
2 files changed, 16 insertions(+), 45 deletions(-)
9
10
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/mips/tcg/translate.c
13
+++ b/target/mips/tcg/translate.c
14
@@ -XXX,XX +XXX,XX @@ static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
15
switch (opc) {
16
case OPC_ADDI:
17
{
18
- TCGv t0 = tcg_temp_local_new();
19
+ TCGv t0 = tcg_temp_new();
20
TCGv t1 = tcg_temp_new();
21
TCGv t2 = tcg_temp_new();
22
TCGLabel *l1 = gen_new_label();
23
@@ -XXX,XX +XXX,XX @@ static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
24
#if defined(TARGET_MIPS64)
25
case OPC_DADDI:
26
{
27
- TCGv t0 = tcg_temp_local_new();
28
+ TCGv t0 = tcg_temp_new();
29
TCGv t1 = tcg_temp_new();
30
TCGv t2 = tcg_temp_new();
31
TCGLabel *l1 = gen_new_label();
32
@@ -XXX,XX +XXX,XX @@ static void gen_arith(DisasContext *ctx, uint32_t opc,
33
switch (opc) {
34
case OPC_ADD:
35
{
36
- TCGv t0 = tcg_temp_local_new();
37
+ TCGv t0 = tcg_temp_new();
38
TCGv t1 = tcg_temp_new();
39
TCGv t2 = tcg_temp_new();
40
TCGLabel *l1 = gen_new_label();
41
@@ -XXX,XX +XXX,XX @@ static void gen_arith(DisasContext *ctx, uint32_t opc,
42
break;
43
case OPC_SUB:
44
{
45
- TCGv t0 = tcg_temp_local_new();
46
+ TCGv t0 = tcg_temp_new();
47
TCGv t1 = tcg_temp_new();
48
TCGv t2 = tcg_temp_new();
49
TCGLabel *l1 = gen_new_label();
50
@@ -XXX,XX +XXX,XX @@ static void gen_arith(DisasContext *ctx, uint32_t opc,
51
#if defined(TARGET_MIPS64)
52
case OPC_DADD:
53
{
54
- TCGv t0 = tcg_temp_local_new();
55
+ TCGv t0 = tcg_temp_new();
56
TCGv t1 = tcg_temp_new();
57
TCGv t2 = tcg_temp_new();
58
TCGLabel *l1 = gen_new_label();
59
@@ -XXX,XX +XXX,XX @@ static void gen_arith(DisasContext *ctx, uint32_t opc,
60
break;
61
case OPC_DSUB:
62
{
63
- TCGv t0 = tcg_temp_local_new();
64
+ TCGv t0 = tcg_temp_new();
65
TCGv t1 = tcg_temp_new();
66
TCGv t2 = tcg_temp_new();
67
TCGLabel *l1 = gen_new_label();
68
@@ -XXX,XX +XXX,XX @@ static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
69
return;
70
}
71
72
- switch (opc) {
73
- case OPC_MULT_G_2E:
74
- case OPC_MULT_G_2F:
75
- case OPC_MULTU_G_2E:
76
- case OPC_MULTU_G_2F:
77
-#if defined(TARGET_MIPS64)
78
- case OPC_DMULT_G_2E:
79
- case OPC_DMULT_G_2F:
80
- case OPC_DMULTU_G_2E:
81
- case OPC_DMULTU_G_2F:
82
-#endif
83
- t0 = tcg_temp_new();
84
- t1 = tcg_temp_new();
85
- break;
86
- default:
87
- t0 = tcg_temp_local_new();
88
- t1 = tcg_temp_local_new();
89
- break;
90
- }
91
-
92
+ t0 = tcg_temp_new();
93
+ t1 = tcg_temp_new();
94
gen_load_gpr(t0, rs);
95
gen_load_gpr(t1, rt);
96
97
@@ -XXX,XX +XXX,XX @@ static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
98
TCGCond cond;
99
100
opc = MASK_LMMI(ctx->opcode);
101
- switch (opc) {
102
- case OPC_ADD_CP2:
103
- case OPC_SUB_CP2:
104
- case OPC_DADD_CP2:
105
- case OPC_DSUB_CP2:
106
- t0 = tcg_temp_local_new_i64();
107
- t1 = tcg_temp_local_new_i64();
108
- break;
109
- default:
110
- t0 = tcg_temp_new_i64();
111
- t1 = tcg_temp_new_i64();
112
- break;
113
- }
114
-
115
check_cp1_enabled(ctx);
116
+
117
+ t0 = tcg_temp_new_i64();
118
+ t1 = tcg_temp_new_i64();
119
gen_load_fpr64(ctx, t0, rs);
120
gen_load_fpr64(ctx, t1, rt);
121
122
@@ -XXX,XX +XXX,XX @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
123
int u, int sel, int h)
124
{
125
int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
126
- TCGv t0 = tcg_temp_local_new();
127
+ TCGv t0 = tcg_temp_new();
128
129
if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
130
((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
131
@@ -XXX,XX +XXX,XX @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
132
int u, int sel, int h)
133
{
134
int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
135
- TCGv t0 = tcg_temp_local_new();
136
+ TCGv t0 = tcg_temp_new();
137
138
gen_load_gpr(t0, rt);
139
if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
140
@@ -XXX,XX +XXX,XX @@ static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
141
case OPC_ALNV_PS:
142
check_ps(ctx);
143
{
144
- TCGv t0 = tcg_temp_local_new();
145
+ TCGv t0 = tcg_temp_new();
146
TCGv_i32 fp = tcg_temp_new_i32();
147
TCGv_i32 fph = tcg_temp_new_i32();
148
TCGLabel *l1 = gen_new_label();
149
diff --git a/target/mips/tcg/nanomips_translate.c.inc b/target/mips/tcg/nanomips_translate.c.inc
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/mips/tcg/nanomips_translate.c.inc
152
+++ b/target/mips/tcg/nanomips_translate.c.inc
153
@@ -XXX,XX +XXX,XX @@ static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
154
static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
155
uint32_t reg1, uint32_t reg2, bool eva)
156
{
157
- TCGv taddr = tcg_temp_local_new();
158
- TCGv lladdr = tcg_temp_local_new();
159
+ TCGv taddr = tcg_temp_new();
160
+ TCGv lladdr = tcg_temp_new();
161
TCGv_i64 tval = tcg_temp_new_i64();
162
TCGv_i64 llval = tcg_temp_new_i64();
163
TCGv_i64 val = tcg_temp_new_i64();
164
--
165
2.34.1
166
167
diff view generated by jsdifflib
New patch
1
Since tcg_temp_new is now identical, use that.
1
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/ppc/translate.c | 6 +++---
7
target/ppc/translate/spe-impl.c.inc | 8 ++++----
8
target/ppc/translate/vmx-impl.c.inc | 4 ++--
9
3 files changed, 9 insertions(+), 9 deletions(-)
10
11
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/ppc/translate.c
14
+++ b/target/ppc/translate.c
15
@@ -XXX,XX +XXX,XX @@ static void gen_bcond(DisasContext *ctx, int type)
16
TCGv target;
17
18
if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
19
- target = tcg_temp_local_new();
20
+ target = tcg_temp_new();
21
if (type == BCOND_CTR) {
22
tcg_gen_mov_tl(target, cpu_ctr);
23
} else if (type == BCOND_TAR) {
24
@@ -XXX,XX +XXX,XX @@ static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
25
{
26
TCGv t0, t1;
27
28
- t0 = tcg_temp_local_new();
29
- t1 = tcg_temp_local_new();
30
+ t0 = tcg_temp_new();
31
+ t1 = tcg_temp_new();
32
33
switch (opc3 & 0x0D) {
34
case 0x05:
35
diff --git a/target/ppc/translate/spe-impl.c.inc b/target/ppc/translate/spe-impl.c.inc
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/ppc/translate/spe-impl.c.inc
38
+++ b/target/ppc/translate/spe-impl.c.inc
39
@@ -XXX,XX +XXX,XX @@ static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
40
{
41
TCGLabel *l1 = gen_new_label();
42
TCGLabel *l2 = gen_new_label();
43
- TCGv_i32 t0 = tcg_temp_local_new_i32();
44
+ TCGv_i32 t0 = tcg_temp_new_i32();
45
46
/* No error here: 6 bits are used */
47
tcg_gen_andi_i32(t0, arg2, 0x3F);
48
@@ -XXX,XX +XXX,XX @@ static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
49
{
50
TCGLabel *l1 = gen_new_label();
51
TCGLabel *l2 = gen_new_label();
52
- TCGv_i32 t0 = tcg_temp_local_new_i32();
53
+ TCGv_i32 t0 = tcg_temp_new_i32();
54
55
/* No error here: 6 bits are used */
56
tcg_gen_andi_i32(t0, arg2, 0x3F);
57
@@ -XXX,XX +XXX,XX @@ static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
58
{
59
TCGLabel *l1 = gen_new_label();
60
TCGLabel *l2 = gen_new_label();
61
- TCGv_i32 t0 = tcg_temp_local_new_i32();
62
+ TCGv_i32 t0 = tcg_temp_new_i32();
63
64
/* No error here: 6 bits are used */
65
tcg_gen_andi_i32(t0, arg2, 0x3F);
66
@@ -XXX,XX +XXX,XX @@ static inline void gen_evsel(DisasContext *ctx)
67
TCGLabel *l2 = gen_new_label();
68
TCGLabel *l3 = gen_new_label();
69
TCGLabel *l4 = gen_new_label();
70
- TCGv_i32 t0 = tcg_temp_local_new_i32();
71
+ TCGv_i32 t0 = tcg_temp_new_i32();
72
73
tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
74
tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
75
diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/ppc/translate/vmx-impl.c.inc
78
+++ b/target/ppc/translate/vmx-impl.c.inc
79
@@ -XXX,XX +XXX,XX @@ static bool do_vcmpq(DisasContext *ctx, arg_VX_bf *a, bool sign)
80
REQUIRE_INSNS_FLAGS2(ctx, ISA310);
81
REQUIRE_VECTOR(ctx);
82
83
- vra = tcg_temp_local_new_i64();
84
- vrb = tcg_temp_local_new_i64();
85
+ vra = tcg_temp_new_i64();
86
+ vrb = tcg_temp_new_i64();
87
gt = gen_new_label();
88
lt = gen_new_label();
89
done = gen_new_label();
90
--
91
2.34.1
92
93
diff view generated by jsdifflib
1
This field is only written, not read; remove it.
1
Since tcg_temp_new_* is now identical, use those.
2
2
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
5
---
8
include/hw/core/cpu.h | 1 -
6
target/xtensa/translate.c | 16 ++++++++--------
9
accel/tcg/cputlb.c | 7 +++----
7
1 file changed, 8 insertions(+), 8 deletions(-)
10
2 files changed, 3 insertions(+), 5 deletions(-)
11
8
12
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
9
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
13
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/core/cpu.h
11
--- a/target/xtensa/translate.c
15
+++ b/include/hw/core/cpu.h
12
+++ b/target/xtensa/translate.c
16
@@ -XXX,XX +XXX,XX @@ struct CPUWatchpoint {
13
@@ -XXX,XX +XXX,XX @@ static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
17
* the memory regions get moved around by io_writex.
14
static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
18
*/
19
typedef struct SavedIOTLB {
20
- hwaddr addr;
21
MemoryRegionSection *section;
22
hwaddr mr_offset;
23
} SavedIOTLB;
24
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/accel/tcg/cputlb.c
27
+++ b/accel/tcg/cputlb.c
28
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUTLBEntryFull *full,
29
* This is read by tlb_plugin_lookup if the fulltlb entry doesn't match
30
* because of the side effect of io_writex changing memory layout.
31
*/
32
-static void save_iotlb_data(CPUState *cs, hwaddr addr,
33
- MemoryRegionSection *section, hwaddr mr_offset)
34
+static void save_iotlb_data(CPUState *cs, MemoryRegionSection *section,
35
+ hwaddr mr_offset)
36
{
15
{
37
#ifdef CONFIG_PLUGIN
16
if (!dc->sar_m32_allocated) {
38
SavedIOTLB *saved = &cs->saved_iotlb;
17
- dc->sar_m32 = tcg_temp_local_new_i32();
39
- saved->addr = addr;
18
+ dc->sar_m32 = tcg_temp_new_i32();
40
saved->section = section;
19
dc->sar_m32_allocated = true;
41
saved->mr_offset = mr_offset;
20
}
42
#endif
21
tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
43
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUTLBEntryFull *full,
22
@@ -XXX,XX +XXX,XX @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
44
* The memory_region_dispatch may trigger a flush/resize
23
if (i == 0 || arg_copy[i].resource != resource) {
45
* so for plugins we save the iotlb_data just in case.
24
resource = arg_copy[i].resource;
46
*/
25
if (arg_copy[i].arg->num_bits <= 32) {
47
- save_iotlb_data(cpu, full->xlat_section, section, mr_offset);
26
- temp = tcg_temp_local_new_i32();
48
+ save_iotlb_data(cpu, section, mr_offset);
27
+ temp = tcg_temp_new_i32();
49
28
tcg_gen_mov_i32(temp, arg_copy[i].arg->in);
50
if (!qemu_mutex_iothread_locked()) {
29
} else if (arg_copy[i].arg->num_bits <= 64) {
51
qemu_mutex_lock_iothread();
30
- temp = tcg_temp_local_new_i64();
31
+ temp = tcg_temp_new_i64();
32
tcg_gen_mov_i64(temp, arg_copy[i].arg->in);
33
} else {
34
g_assert_not_reached();
35
@@ -XXX,XX +XXX,XX @@ static void xtensa_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
36
DisasContext *dc = container_of(dcbase, DisasContext, base);
37
38
if (dc->icount) {
39
- dc->next_icount = tcg_temp_local_new_i32();
40
+ dc->next_icount = tcg_temp_new_i32();
41
}
42
}
43
44
@@ -XXX,XX +XXX,XX @@ static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
45
static void translate_s32c1i(DisasContext *dc, const OpcodeArg arg[],
46
const uint32_t par[])
47
{
48
- TCGv_i32 tmp = tcg_temp_local_new_i32();
49
- TCGv_i32 addr = tcg_temp_local_new_i32();
50
+ TCGv_i32 tmp = tcg_temp_new_i32();
51
+ TCGv_i32 addr = tcg_temp_new_i32();
52
MemOp mop;
53
54
tcg_gen_mov_i32(tmp, arg[0].in);
55
@@ -XXX,XX +XXX,XX @@ static void translate_s32ex(DisasContext *dc, const OpcodeArg arg[],
56
const uint32_t par[])
57
{
58
TCGv_i32 prev = tcg_temp_new_i32();
59
- TCGv_i32 addr = tcg_temp_local_new_i32();
60
- TCGv_i32 res = tcg_temp_local_new_i32();
61
+ TCGv_i32 addr = tcg_temp_new_i32();
62
+ TCGv_i32 res = tcg_temp_new_i32();
63
TCGLabel *label = gen_new_label();
64
MemOp mop;
65
52
--
66
--
53
2.34.1
67
2.34.1
54
68
55
69
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Since tcg_temp_new_i32 is now identical, use that.
2
2
3
This is a heavily used function so lets avoid the cost of
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
CPU_GET_CLASS. On the romulus-bmc run it has a modest effect:
5
6
Before: 36.812 s ± 0.506 s
7
After: 35.912 s ± 0.168 s
8
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-Id: <20220811151413.3350684-4-alex.bennee@linaro.org>
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
Message-Id: <20220923084803.498337-4-clg@kaod.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
---
5
---
16
hw/core/cpu-sysemu.c | 5 ++---
6
include/exec/gen-icount.h | 8 +-------
17
1 file changed, 2 insertions(+), 3 deletions(-)
7
1 file changed, 1 insertion(+), 7 deletions(-)
18
8
19
diff --git a/hw/core/cpu-sysemu.c b/hw/core/cpu-sysemu.c
9
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
20
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/core/cpu-sysemu.c
11
--- a/include/exec/gen-icount.h
22
+++ b/hw/core/cpu-sysemu.c
12
+++ b/include/exec/gen-icount.h
23
@@ -XXX,XX +XXX,XX @@ hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr)
13
@@ -XXX,XX +XXX,XX @@ static inline void gen_io_start(void)
24
14
25
int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs)
15
static inline void gen_tb_start(const TranslationBlock *tb)
26
{
16
{
27
- CPUClass *cc = CPU_GET_CLASS(cpu);
17
- TCGv_i32 count;
28
int ret = 0;
18
-
29
19
- if (tb_cflags(tb) & CF_USE_ICOUNT) {
30
- if (cc->sysemu_ops->asidx_from_attrs) {
20
- count = tcg_temp_local_new_i32();
31
- ret = cc->sysemu_ops->asidx_from_attrs(cpu, attrs);
21
- } else {
32
+ if (cpu->cc->sysemu_ops->asidx_from_attrs) {
22
- count = tcg_temp_new_i32();
33
+ ret = cpu->cc->sysemu_ops->asidx_from_attrs(cpu, attrs);
23
- }
34
assert(ret < cpu->num_ases && ret >= 0);
24
+ TCGv_i32 count = tcg_temp_new_i32();
35
}
25
36
return ret;
26
tcg_gen_ld_i32(count, cpu_env,
27
offsetof(ArchCPU, neg.icount_decr.u32) -
37
--
28
--
38
2.34.1
29
2.34.1
39
30
40
31
diff view generated by jsdifflib
1
This function has two users, who use it incompatibly.
1
These symbols are now unused.
2
In tlb_flush_page_by_mmuidx_async_0, when flushing a
3
single page, we need to flush exactly two pages.
4
In tlb_flush_range_by_mmuidx_async_0, when flushing a
5
range of pages, we need to flush N+1 pages.
6
2
7
This avoids double-flushing of jmp cache pages in a range.
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
5
---
12
accel/tcg/cputlb.c | 25 ++++++++++++++-----------
6
include/tcg/tcg-op.h | 2 --
13
1 file changed, 14 insertions(+), 11 deletions(-)
7
include/tcg/tcg.h | 28 ----------------------------
8
tcg/tcg.c | 16 ----------------
9
3 files changed, 46 deletions(-)
14
10
15
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
11
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/tcg/cputlb.c
13
--- a/include/tcg/tcg-op.h
18
+++ b/accel/tcg/cputlb.c
14
+++ b/include/tcg/tcg-op.h
19
@@ -XXX,XX +XXX,XX @@ static void tb_jmp_cache_clear_page(CPUState *cpu, target_ulong page_addr)
15
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_plugin_cb_end(void)
20
}
16
#if TARGET_LONG_BITS == 32
17
#define tcg_temp_new() tcg_temp_new_i32()
18
#define tcg_global_mem_new tcg_global_mem_new_i32
19
-#define tcg_temp_local_new() tcg_temp_local_new_i32()
20
#define tcg_temp_free tcg_temp_free_i32
21
#define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i32
22
#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32
23
#else
24
#define tcg_temp_new() tcg_temp_new_i64()
25
#define tcg_global_mem_new tcg_global_mem_new_i64
26
-#define tcg_temp_local_new() tcg_temp_local_new_i64()
27
#define tcg_temp_free tcg_temp_free_i64
28
#define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i64
29
#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i64
30
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/include/tcg/tcg.h
33
+++ b/include/tcg/tcg.h
34
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 tcg_temp_new_i32(void)
35
return temp_tcgv_i32(t);
21
}
36
}
22
37
23
-static void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr)
38
-static inline TCGv_i32 tcg_temp_local_new_i32(void)
24
-{
39
-{
25
- /* Discard jump cache entries for any tb which might potentially
40
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, TEMP_TB);
26
- overlap the flushed page. */
41
- return temp_tcgv_i32(t);
27
- tb_jmp_cache_clear_page(cpu, addr - TARGET_PAGE_SIZE);
28
- tb_jmp_cache_clear_page(cpu, addr);
29
-}
42
-}
30
-
43
-
31
/**
44
static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
32
* tlb_mmu_resize_locked() - perform TLB resize bookkeeping; resize if necessary
45
const char *name)
33
* @desc: The CPUTLBDesc portion of the TLB
46
{
34
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_by_mmuidx_async_0(CPUState *cpu,
47
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i64 tcg_temp_new_i64(void)
35
}
48
return temp_tcgv_i64(t);
36
qemu_spin_unlock(&env_tlb(env)->c.lock);
37
38
- tb_flush_jmp_cache(cpu, addr);
39
+ /*
40
+ * Discard jump cache entries for any tb which might potentially
41
+ * overlap the flushed page, which includes the previous.
42
+ */
43
+ tb_jmp_cache_clear_page(cpu, addr - TARGET_PAGE_SIZE);
44
+ tb_jmp_cache_clear_page(cpu, addr);
45
}
49
}
46
50
47
/**
51
-static inline TCGv_i64 tcg_temp_local_new_i64(void)
48
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_range_by_mmuidx_async_0(CPUState *cpu,
52
-{
49
return;
53
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, TEMP_TB);
50
}
54
- return temp_tcgv_i64(t);
51
55
-}
52
- for (target_ulong i = 0; i < d.len; i += TARGET_PAGE_SIZE) {
56
-
53
- tb_flush_jmp_cache(cpu, d.addr + i);
57
/* Used only by tcg infrastructure: tcg-op.c or plugin-gen.c */
54
+ /*
58
static inline TCGv_i128 tcg_temp_ebb_new_i128(void)
55
+ * Discard jump cache entries for any tb which might potentially
59
{
56
+ * overlap the flushed pages, which includes the previous.
60
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i128 tcg_temp_new_i128(void)
57
+ */
61
return temp_tcgv_i128(t);
58
+ d.addr -= TARGET_PAGE_SIZE;
59
+ for (target_ulong i = 0, n = d.len / TARGET_PAGE_SIZE + 1; i < n; i++) {
60
+ tb_jmp_cache_clear_page(cpu, d.addr);
61
+ d.addr += TARGET_PAGE_SIZE;
62
}
63
}
62
}
64
63
64
-static inline TCGv_i128 tcg_temp_local_new_i128(void)
65
-{
66
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, TEMP_TB);
67
- return temp_tcgv_i128(t);
68
-}
69
-
70
static inline TCGv_ptr tcg_global_mem_new_ptr(TCGv_ptr reg, intptr_t offset,
71
const char *name)
72
{
73
@@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr tcg_temp_new_ptr(void)
74
return temp_tcgv_ptr(t);
75
}
76
77
-static inline TCGv_ptr tcg_temp_local_new_ptr(void)
78
-{
79
- TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, TEMP_TB);
80
- return temp_tcgv_ptr(t);
81
-}
82
-
83
#if defined(CONFIG_DEBUG_TCG)
84
/* If you call tcg_clear_temp_count() at the start of a section of
85
* code which is not supposed to leak any TCG temporaries, then
86
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s);
87
/* Allocate a new temporary and initialize it with a constant. */
88
TCGv_i32 tcg_const_i32(int32_t val);
89
TCGv_i64 tcg_const_i64(int64_t val);
90
-TCGv_i32 tcg_const_local_i32(int32_t val);
91
-TCGv_i64 tcg_const_local_i64(int64_t val);
92
TCGv_vec tcg_const_zeros_vec(TCGType);
93
TCGv_vec tcg_const_ones_vec(TCGType);
94
TCGv_vec tcg_const_zeros_vec_matching(TCGv_vec);
95
@@ -XXX,XX +XXX,XX @@ TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val);
96
97
#if UINTPTR_MAX == UINT32_MAX
98
# define tcg_const_ptr(x) ((TCGv_ptr)tcg_const_i32((intptr_t)(x)))
99
-# define tcg_const_local_ptr(x) ((TCGv_ptr)tcg_const_local_i32((intptr_t)(x)))
100
# define tcg_constant_ptr(x) ((TCGv_ptr)tcg_constant_i32((intptr_t)(x)))
101
#else
102
# define tcg_const_ptr(x) ((TCGv_ptr)tcg_const_i64((intptr_t)(x)))
103
-# define tcg_const_local_ptr(x) ((TCGv_ptr)tcg_const_local_i64((intptr_t)(x)))
104
# define tcg_constant_ptr(x) ((TCGv_ptr)tcg_constant_i64((intptr_t)(x)))
105
#endif
106
107
diff --git a/tcg/tcg.c b/tcg/tcg.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/tcg/tcg.c
110
+++ b/tcg/tcg.c
111
@@ -XXX,XX +XXX,XX @@ TCGv_i64 tcg_const_i64(int64_t val)
112
return t0;
113
}
114
115
-TCGv_i32 tcg_const_local_i32(int32_t val)
116
-{
117
- TCGv_i32 t0;
118
- t0 = tcg_temp_local_new_i32();
119
- tcg_gen_movi_i32(t0, val);
120
- return t0;
121
-}
122
-
123
-TCGv_i64 tcg_const_local_i64(int64_t val)
124
-{
125
- TCGv_i64 t0;
126
- t0 = tcg_temp_local_new_i64();
127
- tcg_gen_movi_i64(t0, val);
128
- return t0;
129
-}
130
-
131
#if defined(CONFIG_DEBUG_TCG)
132
void tcg_clear_temp_count(void)
133
{
65
--
134
--
66
2.34.1
135
2.34.1
67
136
68
137
diff view generated by jsdifflib
New patch
1
Rewrite the sections which talked about 'local temporaries'.
2
Remove some assumptions which no longer hold.
1
3
4
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
docs/devel/tcg-ops.rst | 230 +++++++++++++++++++++++------------------
8
1 file changed, 129 insertions(+), 101 deletions(-)
9
10
diff --git a/docs/devel/tcg-ops.rst b/docs/devel/tcg-ops.rst
11
index XXXXXXX..XXXXXXX 100644
12
--- a/docs/devel/tcg-ops.rst
13
+++ b/docs/devel/tcg-ops.rst
14
@@ -XXX,XX +XXX,XX @@ TCG Intermediate Representation
15
Introduction
16
============
17
18
-TCG (Tiny Code Generator) began as a generic backend for a C
19
-compiler. It was simplified to be used in QEMU. It also has its roots
20
-in the QOP code generator written by Paul Brook.
21
+TCG (Tiny Code Generator) began as a generic backend for a C compiler.
22
+It was simplified to be used in QEMU. It also has its roots in the
23
+QOP code generator written by Paul Brook.
24
25
Definitions
26
===========
27
28
-TCG receives RISC-like *TCG ops* and performs some optimizations on them,
29
-including liveness analysis and trivial constant expression
30
-evaluation. TCG ops are then implemented in the host CPU back end,
31
-also known as the TCG target.
32
-
33
-The TCG *target* is the architecture for which we generate the
34
-code. It is of course not the same as the "target" of QEMU which is
35
-the emulated architecture. As TCG started as a generic C backend used
36
-for cross compiling, it is assumed that the TCG target is different
37
-from the host, although it is never the case for QEMU.
38
+The TCG *target* is the architecture for which we generate the code.
39
+It is of course not the same as the "target" of QEMU which is the
40
+emulated architecture. As TCG started as a generic C backend used
41
+for cross compiling, the assumption was that TCG target might be
42
+different from the host, although this is never the case for QEMU.
43
44
In this document, we use *guest* to specify what architecture we are
45
emulating; *target* always means the TCG target, the machine on which
46
we are running QEMU.
47
48
-A TCG *function* corresponds to a QEMU Translated Block (TB).
49
-
50
-A TCG *temporary* is a variable only live in a basic block. Temporaries are allocated explicitly in each function.
51
-
52
-A TCG *local temporary* is a variable only live in a function. Local temporaries are allocated explicitly in each function.
53
-
54
-A TCG *global* is a variable which is live in all the functions
55
-(equivalent of a C global variable). They are defined before the
56
-functions defined. A TCG global can be a memory location (e.g. a QEMU
57
-CPU register), a fixed host register (e.g. the QEMU CPU state pointer)
58
-or a memory location which is stored in a register outside QEMU TBs
59
-(not implemented yet).
60
-
61
-A TCG *basic block* corresponds to a list of instructions terminated
62
-by a branch instruction.
63
-
64
An operation with *undefined behavior* may result in a crash.
65
66
An operation with *unspecified behavior* shall not crash. However,
67
the result may be one of several possibilities so may be considered
68
an *undefined result*.
69
70
-Intermediate representation
71
-===========================
72
+Basic Blocks
73
+============
74
75
-Introduction
76
-------------
77
+A TCG *basic block* is a single entry, multiple exit region which
78
+corresponds to a list of instructions terminated by a label, or
79
+any branch instruction.
80
81
-TCG instructions operate on variables which are temporaries, local
82
-temporaries or globals. TCG instructions and variables are strongly
83
-typed. Two types are supported: 32 bit integers and 64 bit
84
-integers. Pointers are defined as an alias to 32 bit or 64 bit
85
-integers depending on the TCG target word size.
86
+A TCG *extended basic block* is a single entry, multiple exit region
87
+which corresponds to a list of instructions terminated by a label or
88
+an unconditional branch. Specifically, an extended basic block is
89
+a sequence of basic blocks connected by the fall-through paths of
90
+zero or more conditional branch instructions.
91
92
-Each instruction has a fixed number of output variable operands, input
93
-variable operands and always constant operands.
94
+Operations
95
+==========
96
97
-The notable exception is the call instruction which has a variable
98
-number of outputs and inputs.
99
+TCG instructions or *ops* operate on TCG *variables*, both of which
100
+are strongly typed. Each instruction has a fixed number of output
101
+variable operands, input variable operands and constant operands.
102
+Vector instructions have a field specifying the element size within
103
+the vector. The notable exception is the call instruction which has
104
+a variable number of outputs and inputs.
105
106
In the textual form, output operands usually come first, followed by
107
input operands, followed by constant operands. The output type is
108
@@ -XXX,XX +XXX,XX @@ included in the instruction name. Constants are prefixed with a '$'.
109
110
add_i32 t0, t1, t2 /* (t0 <- t1 + t2) */
111
112
+Variables
113
+=========
114
115
-Assumptions
116
------------
117
+* ``TEMP_FIXED``
118
119
-Basic blocks
120
-^^^^^^^^^^^^
121
+ There is one TCG *fixed global* variable, ``cpu_env``, which is
122
+ live in all translation blocks, and holds a pointer to ``CPUArchState``.
123
+ This variable is held in a host cpu register at all times in all
124
+ translation blocks.
125
126
-* Basic blocks end after branches (e.g. brcond_i32 instruction),
127
- goto_tb and exit_tb instructions.
128
+* ``TEMP_GLOBAL``
129
130
-* Basic blocks start after the end of a previous basic block, or at a
131
- set_label instruction.
132
+ A TCG *global* is a variable which is live in all translation blocks,
133
+ and corresponds to memory location that is within ``CPUArchState``.
134
+ These may be specified as an offset from ``cpu_env``, in which case
135
+ they are called *direct globals*, or may be specified as an offset
136
+ from a direct global, in which case they are called *indirect globals*.
137
+ Even indirect globals should still reference memory within
138
+ ``CPUArchState``. All TCG globals are defined during
139
+ ``TCGCPUOps.initialize``, before any translation blocks are generated.
140
141
-After the end of a basic block, the content of temporaries is
142
-destroyed, but local temporaries and globals are preserved.
143
+* ``TEMP_CONST``
144
145
-Floating point types
146
-^^^^^^^^^^^^^^^^^^^^
147
+ A TCG *constant* is a variable which is live throughout the entire
148
+ translation block, and contains a constant value. These variables
149
+ are allocated on demand during translation and are hashed so that
150
+ there is exactly one variable holding a given value.
151
152
-* Floating point types are not supported yet
153
+* ``TEMP_TB``
154
155
-Pointers
156
-^^^^^^^^
157
+ A TCG *translation block temporary* is a variable which is live
158
+ throughout the entire translation block, but dies on any exit.
159
+ These temporaries are allocated explicitly during translation.
160
161
-* Depending on the TCG target, pointer size is 32 bit or 64
162
- bit. The type ``TCG_TYPE_PTR`` is an alias to ``TCG_TYPE_I32`` or
163
- ``TCG_TYPE_I64``.
164
+* ``TEMP_EBB``
165
+
166
+ A TCG *extended basic block temporary* is a variable which is live
167
+ throughout an extended basic block, but dies on any exit.
168
+ These temporaries are allocated explicitly during translation.
169
+
170
+Types
171
+=====
172
+
173
+* ``TCG_TYPE_I32``
174
+
175
+ A 32-bit integer.
176
+
177
+* ``TCG_TYPE_I64``
178
+
179
+ A 64-bit integer. For 32-bit hosts, such variables are split into a pair
180
+ of variables with ``type=TCG_TYPE_I32`` and ``base_type=TCG_TYPE_I64``.
181
+ The ``temp_subindex`` for each indicates where it falls within the
182
+ host-endian representation.
183
+
184
+* ``TCG_TYPE_PTR``
185
+
186
+ An alias for ``TCG_TYPE_I32`` or ``TCG_TYPE_I64``, depending on the size
187
+ of a pointer for the host.
188
+
189
+* ``TCG_TYPE_REG``
190
+
191
+ An alias for ``TCG_TYPE_I32`` or ``TCG_TYPE_I64``, depending on the size
192
+ of the integer registers for the host. This may be larger
193
+ than ``TCG_TYPE_PTR`` depending on the host ABI.
194
+
195
+* ``TCG_TYPE_I128``
196
+
197
+ A 128-bit integer. For all hosts, such variables are split into a number
198
+ of variables with ``type=TCG_TYPE_REG`` and ``base_type=TCG_TYPE_I128``.
199
+ The ``temp_subindex`` for each indicates where it falls within the
200
+ host-endian representation.
201
+
202
+* ``TCG_TYPE_V64``
203
+
204
+ A 64-bit vector. This type is valid only if the TCG target
205
+ sets ``TCG_TARGET_HAS_v64``.
206
+
207
+* ``TCG_TYPE_V128``
208
+
209
+ A 128-bit vector. This type is valid only if the TCG target
210
+ sets ``TCG_TARGET_HAS_v128``.
211
+
212
+* ``TCG_TYPE_V256``
213
+
214
+ A 256-bit vector. This type is valid only if the TCG target
215
+ sets ``TCG_TARGET_HAS_v256``.
216
217
Helpers
218
-^^^^^^^
219
+=======
220
221
-* Using the tcg_gen_helper_x_y it is possible to call any function
222
- taking i32, i64 or pointer types. By default, before calling a helper,
223
- all globals are stored at their canonical location and it is assumed
224
- that the function can modify them. By default, the helper is allowed to
225
- modify the CPU state or raise an exception.
226
+Helpers are registered in a guest-specific ``helper.h``,
227
+which is processed to generate ``tcg_gen_helper_*`` functions.
228
+With these functions it is possible to call a function taking
229
+i32, i64, i128 or pointer types.
230
231
- This can be overridden using the following function modifiers:
232
+By default, before calling a helper, all globals are stored at their
233
+canonical location. By default, the helper is allowed to modify the
234
+CPU state (including the state represented by tcg globals)
235
+or may raise an exception. This default can be overridden using the
236
+following function modifiers:
237
238
- - ``TCG_CALL_NO_READ_GLOBALS`` means that the helper does not read globals,
239
- either directly or via an exception. They will not be saved to their
240
- canonical locations before calling the helper.
241
+* ``TCG_CALL_NO_WRITE_GLOBALS``
242
243
- - ``TCG_CALL_NO_WRITE_GLOBALS`` means that the helper does not modify any globals.
244
- They will only be saved to their canonical location before calling helpers,
245
- but they won't be reloaded afterwards.
246
+ The helper does not modify any globals, but may read them.
247
+ Globals will be saved to their canonical location before calling helpers,
248
+ but need not be reloaded afterwards.
249
250
- - ``TCG_CALL_NO_SIDE_EFFECTS`` means that the call to the function is removed if
251
- the return value is not used.
252
+* ``TCG_CALL_NO_READ_GLOBALS``
253
254
- Note that ``TCG_CALL_NO_READ_GLOBALS`` implies ``TCG_CALL_NO_WRITE_GLOBALS``.
255
+ The helper does not read globals, either directly or via an exception.
256
+ They will not be saved to their canonical locations before calling
257
+ the helper. This implies ``TCG_CALL_NO_WRITE_GLOBALS``.
258
259
- On some TCG targets (e.g. x86), several calling conventions are
260
- supported.
261
+* ``TCG_CALL_NO_SIDE_EFFECTS``
262
263
-Branches
264
-^^^^^^^^
265
-
266
-* Use the instruction 'br' to jump to a label.
267
+ The call to the helper function may be removed if the return value is
268
+ not used. This means that it may not modify any CPU state nor may it
269
+ raise an exception.
270
271
Code Optimizations
272
-------------------
273
+==================
274
275
When generating instructions, you can count on at least the following
276
optimizations:
277
@@ -XXX,XX +XXX,XX @@ Recommended coding rules for best performance
278
often modified, e.g. the integer registers and the condition
279
codes. TCG will be able to use host registers to store them.
280
281
-- Avoid globals stored in fixed registers. They must be used only to
282
- store the pointer to the CPU state and possibly to store a pointer
283
- to a register window.
284
-
285
-- Use temporaries. Use local temporaries only when really needed,
286
- e.g. when you need to use a value after a jump. Local temporaries
287
- introduce a performance hit in the current TCG implementation: their
288
- content is saved to memory at end of each basic block.
289
-
290
-- Free temporaries and local temporaries when they are no longer used
291
- (tcg_temp_free). Since tcg_const_x() also creates a temporary, you
292
- should free it after it is used. Freeing temporaries does not yield
293
- a better generated code, but it reduces the memory usage of TCG and
294
- the speed of the translation.
295
+- Free temporaries when they are no longer used (``tcg_temp_free``).
296
+ Since ``tcg_const_x`` also creates a temporary, you should free it
297
+ after it is used.
298
299
- Don't hesitate to use helpers for complicated or seldom used guest
300
instructions. There is little performance advantage in using TCG to
301
@@ -XXX,XX +XXX,XX @@ Recommended coding rules for best performance
302
the instruction is mostly doing loads and stores, and in those cases
303
inline TCG may still be faster for longer sequences.
304
305
-- The hard limit on the number of TCG instructions you can generate
306
- per guest instruction is set by ``MAX_OP_PER_INSTR`` in ``exec-all.h`` --
307
- you cannot exceed this without risking a buffer overrun.
308
-
309
- Use the 'discard' instruction if you know that TCG won't be able to
310
prove that a given global is "dead" at a given program point. The
311
x86 guest uses it to improve the condition codes optimisation.
312
--
313
2.34.1
diff view generated by jsdifflib