1
TCG patch queue, plus one target/sh4 patch that
1
v2: Fix target/loongarch printf formats for vaddr
2
Yoshinori Sato asked me to process.
2
Include two more reviewed patches.
3
3
4
4
5
r~
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
12
are available in the Git repository at:
13
14
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20221004
15
16
for you to fetch changes up to ab419fd8a035a65942de4e63effcd55ccbf1a9fe:
17
18
target/sh4: Fix TB_FLAG_UNALIGN (2022-10-04 12:33:05 -0700)
19
20
----------------------------------------------------------------
21
Cache CPUClass for use in hot code paths.
22
Add CPUTLBEntryFull, probe_access_full, tlb_set_page_full.
23
Add generic support for TARGET_TB_PCREL.
24
tcg/ppc: Optimize 26-bit jumps using STQ for POWER 2.07
25
target/sh4: Fix TB_FLAG_UNALIGN
26
27
----------------------------------------------------------------
28
Alex Bennée (3):
29
cpu: cache CPUClass in CPUState for hot code paths
30
hw/core/cpu-sysemu: used cached class in cpu_asidx_from_attrs
31
cputlb: used cached CPUClass in our hot-paths
32
33
Leandro Lupori (1):
34
tcg/ppc: Optimize 26-bit jumps
35
36
Richard Henderson (16):
37
accel/tcg: Rename CPUIOTLBEntry to CPUTLBEntryFull
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
54
accel/tcg/internal.h | 10 ++
55
accel/tcg/tb-hash.h | 1 +
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
diff view generated by jsdifflib
1
This bitmap is created and discarded immediately.
1
These should have been removed with the rest. There are
2
We gain nothing by its existence.
2
a couple of hosts which can emit guest_base into the
3
constant pool: aarch64, mips64, ppc64, riscv64.
3
4
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Fixes: a417ef835058 ("tcg: Remove TCG_TARGET_NEED_LDST_LABELS and TCG_TARGET_NEED_POOL_LABELS")
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-Id: <20220822232338.1727934-2-richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
---
8
---
8
accel/tcg/translate-all.c | 78 ++-------------------------------------
9
tcg/tci/tcg-target.h | 1 -
9
1 file changed, 4 insertions(+), 74 deletions(-)
10
tcg/tcg.c | 4 ----
11
2 files changed, 5 deletions(-)
10
12
11
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
13
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/translate-all.c
15
--- a/tcg/tci/tcg-target.h
14
+++ b/accel/tcg/translate-all.c
16
+++ b/tcg/tci/tcg-target.h
15
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ typedef enum {
16
#define assert_memory_lock() tcg_debug_assert(have_mmap_lock())
18
} TCGReg;
19
20
#define HAVE_TCG_QEMU_TB_EXEC
21
-#define TCG_TARGET_NEED_POOL_LABELS
22
23
#endif /* TCG_TARGET_H */
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 @@ void tcg_prologue_init(void)
29
tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr);
17
#endif
30
#endif
18
31
19
-#define SMC_BITMAP_USE_THRESHOLD 10
32
-#ifdef TCG_TARGET_NEED_POOL_LABELS
20
-
33
s->pool_labels = NULL;
21
typedef struct PageDesc {
22
/* list of TBs intersecting this ram page */
23
uintptr_t first_tb;
24
-#ifdef CONFIG_SOFTMMU
25
- /* in order to optimize self modifying code, we count the number
26
- of lookups we do to a given page to use a bitmap */
27
- unsigned long *code_bitmap;
28
- unsigned int code_write_count;
29
-#else
30
+#ifdef CONFIG_USER_ONLY
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
34
-#endif
52
-}
35
53
-
36
qemu_thread_jit_write();
54
/* Set to NULL all the 'first_tb' fields in all PageDescs. */
37
/* Generate the prologue. */
55
static void page_flush_tb_1(int level, void **lp)
38
tcg_target_qemu_prologue(s);
56
{
39
57
@@ -XXX,XX +XXX,XX @@ static void page_flush_tb_1(int level, void **lp)
40
-#ifdef TCG_TARGET_NEED_POOL_LABELS
58
for (i = 0; i < V_L2_SIZE; ++i) {
41
/* Allow the prologue to put e.g. guest_base into a pool entry. */
59
page_lock(&pd[i]);
42
{
60
pd[i].first_tb = (uintptr_t)NULL;
43
int result = tcg_out_pool_finalize(s);
61
- invalidate_page_bitmap(pd + i);
44
tcg_debug_assert(result == 0);
62
page_unlock(&pd[i]);
63
}
64
} else {
65
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
66
if (rm_from_page_list) {
67
p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
68
tb_page_remove(p, tb);
69
- invalidate_page_bitmap(p);
70
if (tb->page_addr[1] != -1) {
71
p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
72
tb_page_remove(p, tb);
73
- invalidate_page_bitmap(p);
74
}
75
}
45
}
76
77
@@ -XXX,XX +XXX,XX @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
78
}
79
}
80
81
-#ifdef CONFIG_SOFTMMU
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
46
-#endif
109
-
47
110
/* add the tb in the target page and protect it if necessary
48
prologue_size = tcg_current_code_size(s);
111
*
49
perf_report_prologue(s->code_gen_ptr, prologue_size);
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
--
50
--
168
2.34.1
51
2.43.0
169
52
170
53
diff view generated by jsdifflib
1
Wrap the bare TranslationBlock pointer into a structure.
1
This is now prohibited in configuration.
2
2
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
5
---
7
accel/tcg/tb-hash.h | 1 +
6
include/qemu/atomic.h | 18 +++--------------
8
accel/tcg/tb-jmp-cache.h | 24 ++++++++++++++++++++++++
7
include/tcg/oversized-guest.h | 23 ----------------------
9
include/exec/cpu-common.h | 1 +
8
accel/tcg/cputlb.c | 7 -------
10
include/hw/core/cpu.h | 15 +--------------
9
accel/tcg/tcg-all.c | 9 ++++-----
11
include/qemu/typedefs.h | 1 +
10
target/arm/ptw.c | 34 ---------------------------------
12
accel/stubs/tcg-stub.c | 4 ++++
11
target/riscv/cpu_helper.c | 13 +------------
13
accel/tcg/cpu-exec.c | 10 +++++++---
12
docs/devel/multi-thread-tcg.rst | 1 -
14
accel/tcg/cputlb.c | 9 +++++----
13
7 files changed, 8 insertions(+), 97 deletions(-)
15
accel/tcg/translate-all.c | 28 +++++++++++++++++++++++++---
14
delete mode 100644 include/tcg/oversized-guest.h
16
hw/core/cpu-common.c | 3 +--
15
17
plugins/core.c | 2 +-
16
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
18
trace/control-target.c | 2 +-
17
index XXXXXXX..XXXXXXX 100644
19
12 files changed, 72 insertions(+), 28 deletions(-)
18
--- a/include/qemu/atomic.h
20
create mode 100644 accel/tcg/tb-jmp-cache.h
19
+++ b/include/qemu/atomic.h
21
20
@@ -XXX,XX +XXX,XX @@
22
diff --git a/accel/tcg/tb-hash.h b/accel/tcg/tb-hash.h
21
*/
23
index XXXXXXX..XXXXXXX 100644
22
#define signal_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
24
--- a/accel/tcg/tb-hash.h
23
25
+++ b/accel/tcg/tb-hash.h
24
-/* Sanity check that the size of an atomic operation isn't "overly large".
26
@@ -XXX,XX +XXX,XX @@
25
+/*
27
#include "exec/cpu-defs.h"
26
+ * Sanity check that the size of an atomic operation isn't "overly large".
28
#include "exec/exec-all.h"
27
* Despite the fact that e.g. i686 has 64-bit atomic operations, we do not
29
#include "qemu/xxhash.h"
28
* want to use them because we ought not need them, and this lets us do a
30
+#include "tb-jmp-cache.h"
29
* bit of sanity checking that other 32-bit hosts might build.
31
30
- *
32
#ifdef CONFIG_SOFTMMU
31
- * That said, we have a problem on 64-bit ILP32 hosts in that in order to
33
32
- * sync with TCG_OVERSIZED_GUEST, this must match TCG_TARGET_REG_BITS.
34
diff --git a/accel/tcg/tb-jmp-cache.h b/accel/tcg/tb-jmp-cache.h
33
- * We'd prefer not want to pull in everything else TCG related, so handle
35
new file mode 100644
34
- * those few cases by hand.
35
- *
36
- * Note that x32 is fully detected with __x86_64__ + _ILP32, and that for
37
- * Sparc we always force the use of sparcv9 in configure. MIPS n32 (ILP32) &
38
- * n64 (LP64) ABIs are both detected using __mips64.
39
*/
40
-#if defined(__x86_64__) || defined(__sparc__) || defined(__mips64)
41
-# define ATOMIC_REG_SIZE 8
42
-#else
43
-# define ATOMIC_REG_SIZE sizeof(void *)
44
-#endif
45
+#define ATOMIC_REG_SIZE sizeof(void *)
46
47
/* Weak atomic operations prevent the compiler moving other
48
* loads/stores past the atomic operation load/store. However there is
49
diff --git a/include/tcg/oversized-guest.h b/include/tcg/oversized-guest.h
50
deleted file mode 100644
36
index XXXXXXX..XXXXXXX
51
index XXXXXXX..XXXXXXX
37
--- /dev/null
52
--- a/include/tcg/oversized-guest.h
38
+++ b/accel/tcg/tb-jmp-cache.h
53
+++ /dev/null
39
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@
40
+/*
55
-/* SPDX-License-Identifier: MIT */
41
+ * The per-CPU TranslationBlock jump cache.
56
-/*
42
+ *
57
- * Define TCG_OVERSIZED_GUEST
43
+ * Copyright (c) 2003 Fabrice Bellard
58
- * Copyright (c) 2008 Fabrice Bellard
44
+ *
59
- */
45
+ * SPDX-License-Identifier: GPL-2.0-or-later
60
-
46
+ */
61
-#ifndef EXEC_TCG_OVERSIZED_GUEST_H
47
+
62
-#define EXEC_TCG_OVERSIZED_GUEST_H
48
+#ifndef ACCEL_TCG_TB_JMP_CACHE_H
63
-
49
+#define ACCEL_TCG_TB_JMP_CACHE_H
64
-#include "tcg-target-reg-bits.h"
50
+
65
-#include "cpu-param.h"
51
+#define TB_JMP_CACHE_BITS 12
66
-
52
+#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
67
-/*
53
+
68
- * Oversized TCG guests make things like MTTCG hard
54
+/*
69
- * as we can't use atomics for cputlb updates.
55
+ * Accessed in parallel; all accesses to 'tb' must be atomic.
70
- */
56
+ */
71
-#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
57
+struct CPUJumpCache {
72
-#define TCG_OVERSIZED_GUEST 1
58
+ struct {
73
-#else
59
+ TranslationBlock *tb;
74
-#define TCG_OVERSIZED_GUEST 0
60
+ } array[TB_JMP_CACHE_SIZE];
75
-#endif
61
+};
76
-
62
+
77
-#endif
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
-{
106
- unsigned int i;
107
-
108
- for (i = 0; i < TB_JMP_CACHE_SIZE; i++) {
109
- qatomic_set(&cpu->tb_jmp_cache[i], NULL);
110
- }
111
-}
112
-
113
/**
114
* qemu_tcg_mttcg_enabled:
115
* Check whether we are running MultiThread TCG or not.
116
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
117
index XXXXXXX..XXXXXXX 100644
118
--- a/include/qemu/typedefs.h
119
+++ b/include/qemu/typedefs.h
120
@@ -XXX,XX +XXX,XX @@ typedef struct CoMutex CoMutex;
121
typedef struct ConfidentialGuestSupport ConfidentialGuestSupport;
122
typedef struct CPUAddressSpace CPUAddressSpace;
123
typedef struct CPUArchState CPUArchState;
124
+typedef struct CPUJumpCache CPUJumpCache;
125
typedef struct CPUState CPUState;
126
typedef struct CPUTLBEntryFull CPUTLBEntryFull;
127
typedef struct DeviceListener DeviceListener;
128
diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/accel/stubs/tcg-stub.c
131
+++ b/accel/stubs/tcg-stub.c
132
@@ -XXX,XX +XXX,XX @@ void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
133
{
134
}
135
136
+void tcg_flush_jmp_cache(CPUState *cpu)
137
+{
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
144
index XXXXXXX..XXXXXXX 100644
145
--- a/accel/tcg/cpu-exec.c
146
+++ 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,
156
tcg_debug_assert(!(cflags & CF_INVALID));
157
158
hash = tb_jmp_cache_hash_func(pc);
159
- tb = qatomic_rcu_read(&cpu->tb_jmp_cache[hash]);
160
+ tb = qatomic_rcu_read(&cpu->tb_jmp_cache->array[hash].tb);
161
162
if (likely(tb &&
163
tb->pc == pc &&
164
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
165
if (tb == NULL) {
166
return NULL;
167
}
168
- qatomic_set(&cpu->tb_jmp_cache[hash], tb);
169
+ qatomic_set(&cpu->tb_jmp_cache->array[hash].tb, tb);
170
return tb;
171
}
172
173
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
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
185
*/
186
- qatomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb);
187
+ h = tb_jmp_cache_hash_func(pc);
188
+ qatomic_set(&cpu->tb_jmp_cache->array[h].tb, tb);
189
}
190
191
#ifndef CONFIG_USER_ONLY
192
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
78
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
193
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
194
--- a/accel/tcg/cputlb.c
80
--- a/accel/tcg/cputlb.c
195
+++ b/accel/tcg/cputlb.c
81
+++ b/accel/tcg/cputlb.c
196
@@ -XXX,XX +XXX,XX @@ static void tlb_window_reset(CPUTLBDesc *desc, int64_t ns,
82
@@ -XXX,XX +XXX,XX @@
197
83
#include "qemu/plugin-memory.h"
198
static void tb_jmp_cache_clear_page(CPUState *cpu, target_ulong page_addr)
84
#endif
85
#include "tcg/tcg-ldst.h"
86
-#include "tcg/oversized-guest.h"
87
88
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
89
/* #define DEBUG_TLB */
90
@@ -XXX,XX +XXX,XX @@ static inline uint64_t tlb_read_idx(const CPUTLBEntry *entry,
91
return qatomic_read(ptr);
92
#else
93
const uint64_t *ptr = &entry->addr_idx[access_type];
94
-# if TCG_OVERSIZED_GUEST
95
- return *ptr;
96
-# else
97
/* ofs might correspond to .addr_write, so use qatomic_read */
98
return qatomic_read(ptr);
99
-# endif
100
#endif
101
}
102
103
@@ -XXX,XX +XXX,XX @@ static void tlb_reset_dirty_range_locked(CPUTLBEntry *tlb_entry,
104
uint32_t *ptr_write = (uint32_t *)&tlb_entry->addr_write;
105
ptr_write += HOST_BIG_ENDIAN;
106
qatomic_set(ptr_write, *ptr_write | TLB_NOTDIRTY);
107
-#elif TCG_OVERSIZED_GUEST
108
- tlb_entry->addr_write |= TLB_NOTDIRTY;
109
#else
110
qatomic_set(&tlb_entry->addr_write,
111
tlb_entry->addr_write | TLB_NOTDIRTY);
112
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/accel/tcg/tcg-all.c
115
+++ b/accel/tcg/tcg-all.c
116
@@ -XXX,XX +XXX,XX @@
117
#include "exec/replay-core.h"
118
#include "system/cpu-timers.h"
119
#include "tcg/startup.h"
120
-#include "tcg/oversized-guest.h"
121
#include "qapi/error.h"
122
#include "qemu/error-report.h"
123
#include "qemu/accel.h"
124
@@ -XXX,XX +XXX,XX @@
125
#include "hw/boards.h"
126
#endif
127
#include "internal-common.h"
128
+#include "cpu-param.h"
129
+
130
131
struct TCGState {
132
AccelState parent_obj;
133
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(TCGState, TCG_STATE,
134
135
static bool default_mttcg_enabled(void)
199
{
136
{
200
- unsigned int i, i0 = tb_jmp_cache_hash_page(page_addr);
137
- if (icount_enabled() || TCG_OVERSIZED_GUEST) {
201
+ int i, i0 = tb_jmp_cache_hash_page(page_addr);
138
+ if (icount_enabled()) {
202
+ CPUJumpCache *jc = cpu->tb_jmp_cache;
139
return false;
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
}
140
}
208
}
141
#ifdef TARGET_SUPPORTS_MTTCG
209
142
@@ -XXX,XX +XXX,XX @@ static void tcg_set_thread(Object *obj, const char *value, Error **errp)
210
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data)
143
TCGState *s = TCG_STATE(obj);
211
144
212
qemu_spin_unlock(&env_tlb(env)->c.lock);
145
if (strcmp(value, "multi") == 0) {
213
146
- if (TCG_OVERSIZED_GUEST) {
214
- cpu_tb_jmp_cache_clear(cpu);
147
- error_setg(errp, "No MTTCG when guest word size > hosts");
215
+ tcg_flush_jmp_cache(cpu);
148
- } else if (icount_enabled()) {
216
149
+ if (icount_enabled()) {
217
if (to_clean == ALL_MMUIDX_BITS) {
150
error_setg(errp, "No MTTCG when icount is enabled");
218
qatomic_set(&env_tlb(env)->c.full_flush_count,
151
} else {
219
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_range_by_mmuidx_async_0(CPUState *cpu,
152
#ifndef TARGET_SUPPORTS_MTTCG
220
* longer to clear each entry individually than it will to clear it all.
153
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
221
*/
154
index XXXXXXX..XXXXXXX 100644
222
if (d.len >= (TARGET_PAGE_SIZE * TB_JMP_CACHE_SIZE)) {
155
--- a/target/arm/ptw.c
223
- cpu_tb_jmp_cache_clear(cpu);
156
+++ b/target/arm/ptw.c
224
+ tcg_flush_jmp_cache(cpu);
157
@@ -XXX,XX +XXX,XX @@
225
return;
158
#include "internals.h"
159
#include "cpu-features.h"
160
#include "idau.h"
161
-#ifdef CONFIG_TCG
162
-# include "tcg/oversized-guest.h"
163
-#endif
164
165
typedef struct S1Translate {
166
/*
167
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
168
ptw->out_rw = true;
226
}
169
}
227
170
228
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
171
-#ifdef CONFIG_ATOMIC64
229
index XXXXXXX..XXXXXXX 100644
172
if (ptw->out_be) {
230
--- a/accel/tcg/translate-all.c
173
old_val = cpu_to_be64(old_val);
231
+++ b/accel/tcg/translate-all.c
174
new_val = cpu_to_be64(new_val);
232
@@ -XXX,XX +XXX,XX @@
175
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
233
#include "sysemu/tcg.h"
176
cur_val = qatomic_cmpxchg__nocheck((uint64_t *)host, old_val, new_val);
234
#include "qapi/error.h"
177
cur_val = le64_to_cpu(cur_val);
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
}
178
}
242
179
-#else
243
CPU_FOREACH(cpu) {
180
- /*
244
- cpu_tb_jmp_cache_clear(cpu);
181
- * We can't support the full 64-bit atomic cmpxchg on the host.
245
+ tcg_flush_jmp_cache(cpu);
182
- * Because this is only used for FEAT_HAFDBS, which is only for AA64,
246
}
183
- * we know that TCG_OVERSIZED_GUEST is set, which means that we are
247
184
- * running in round-robin mode and could only race with dma i/o.
248
qht_reset_size(&tb_ctx.htable, CODE_GEN_HTABLE_SIZE);
185
- */
249
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
186
-#if !TCG_OVERSIZED_GUEST
250
/* remove the TB from the hash list */
187
-# error "Unexpected configuration"
251
h = tb_jmp_cache_hash_func(tb->pc);
188
-#endif
252
CPU_FOREACH(cpu) {
189
- bool locked = bql_locked();
253
- if (qatomic_read(&cpu->tb_jmp_cache[h]) == tb) {
190
- if (!locked) {
254
- qatomic_set(&cpu->tb_jmp_cache[h], NULL);
191
- bql_lock();
255
+ CPUJumpCache *jc = cpu->tb_jmp_cache;
192
- }
256
+ if (qatomic_read(&jc->array[h].tb) == tb) {
193
- if (ptw->out_be) {
257
+ qatomic_set(&jc->array[h].tb, NULL);
194
- cur_val = ldq_be_p(host);
258
}
195
- if (cur_val == old_val) {
259
}
196
- stq_be_p(host, new_val);
260
197
- }
261
@@ -XXX,XX +XXX,XX @@ int page_unprotect(target_ulong address, uintptr_t pc)
198
- } else {
262
}
199
- cur_val = ldq_le_p(host);
263
#endif /* CONFIG_USER_ONLY */
200
- if (cur_val == old_val) {
264
201
- stq_le_p(host, new_val);
265
+/*
202
- }
266
+ * Called by generic code at e.g. cpu reset after cpu creation,
203
- }
267
+ * therefore we must be prepared to allocate the jump cache.
204
- if (!locked) {
268
+ */
205
- bql_unlock();
269
+void tcg_flush_jmp_cache(CPUState *cpu)
206
- }
270
+{
207
-#endif
271
+ CPUJumpCache *jc = cpu->tb_jmp_cache;
208
-
272
+
209
return cur_val;
273
+ if (likely(jc)) {
210
#else
274
+ for (int i = 0; i < TB_JMP_CACHE_SIZE; i++) {
211
/* AArch32 does not have FEAT_HADFS; non-TCG guests only use debug-mode. */
275
+ qatomic_set(&jc->array[i].tb, NULL);
212
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
276
+ }
213
index XXXXXXX..XXXXXXX 100644
277
+ } else {
214
--- a/target/riscv/cpu_helper.c
278
+ /* This should happen once during realize, and thus never race. */
215
+++ b/target/riscv/cpu_helper.c
279
+ jc = g_new0(CPUJumpCache, 1);
216
@@ -XXX,XX +XXX,XX @@
280
+ jc = qatomic_xchg(&cpu->tb_jmp_cache, jc);
217
#include "system/cpu-timers.h"
281
+ assert(jc == NULL);
218
#include "cpu_bits.h"
282
+ }
219
#include "debug.h"
283
+}
220
-#include "tcg/oversized-guest.h"
284
+
221
#include "pmp.h"
285
/* This is a wrapper for common code that can not use CONFIG_SOFTMMU */
222
286
void tcg_flush_softmmu_tlb(CPUState *cs)
223
int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
287
{
224
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
288
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
225
hwaddr pte_addr;
289
index XXXXXXX..XXXXXXX 100644
226
int i;
290
--- a/hw/core/cpu-common.c
227
291
+++ b/hw/core/cpu-common.c
228
-#if !TCG_OVERSIZED_GUEST
292
@@ -XXX,XX +XXX,XX @@ static void cpu_common_reset(DeviceState *dev)
229
-restart:
293
cpu->cflags_next_tb = -1;
230
-#endif
294
231
+ restart:
295
if (tcg_enabled()) {
232
for (i = 0; i < levels; i++, ptshift -= ptidxbits) {
296
- cpu_tb_jmp_cache_clear(cpu);
233
target_ulong idx;
297
-
234
if (i == 0) {
298
+ tcg_flush_jmp_cache(cpu);
235
@@ -XXX,XX +XXX,XX @@ restart:
299
tcg_flush_softmmu_tlb(cpu);
236
false, MEMTXATTRS_UNSPECIFIED);
300
}
237
if (memory_region_is_ram(mr)) {
301
}
238
target_ulong *pte_pa = qemu_map_ram_ptr(mr->ram_block, addr1);
302
diff --git a/plugins/core.c b/plugins/core.c
239
-#if TCG_OVERSIZED_GUEST
303
index XXXXXXX..XXXXXXX 100644
240
- /*
304
--- a/plugins/core.c
241
- * MTTCG is not enabled on oversized TCG guests so
305
+++ b/plugins/core.c
242
- * page table updates do not need to be atomic
306
@@ -XXX,XX +XXX,XX @@ struct qemu_plugin_ctx *plugin_id_to_ctx_locked(qemu_plugin_id_t id)
243
- */
307
static void plugin_cpu_update__async(CPUState *cpu, run_on_cpu_data data)
244
- *pte_pa = pte = updated_pte;
308
{
245
-#else
309
bitmap_copy(cpu->plugin_mask, &data.host_ulong, QEMU_PLUGIN_EV_MAX);
246
target_ulong old_pte;
310
- cpu_tb_jmp_cache_clear(cpu);
247
if (riscv_cpu_sxl(env) == MXL_RV32) {
311
+ tcg_flush_jmp_cache(cpu);
248
old_pte = qatomic_cmpxchg((uint32_t *)pte_pa, pte, updated_pte);
312
}
249
@@ -XXX,XX +XXX,XX @@ restart:
313
250
goto restart;
314
static void plugin_cpu_update__locked(gpointer k, gpointer v, gpointer udata)
251
}
315
diff --git a/trace/control-target.c b/trace/control-target.c
252
pte = updated_pte;
316
index XXXXXXX..XXXXXXX 100644
253
-#endif
317
--- a/trace/control-target.c
254
} else {
318
+++ b/trace/control-target.c
255
/*
319
@@ -XXX,XX +XXX,XX @@ static void trace_event_synchronize_vcpu_state_dynamic(
256
* Misconfigured PTE in ROM (AD bits are not preset) or
320
{
257
diff --git a/docs/devel/multi-thread-tcg.rst b/docs/devel/multi-thread-tcg.rst
321
bitmap_copy(vcpu->trace_dstate, vcpu->trace_dstate_delayed,
258
index XXXXXXX..XXXXXXX 100644
322
CPU_TRACE_DSTATE_MAX_EVENTS);
259
--- a/docs/devel/multi-thread-tcg.rst
323
- cpu_tb_jmp_cache_clear(vcpu);
260
+++ b/docs/devel/multi-thread-tcg.rst
324
+ tcg_flush_jmp_cache(vcpu);
261
@@ -XXX,XX +XXX,XX @@ if:
325
}
262
326
263
* forced by --accel tcg,thread=single
327
void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
264
* enabling --icount mode
265
-* 64 bit guests on 32 bit hosts (TCG_OVERSIZED_GUEST)
266
267
In the general case of running translated code there should be no
268
inter-vCPU dependencies and all vCPUs should be able to run at full
328
--
269
--
329
2.34.1
270
2.43.0
330
271
331
272
diff view generated by jsdifflib
1
Populate this new method for all targets. Always match
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
the result that would be given by cpu_get_tb_cpu_state,
3
as we will want these values to correspond in the logs.
4
5
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
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>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
3
---
10
Cc: Eduardo Habkost <eduardo@habkost.net> (supporter:Machine core)
4
tcg/tcg-op-ldst.c | 21 +++------------------
11
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com> (supporter:Machine core)
5
tcg/tcg.c | 4 +---
12
Cc: "Philippe Mathieu-Daudé" <f4bug@amsat.org> (reviewer:Machine core)
6
2 files changed, 4 insertions(+), 21 deletions(-)
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
7
58
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
8
diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c
59
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
60
--- a/include/hw/core/cpu.h
10
--- a/tcg/tcg-op-ldst.c
61
+++ b/include/hw/core/cpu.h
11
+++ b/tcg/tcg-op-ldst.c
62
@@ -XXX,XX +XXX,XX @@ struct SysemuCPUOps;
12
@@ -XXX,XX +XXX,XX @@ static MemOp tcg_canonicalize_memop(MemOp op, bool is64, bool st)
63
* If the target behaviour here is anything other than "set
13
static void gen_ldst(TCGOpcode opc, TCGType type, TCGTemp *vl, TCGTemp *vh,
64
* the PC register to the value passed in" then the target must
14
TCGTemp *addr, MemOpIdx oi)
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
}
86
87
+static vaddr alpha_cpu_get_pc(CPUState *cs)
88
+{
89
+ AlphaCPU *cpu = ALPHA_CPU(cs);
90
+
91
+ return cpu->env.pc;
92
+}
93
+
94
+
95
static bool alpha_cpu_has_work(CPUState *cs)
96
{
15
{
97
/* Here we are checking to see if the CPU should wake up from HALT.
16
- if (TCG_TARGET_REG_BITS == 64 || tcg_ctx->addr_type == TCG_TYPE_I32) {
98
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
17
- if (vh) {
99
cc->has_work = alpha_cpu_has_work;
18
- tcg_gen_op4(opc, type, temp_arg(vl), temp_arg(vh),
100
cc->dump_state = alpha_cpu_dump_state;
19
- temp_arg(addr), oi);
101
cc->set_pc = alpha_cpu_set_pc;
20
- } else {
102
+ cc->get_pc = alpha_cpu_get_pc;
21
- tcg_gen_op3(opc, type, temp_arg(vl), temp_arg(addr), oi);
103
cc->gdb_read_register = alpha_cpu_gdb_read_register;
22
- }
104
cc->gdb_write_register = alpha_cpu_gdb_write_register;
23
+ if (vh) {
105
#ifndef CONFIG_USER_ONLY
24
+ tcg_gen_op4(opc, type, temp_arg(vl), temp_arg(vh), temp_arg(addr), oi);
106
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
25
} else {
107
index XXXXXXX..XXXXXXX 100644
26
- /* See TCGV_LOW/HIGH. */
108
--- a/target/arm/cpu.c
27
- TCGTemp *al = addr + HOST_BIG_ENDIAN;
109
+++ b/target/arm/cpu.c
28
- TCGTemp *ah = addr + !HOST_BIG_ENDIAN;
110
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_set_pc(CPUState *cs, vaddr value)
29
-
30
- if (vh) {
31
- tcg_gen_op5(opc, type, temp_arg(vl), temp_arg(vh),
32
- temp_arg(al), temp_arg(ah), oi);
33
- } else {
34
- tcg_gen_op4(opc, type, temp_arg(vl),
35
- temp_arg(al), temp_arg(ah), oi);
36
- }
37
+ tcg_gen_op3(opc, type, temp_arg(vl), temp_arg(addr), oi);
111
}
38
}
112
}
39
}
113
40
114
+static vaddr arm_cpu_get_pc(CPUState *cs)
41
diff --git a/tcg/tcg.c b/tcg/tcg.c
115
+{
116
+ ARMCPU *cpu = ARM_CPU(cs);
117
+ CPUARMState *env = &cpu->env;
118
+
119
+ if (is_a64(env)) {
120
+ return env->pc;
121
+ } else {
122
+ return env->regs[15];
123
+ }
124
+}
125
+
126
#ifdef CONFIG_TCG
127
void arm_cpu_synchronize_from_tb(CPUState *cs,
128
const TranslationBlock *tb)
129
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
130
cc->has_work = arm_cpu_has_work;
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
42
index XXXXXXX..XXXXXXX 100644
139
--- a/target/avr/cpu.c
43
--- a/tcg/tcg.c
140
+++ b/target/avr/cpu.c
44
+++ b/tcg/tcg.c
141
@@ -XXX,XX +XXX,XX @@ static void avr_cpu_set_pc(CPUState *cs, vaddr value)
45
@@ -XXX,XX +XXX,XX @@ void tcg_func_start(TCGContext *s)
142
cpu->env.pc_w = value / 2; /* internally PC points to words */
46
s->emit_before_op = NULL;
47
QSIMPLEQ_INIT(&s->labels);
48
49
- tcg_debug_assert(s->addr_type == TCG_TYPE_I32 ||
50
- s->addr_type == TCG_TYPE_I64);
51
-
52
+ tcg_debug_assert(s->addr_type <= TCG_TYPE_REG);
53
tcg_debug_assert(s->insn_start_words > 0);
143
}
54
}
144
55
145
+static vaddr avr_cpu_get_pc(CPUState *cs)
146
+{
147
+ AVRCPU *cpu = AVR_CPU(cs);
148
+
149
+ return cpu->env.pc_w * 2;
150
+}
151
+
152
static bool avr_cpu_has_work(CPUState *cs)
153
{
154
AVRCPU *cpu = AVR_CPU(cs);
155
@@ -XXX,XX +XXX,XX @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
156
cc->has_work = avr_cpu_has_work;
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
}
170
171
+static vaddr cris_cpu_get_pc(CPUState *cs)
172
+{
173
+ CRISCPU *cpu = CRIS_CPU(cs);
174
+
175
+ return cpu->env.pc;
176
+}
177
+
178
static bool cris_cpu_has_work(CPUState *cs)
179
{
180
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
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
--
56
--
641
2.34.1
57
2.43.0
642
58
643
59
diff view generated by jsdifflib
1
This function has two users, who use it incompatibly.
1
Since 64-on-32 is now unsupported, guest addresses always
2
In tlb_flush_page_by_mmuidx_async_0, when flushing a
2
fit in one host register. Drop the replication of opcodes.
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
3
7
This avoids double-flushing of jmp cache pages in a range.
4
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>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
6
---
12
accel/tcg/cputlb.c | 25 ++++++++++++++-----------
7
include/tcg/tcg-opc.h | 28 ++------
13
1 file changed, 14 insertions(+), 11 deletions(-)
8
tcg/optimize.c | 21 ++----
9
tcg/tcg-op-ldst.c | 82 +++++----------------
10
tcg/tcg.c | 42 ++++-------
11
tcg/tci.c | 119 ++++++-------------------------
12
tcg/aarch64/tcg-target.c.inc | 36 ++++------
13
tcg/arm/tcg-target.c.inc | 40 +++--------
14
tcg/i386/tcg-target.c.inc | 69 ++++--------------
15
tcg/loongarch64/tcg-target.c.inc | 36 ++++------
16
tcg/mips/tcg-target.c.inc | 51 +++----------
17
tcg/ppc/tcg-target.c.inc | 68 ++++--------------
18
tcg/riscv/tcg-target.c.inc | 24 +++----
19
tcg/s390x/tcg-target.c.inc | 36 ++++------
20
tcg/sparc64/tcg-target.c.inc | 24 +++----
21
tcg/tci/tcg-target.c.inc | 60 ++++------------
22
15 files changed, 177 insertions(+), 559 deletions(-)
14
23
15
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
24
diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
16
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/tcg/cputlb.c
26
--- a/include/tcg/tcg-opc.h
18
+++ b/accel/tcg/cputlb.c
27
+++ b/include/tcg/tcg-opc.h
19
@@ -XXX,XX +XXX,XX @@ static void tb_jmp_cache_clear_page(CPUState *cpu, target_ulong page_addr)
28
@@ -XXX,XX +XXX,XX @@ DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
29
DEF(plugin_cb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
30
DEF(plugin_mem_cb, 0, 1, 1, TCG_OPF_NOT_PRESENT)
31
32
-/* Replicate ld/st ops for 32 and 64-bit guest addresses. */
33
-DEF(qemu_ld_a32_i32, 1, 1, 1,
34
+DEF(qemu_ld_i32, 1, 1, 1,
35
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
36
-DEF(qemu_st_a32_i32, 0, 1 + 1, 1,
37
+DEF(qemu_st_i32, 0, 1 + 1, 1,
38
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
39
-DEF(qemu_ld_a32_i64, DATA64_ARGS, 1, 1,
40
+DEF(qemu_ld_i64, DATA64_ARGS, 1, 1,
41
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
42
-DEF(qemu_st_a32_i64, 0, DATA64_ARGS + 1, 1,
43
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
44
-
45
-DEF(qemu_ld_a64_i32, 1, DATA64_ARGS, 1,
46
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
47
-DEF(qemu_st_a64_i32, 0, 1 + DATA64_ARGS, 1,
48
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
49
-DEF(qemu_ld_a64_i64, DATA64_ARGS, DATA64_ARGS, 1,
50
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
51
-DEF(qemu_st_a64_i64, 0, DATA64_ARGS + DATA64_ARGS, 1,
52
+DEF(qemu_st_i64, 0, DATA64_ARGS + 1, 1,
53
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
54
55
/* Only used by i386 to cope with stupid register constraints. */
56
-DEF(qemu_st8_a32_i32, 0, 1 + 1, 1,
57
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
58
-DEF(qemu_st8_a64_i32, 0, 1 + DATA64_ARGS, 1,
59
+DEF(qemu_st8_i32, 0, 1 + 1, 1,
60
TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
61
62
/* Only for 64-bit hosts at the moment. */
63
-DEF(qemu_ld_a32_i128, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
64
-DEF(qemu_ld_a64_i128, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
65
-DEF(qemu_st_a32_i128, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
66
-DEF(qemu_st_a64_i128, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
67
+DEF(qemu_ld_i128, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
68
+DEF(qemu_st_i128, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
69
70
/* Host vector support. */
71
72
diff --git a/tcg/optimize.c b/tcg/optimize.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/tcg/optimize.c
75
+++ b/tcg/optimize.c
76
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
77
CASE_OP_32_64_VEC(orc):
78
done = fold_orc(&ctx, op);
79
break;
80
- case INDEX_op_qemu_ld_a32_i32:
81
- case INDEX_op_qemu_ld_a64_i32:
82
+ case INDEX_op_qemu_ld_i32:
83
done = fold_qemu_ld_1reg(&ctx, op);
84
break;
85
- case INDEX_op_qemu_ld_a32_i64:
86
- case INDEX_op_qemu_ld_a64_i64:
87
+ case INDEX_op_qemu_ld_i64:
88
if (TCG_TARGET_REG_BITS == 64) {
89
done = fold_qemu_ld_1reg(&ctx, op);
90
break;
91
}
92
QEMU_FALLTHROUGH;
93
- case INDEX_op_qemu_ld_a32_i128:
94
- case INDEX_op_qemu_ld_a64_i128:
95
+ case INDEX_op_qemu_ld_i128:
96
done = fold_qemu_ld_2reg(&ctx, op);
97
break;
98
- case INDEX_op_qemu_st8_a32_i32:
99
- case INDEX_op_qemu_st8_a64_i32:
100
- case INDEX_op_qemu_st_a32_i32:
101
- case INDEX_op_qemu_st_a64_i32:
102
- case INDEX_op_qemu_st_a32_i64:
103
- case INDEX_op_qemu_st_a64_i64:
104
- case INDEX_op_qemu_st_a32_i128:
105
- case INDEX_op_qemu_st_a64_i128:
106
+ case INDEX_op_qemu_st8_i32:
107
+ case INDEX_op_qemu_st_i32:
108
+ case INDEX_op_qemu_st_i64:
109
+ case INDEX_op_qemu_st_i128:
110
done = fold_qemu_st(&ctx, op);
111
break;
112
CASE_OP_32_64(rem):
113
diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/tcg/tcg-op-ldst.c
116
+++ b/tcg/tcg-op-ldst.c
117
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_ld_i32_int(TCGv_i32 val, TCGTemp *addr,
118
MemOp orig_memop;
119
MemOpIdx orig_oi, oi;
120
TCGv_i64 copy_addr;
121
- TCGOpcode opc;
122
123
tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
124
orig_memop = memop = tcg_canonicalize_memop(memop, 0, 0);
125
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_ld_i32_int(TCGv_i32 val, TCGTemp *addr,
20
}
126
}
127
128
copy_addr = plugin_maybe_preserve_addr(addr);
129
- if (tcg_ctx->addr_type == TCG_TYPE_I32) {
130
- opc = INDEX_op_qemu_ld_a32_i32;
131
- } else {
132
- opc = INDEX_op_qemu_ld_a64_i32;
133
- }
134
- gen_ldst(opc, TCG_TYPE_I32, tcgv_i32_temp(val), NULL, addr, oi);
135
+ gen_ldst(INDEX_op_qemu_ld_i32, TCG_TYPE_I32,
136
+ tcgv_i32_temp(val), NULL, addr, oi);
137
plugin_gen_mem_callbacks_i32(val, copy_addr, addr, orig_oi,
138
QEMU_PLUGIN_MEM_R);
139
140
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_st_i32_int(TCGv_i32 val, TCGTemp *addr,
141
}
142
143
if (TCG_TARGET_HAS_qemu_st8_i32 && (memop & MO_SIZE) == MO_8) {
144
- if (tcg_ctx->addr_type == TCG_TYPE_I32) {
145
- opc = INDEX_op_qemu_st8_a32_i32;
146
- } else {
147
- opc = INDEX_op_qemu_st8_a64_i32;
148
- }
149
+ opc = INDEX_op_qemu_st8_i32;
150
} else {
151
- if (tcg_ctx->addr_type == TCG_TYPE_I32) {
152
- opc = INDEX_op_qemu_st_a32_i32;
153
- } else {
154
- opc = INDEX_op_qemu_st_a64_i32;
155
- }
156
+ opc = INDEX_op_qemu_st_i32;
157
}
158
gen_ldst(opc, TCG_TYPE_I32, tcgv_i32_temp(val), NULL, addr, oi);
159
plugin_gen_mem_callbacks_i32(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W);
160
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_ld_i64_int(TCGv_i64 val, TCGTemp *addr,
161
MemOp orig_memop;
162
MemOpIdx orig_oi, oi;
163
TCGv_i64 copy_addr;
164
- TCGOpcode opc;
165
166
if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
167
tcg_gen_qemu_ld_i32_int(TCGV_LOW(val), addr, idx, memop);
168
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_ld_i64_int(TCGv_i64 val, TCGTemp *addr,
169
}
170
171
copy_addr = plugin_maybe_preserve_addr(addr);
172
- if (tcg_ctx->addr_type == TCG_TYPE_I32) {
173
- opc = INDEX_op_qemu_ld_a32_i64;
174
- } else {
175
- opc = INDEX_op_qemu_ld_a64_i64;
176
- }
177
- gen_ldst_i64(opc, val, addr, oi);
178
+ gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, oi);
179
plugin_gen_mem_callbacks_i64(val, copy_addr, addr, orig_oi,
180
QEMU_PLUGIN_MEM_R);
181
182
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_st_i64_int(TCGv_i64 val, TCGTemp *addr,
183
{
184
TCGv_i64 swap = NULL;
185
MemOpIdx orig_oi, oi;
186
- TCGOpcode opc;
187
188
if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
189
tcg_gen_qemu_st_i32_int(TCGV_LOW(val), addr, idx, memop);
190
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_st_i64_int(TCGv_i64 val, TCGTemp *addr,
191
oi = make_memop_idx(memop, idx);
192
}
193
194
- if (tcg_ctx->addr_type == TCG_TYPE_I32) {
195
- opc = INDEX_op_qemu_st_a32_i64;
196
- } else {
197
- opc = INDEX_op_qemu_st_a64_i64;
198
- }
199
- gen_ldst_i64(opc, val, addr, oi);
200
+ gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, oi);
201
plugin_gen_mem_callbacks_i64(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W);
202
203
if (swap) {
204
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
205
{
206
MemOpIdx orig_oi;
207
TCGv_i64 ext_addr = NULL;
208
- TCGOpcode opc;
209
210
check_max_alignment(memop_alignment_bits(memop));
211
tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
212
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
213
hi = TCGV128_HIGH(val);
214
}
215
216
- if (tcg_ctx->addr_type == TCG_TYPE_I32) {
217
- opc = INDEX_op_qemu_ld_a32_i128;
218
- } else {
219
- opc = INDEX_op_qemu_ld_a64_i128;
220
- }
221
- gen_ldst(opc, TCG_TYPE_I128, tcgv_i64_temp(lo),
222
+ gen_ldst(INDEX_op_qemu_ld_i128, TCG_TYPE_I128, tcgv_i64_temp(lo),
223
tcgv_i64_temp(hi), addr, oi);
224
225
if (need_bswap) {
226
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
227
canonicalize_memop_i128_as_i64(mop, memop);
228
need_bswap = (mop[0] ^ memop) & MO_BSWAP;
229
230
- if (tcg_ctx->addr_type == TCG_TYPE_I32) {
231
- opc = INDEX_op_qemu_ld_a32_i64;
232
- } else {
233
- opc = INDEX_op_qemu_ld_a64_i64;
234
- }
235
-
236
/*
237
* Since there are no global TCGv_i128, there is no visible state
238
* changed if the second load faults. Load directly into the two
239
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
240
y = TCGV128_LOW(val);
241
}
242
243
- gen_ldst_i64(opc, x, addr, make_memop_idx(mop[0], idx));
244
+ gen_ldst_i64(INDEX_op_qemu_ld_i64, x, addr,
245
+ make_memop_idx(mop[0], idx));
246
247
if (need_bswap) {
248
tcg_gen_bswap64_i64(x, x);
249
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
250
addr_p8 = tcgv_i64_temp(t);
251
}
252
253
- gen_ldst_i64(opc, y, addr_p8, make_memop_idx(mop[1], idx));
254
+ gen_ldst_i64(INDEX_op_qemu_ld_i64, y, addr_p8,
255
+ make_memop_idx(mop[1], idx));
256
tcg_temp_free_internal(addr_p8);
257
258
if (need_bswap) {
259
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
260
{
261
MemOpIdx orig_oi;
262
TCGv_i64 ext_addr = NULL;
263
- TCGOpcode opc;
264
265
check_max_alignment(memop_alignment_bits(memop));
266
tcg_gen_req_mo(TCG_MO_ST_LD | TCG_MO_ST_ST);
267
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
268
hi = TCGV128_HIGH(val);
269
}
270
271
- if (tcg_ctx->addr_type == TCG_TYPE_I32) {
272
- opc = INDEX_op_qemu_st_a32_i128;
273
- } else {
274
- opc = INDEX_op_qemu_st_a64_i128;
275
- }
276
- gen_ldst(opc, TCG_TYPE_I128, tcgv_i64_temp(lo),
277
- tcgv_i64_temp(hi), addr, oi);
278
+ gen_ldst(INDEX_op_qemu_st_i128, TCG_TYPE_I128,
279
+ tcgv_i64_temp(lo), tcgv_i64_temp(hi), addr, oi);
280
281
if (need_bswap) {
282
tcg_temp_free_i64(lo);
283
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
284
285
canonicalize_memop_i128_as_i64(mop, memop);
286
287
- if (tcg_ctx->addr_type == TCG_TYPE_I32) {
288
- opc = INDEX_op_qemu_st_a32_i64;
289
- } else {
290
- opc = INDEX_op_qemu_st_a64_i64;
291
- }
292
-
293
if ((memop & MO_BSWAP) == MO_LE) {
294
x = TCGV128_LOW(val);
295
y = TCGV128_HIGH(val);
296
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
297
x = b;
298
}
299
300
- gen_ldst_i64(opc, x, addr, make_memop_idx(mop[0], idx));
301
+ gen_ldst_i64(INDEX_op_qemu_st_i64, x, addr,
302
+ make_memop_idx(mop[0], idx));
303
304
if (tcg_ctx->addr_type == TCG_TYPE_I32) {
305
TCGv_i32 t = tcg_temp_ebb_new_i32();
306
@@ -XXX,XX +XXX,XX @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
307
308
if (b) {
309
tcg_gen_bswap64_i64(b, y);
310
- gen_ldst_i64(opc, b, addr_p8, make_memop_idx(mop[1], idx));
311
+ gen_ldst_i64(INDEX_op_qemu_st_i64, b, addr_p8,
312
+ make_memop_idx(mop[1], idx));
313
tcg_temp_free_i64(b);
314
} else {
315
- gen_ldst_i64(opc, y, addr_p8, make_memop_idx(mop[1], idx));
316
+ gen_ldst_i64(INDEX_op_qemu_st_i64, y, addr_p8,
317
+ make_memop_idx(mop[1], idx));
318
}
319
tcg_temp_free_internal(addr_p8);
320
} else {
321
diff --git a/tcg/tcg.c b/tcg/tcg.c
322
index XXXXXXX..XXXXXXX 100644
323
--- a/tcg/tcg.c
324
+++ b/tcg/tcg.c
325
@@ -XXX,XX +XXX,XX @@ bool tcg_op_supported(TCGOpcode op, TCGType type, unsigned flags)
326
case INDEX_op_exit_tb:
327
case INDEX_op_goto_tb:
328
case INDEX_op_goto_ptr:
329
- case INDEX_op_qemu_ld_a32_i32:
330
- case INDEX_op_qemu_ld_a64_i32:
331
- case INDEX_op_qemu_st_a32_i32:
332
- case INDEX_op_qemu_st_a64_i32:
333
- case INDEX_op_qemu_ld_a32_i64:
334
- case INDEX_op_qemu_ld_a64_i64:
335
- case INDEX_op_qemu_st_a32_i64:
336
- case INDEX_op_qemu_st_a64_i64:
337
+ case INDEX_op_qemu_ld_i32:
338
+ case INDEX_op_qemu_st_i32:
339
+ case INDEX_op_qemu_ld_i64:
340
+ case INDEX_op_qemu_st_i64:
341
return true;
342
343
- case INDEX_op_qemu_st8_a32_i32:
344
- case INDEX_op_qemu_st8_a64_i32:
345
+ case INDEX_op_qemu_st8_i32:
346
return TCG_TARGET_HAS_qemu_st8_i32;
347
348
- case INDEX_op_qemu_ld_a32_i128:
349
- case INDEX_op_qemu_ld_a64_i128:
350
- case INDEX_op_qemu_st_a32_i128:
351
- case INDEX_op_qemu_st_a64_i128:
352
+ case INDEX_op_qemu_ld_i128:
353
+ case INDEX_op_qemu_st_i128:
354
return TCG_TARGET_HAS_qemu_ldst_i128;
355
356
case INDEX_op_mov_i32:
357
@@ -XXX,XX +XXX,XX @@ void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
358
}
359
i = 1;
360
break;
361
- case INDEX_op_qemu_ld_a32_i32:
362
- case INDEX_op_qemu_ld_a64_i32:
363
- case INDEX_op_qemu_st_a32_i32:
364
- case INDEX_op_qemu_st_a64_i32:
365
- case INDEX_op_qemu_st8_a32_i32:
366
- case INDEX_op_qemu_st8_a64_i32:
367
- case INDEX_op_qemu_ld_a32_i64:
368
- case INDEX_op_qemu_ld_a64_i64:
369
- case INDEX_op_qemu_st_a32_i64:
370
- case INDEX_op_qemu_st_a64_i64:
371
- case INDEX_op_qemu_ld_a32_i128:
372
- case INDEX_op_qemu_ld_a64_i128:
373
- case INDEX_op_qemu_st_a32_i128:
374
- case INDEX_op_qemu_st_a64_i128:
375
+ case INDEX_op_qemu_ld_i32:
376
+ case INDEX_op_qemu_st_i32:
377
+ case INDEX_op_qemu_st8_i32:
378
+ case INDEX_op_qemu_ld_i64:
379
+ case INDEX_op_qemu_st_i64:
380
+ case INDEX_op_qemu_ld_i128:
381
+ case INDEX_op_qemu_st_i128:
382
{
383
const char *s_al, *s_op, *s_at;
384
MemOpIdx oi = op->args[k++];
385
diff --git a/tcg/tci.c b/tcg/tci.c
386
index XXXXXXX..XXXXXXX 100644
387
--- a/tcg/tci.c
388
+++ b/tcg/tci.c
389
@@ -XXX,XX +XXX,XX @@ static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
390
*i4 = extract32(insn, 26, 6);
21
}
391
}
22
392
23
-static void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr)
393
-static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
394
- TCGReg *r2, TCGReg *r3, TCGReg *r4)
24
-{
395
-{
25
- /* Discard jump cache entries for any tb which might potentially
396
- *r0 = extract32(insn, 8, 4);
26
- overlap the flushed page. */
397
- *r1 = extract32(insn, 12, 4);
27
- tb_jmp_cache_clear_page(cpu, addr - TARGET_PAGE_SIZE);
398
- *r2 = extract32(insn, 16, 4);
28
- tb_jmp_cache_clear_page(cpu, addr);
399
- *r3 = extract32(insn, 20, 4);
400
- *r4 = extract32(insn, 24, 4);
29
-}
401
-}
30
-
402
-
31
/**
403
static void tci_args_rrrr(uint32_t insn,
32
* tlb_mmu_resize_locked() - perform TLB resize bookkeeping; resize if necessary
404
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
33
* @desc: The CPUTLBDesc portion of the TLB
405
{
34
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_by_mmuidx_async_0(CPUState *cpu,
406
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
35
}
407
tb_ptr = ptr;
36
qemu_spin_unlock(&env_tlb(env)->c.lock);
408
break;
37
409
38
- tb_flush_jmp_cache(cpu, addr);
410
- case INDEX_op_qemu_ld_a32_i32:
39
+ /*
411
+ case INDEX_op_qemu_ld_i32:
40
+ * Discard jump cache entries for any tb which might potentially
412
tci_args_rrm(insn, &r0, &r1, &oi);
41
+ * overlap the flushed page, which includes the previous.
413
- taddr = (uint32_t)regs[r1];
42
+ */
414
- goto do_ld_i32;
43
+ tb_jmp_cache_clear_page(cpu, addr - TARGET_PAGE_SIZE);
415
- case INDEX_op_qemu_ld_a64_i32:
44
+ tb_jmp_cache_clear_page(cpu, addr);
416
- if (TCG_TARGET_REG_BITS == 64) {
417
- tci_args_rrm(insn, &r0, &r1, &oi);
418
- taddr = regs[r1];
419
- } else {
420
- tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
421
- taddr = tci_uint64(regs[r2], regs[r1]);
422
- oi = regs[r3];
423
- }
424
- do_ld_i32:
425
+ taddr = regs[r1];
426
regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr);
427
break;
428
429
- case INDEX_op_qemu_ld_a32_i64:
430
- if (TCG_TARGET_REG_BITS == 64) {
431
- tci_args_rrm(insn, &r0, &r1, &oi);
432
- taddr = (uint32_t)regs[r1];
433
- } else {
434
- tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
435
- taddr = (uint32_t)regs[r2];
436
- oi = regs[r3];
437
- }
438
- goto do_ld_i64;
439
- case INDEX_op_qemu_ld_a64_i64:
440
+ case INDEX_op_qemu_ld_i64:
441
if (TCG_TARGET_REG_BITS == 64) {
442
tci_args_rrm(insn, &r0, &r1, &oi);
443
taddr = regs[r1];
444
} else {
445
- tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
446
- taddr = tci_uint64(regs[r3], regs[r2]);
447
- oi = regs[r4];
448
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
449
+ taddr = regs[r2];
450
+ oi = regs[r3];
451
}
452
- do_ld_i64:
453
tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
454
if (TCG_TARGET_REG_BITS == 32) {
455
tci_write_reg64(regs, r1, r0, tmp64);
456
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
457
}
458
break;
459
460
- case INDEX_op_qemu_st_a32_i32:
461
+ case INDEX_op_qemu_st_i32:
462
tci_args_rrm(insn, &r0, &r1, &oi);
463
- taddr = (uint32_t)regs[r1];
464
- goto do_st_i32;
465
- case INDEX_op_qemu_st_a64_i32:
466
- if (TCG_TARGET_REG_BITS == 64) {
467
- tci_args_rrm(insn, &r0, &r1, &oi);
468
- taddr = regs[r1];
469
- } else {
470
- tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
471
- taddr = tci_uint64(regs[r2], regs[r1]);
472
- oi = regs[r3];
473
- }
474
- do_st_i32:
475
+ taddr = regs[r1];
476
tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr);
477
break;
478
479
- case INDEX_op_qemu_st_a32_i64:
480
- if (TCG_TARGET_REG_BITS == 64) {
481
- tci_args_rrm(insn, &r0, &r1, &oi);
482
- tmp64 = regs[r0];
483
- taddr = (uint32_t)regs[r1];
484
- } else {
485
- tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
486
- tmp64 = tci_uint64(regs[r1], regs[r0]);
487
- taddr = (uint32_t)regs[r2];
488
- oi = regs[r3];
489
- }
490
- goto do_st_i64;
491
- case INDEX_op_qemu_st_a64_i64:
492
+ case INDEX_op_qemu_st_i64:
493
if (TCG_TARGET_REG_BITS == 64) {
494
tci_args_rrm(insn, &r0, &r1, &oi);
495
tmp64 = regs[r0];
496
taddr = regs[r1];
497
} else {
498
- tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
499
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
500
tmp64 = tci_uint64(regs[r1], regs[r0]);
501
- taddr = tci_uint64(regs[r3], regs[r2]);
502
- oi = regs[r4];
503
+ taddr = regs[r2];
504
+ oi = regs[r3];
505
}
506
- do_st_i64:
507
tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
508
break;
509
510
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
511
str_r(r3), str_r(r4), str_r(r5));
512
break;
513
514
- case INDEX_op_qemu_ld_a32_i32:
515
- case INDEX_op_qemu_st_a32_i32:
516
- len = 1 + 1;
517
- goto do_qemu_ldst;
518
- case INDEX_op_qemu_ld_a32_i64:
519
- case INDEX_op_qemu_st_a32_i64:
520
- case INDEX_op_qemu_ld_a64_i32:
521
- case INDEX_op_qemu_st_a64_i32:
522
- len = 1 + DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
523
- goto do_qemu_ldst;
524
- case INDEX_op_qemu_ld_a64_i64:
525
- case INDEX_op_qemu_st_a64_i64:
526
- len = 2 * DIV_ROUND_UP(64, TCG_TARGET_REG_BITS);
527
- goto do_qemu_ldst;
528
- do_qemu_ldst:
529
- switch (len) {
530
- case 2:
531
- tci_args_rrm(insn, &r0, &r1, &oi);
532
- info->fprintf_func(info->stream, "%-12s %s, %s, %x",
533
- op_name, str_r(r0), str_r(r1), oi);
534
- break;
535
- case 3:
536
+ case INDEX_op_qemu_ld_i64:
537
+ case INDEX_op_qemu_st_i64:
538
+ if (TCG_TARGET_REG_BITS == 32) {
539
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
540
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
541
op_name, str_r(r0), str_r(r1),
542
str_r(r2), str_r(r3));
543
break;
544
- case 4:
545
- tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
546
- info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s",
547
- op_name, str_r(r0), str_r(r1),
548
- str_r(r2), str_r(r3), str_r(r4));
549
- break;
550
- default:
551
- g_assert_not_reached();
552
}
553
+ /* fall through */
554
+ case INDEX_op_qemu_ld_i32:
555
+ case INDEX_op_qemu_st_i32:
556
+ tci_args_rrm(insn, &r0, &r1, &oi);
557
+ info->fprintf_func(info->stream, "%-12s %s, %s, %x",
558
+ op_name, str_r(r0), str_r(r1), oi);
559
break;
560
561
case 0:
562
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
563
index XXXXXXX..XXXXXXX 100644
564
--- a/tcg/aarch64/tcg-target.c.inc
565
+++ b/tcg/aarch64/tcg-target.c.inc
566
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
567
tcg_out_insn(s, 3506, CSEL, ext, a0, REG0(3), REG0(4), args[5]);
568
break;
569
570
- case INDEX_op_qemu_ld_a32_i32:
571
- case INDEX_op_qemu_ld_a64_i32:
572
- case INDEX_op_qemu_ld_a32_i64:
573
- case INDEX_op_qemu_ld_a64_i64:
574
+ case INDEX_op_qemu_ld_i32:
575
+ case INDEX_op_qemu_ld_i64:
576
tcg_out_qemu_ld(s, a0, a1, a2, ext);
577
break;
578
- case INDEX_op_qemu_st_a32_i32:
579
- case INDEX_op_qemu_st_a64_i32:
580
- case INDEX_op_qemu_st_a32_i64:
581
- case INDEX_op_qemu_st_a64_i64:
582
+ case INDEX_op_qemu_st_i32:
583
+ case INDEX_op_qemu_st_i64:
584
tcg_out_qemu_st(s, REG0(0), a1, a2, ext);
585
break;
586
- case INDEX_op_qemu_ld_a32_i128:
587
- case INDEX_op_qemu_ld_a64_i128:
588
+ case INDEX_op_qemu_ld_i128:
589
tcg_out_qemu_ldst_i128(s, a0, a1, a2, args[3], true);
590
break;
591
- case INDEX_op_qemu_st_a32_i128:
592
- case INDEX_op_qemu_st_a64_i128:
593
+ case INDEX_op_qemu_st_i128:
594
tcg_out_qemu_ldst_i128(s, REG0(0), REG0(1), a2, args[3], false);
595
break;
596
597
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
598
case INDEX_op_movcond_i64:
599
return C_O1_I4(r, r, rC, rZ, rZ);
600
601
- case INDEX_op_qemu_ld_a32_i32:
602
- case INDEX_op_qemu_ld_a64_i32:
603
- case INDEX_op_qemu_ld_a32_i64:
604
- case INDEX_op_qemu_ld_a64_i64:
605
+ case INDEX_op_qemu_ld_i32:
606
+ case INDEX_op_qemu_ld_i64:
607
return C_O1_I1(r, r);
608
- case INDEX_op_qemu_ld_a32_i128:
609
- case INDEX_op_qemu_ld_a64_i128:
610
+ case INDEX_op_qemu_ld_i128:
611
return C_O2_I1(r, r, r);
612
- case INDEX_op_qemu_st_a32_i32:
613
- case INDEX_op_qemu_st_a64_i32:
614
- case INDEX_op_qemu_st_a32_i64:
615
- case INDEX_op_qemu_st_a64_i64:
616
+ case INDEX_op_qemu_st_i32:
617
+ case INDEX_op_qemu_st_i64:
618
return C_O0_I2(rZ, r);
619
- case INDEX_op_qemu_st_a32_i128:
620
- case INDEX_op_qemu_st_a64_i128:
621
+ case INDEX_op_qemu_st_i128:
622
return C_O0_I3(rZ, rZ, r);
623
624
case INDEX_op_deposit_i32:
625
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
626
index XXXXXXX..XXXXXXX 100644
627
--- a/tcg/arm/tcg-target.c.inc
628
+++ b/tcg/arm/tcg-target.c.inc
629
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
630
ARITH_MOV, args[0], 0, 0);
631
break;
632
633
- case INDEX_op_qemu_ld_a32_i32:
634
+ case INDEX_op_qemu_ld_i32:
635
tcg_out_qemu_ld(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
636
break;
637
- case INDEX_op_qemu_ld_a64_i32:
638
- tcg_out_qemu_ld(s, args[0], -1, args[1], args[2],
639
- args[3], TCG_TYPE_I32);
640
- break;
641
- case INDEX_op_qemu_ld_a32_i64:
642
+ case INDEX_op_qemu_ld_i64:
643
tcg_out_qemu_ld(s, args[0], args[1], args[2], -1,
644
args[3], TCG_TYPE_I64);
645
break;
646
- case INDEX_op_qemu_ld_a64_i64:
647
- tcg_out_qemu_ld(s, args[0], args[1], args[2], args[3],
648
- args[4], TCG_TYPE_I64);
649
- break;
650
651
- case INDEX_op_qemu_st_a32_i32:
652
+ case INDEX_op_qemu_st_i32:
653
tcg_out_qemu_st(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
654
break;
655
- case INDEX_op_qemu_st_a64_i32:
656
- tcg_out_qemu_st(s, args[0], -1, args[1], args[2],
657
- args[3], TCG_TYPE_I32);
658
- break;
659
- case INDEX_op_qemu_st_a32_i64:
660
+ case INDEX_op_qemu_st_i64:
661
tcg_out_qemu_st(s, args[0], args[1], args[2], -1,
662
args[3], TCG_TYPE_I64);
663
break;
664
- case INDEX_op_qemu_st_a64_i64:
665
- tcg_out_qemu_st(s, args[0], args[1], args[2], args[3],
666
- args[4], TCG_TYPE_I64);
667
- break;
668
669
case INDEX_op_bswap16_i32:
670
tcg_out_bswap16(s, COND_AL, args[0], args[1], args[2]);
671
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
672
case INDEX_op_setcond2_i32:
673
return C_O1_I4(r, r, r, rI, rI);
674
675
- case INDEX_op_qemu_ld_a32_i32:
676
+ case INDEX_op_qemu_ld_i32:
677
return C_O1_I1(r, q);
678
- case INDEX_op_qemu_ld_a64_i32:
679
- return C_O1_I2(r, q, q);
680
- case INDEX_op_qemu_ld_a32_i64:
681
+ case INDEX_op_qemu_ld_i64:
682
return C_O2_I1(e, p, q);
683
- case INDEX_op_qemu_ld_a64_i64:
684
- return C_O2_I2(e, p, q, q);
685
- case INDEX_op_qemu_st_a32_i32:
686
+ case INDEX_op_qemu_st_i32:
687
return C_O0_I2(q, q);
688
- case INDEX_op_qemu_st_a64_i32:
689
- return C_O0_I3(q, q, q);
690
- case INDEX_op_qemu_st_a32_i64:
691
+ case INDEX_op_qemu_st_i64:
692
return C_O0_I3(Q, p, q);
693
- case INDEX_op_qemu_st_a64_i64:
694
- return C_O0_I4(Q, p, q, q);
695
696
case INDEX_op_st_vec:
697
return C_O0_I2(w, r);
698
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
699
index XXXXXXX..XXXXXXX 100644
700
--- a/tcg/i386/tcg-target.c.inc
701
+++ b/tcg/i386/tcg-target.c.inc
702
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
703
tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0);
704
break;
705
706
- case INDEX_op_qemu_ld_a64_i32:
707
- if (TCG_TARGET_REG_BITS == 32) {
708
- tcg_out_qemu_ld(s, a0, -1, a1, a2, args[3], TCG_TYPE_I32);
709
- break;
710
- }
711
- /* fall through */
712
- case INDEX_op_qemu_ld_a32_i32:
713
+ case INDEX_op_qemu_ld_i32:
714
tcg_out_qemu_ld(s, a0, -1, a1, -1, a2, TCG_TYPE_I32);
715
break;
716
- case INDEX_op_qemu_ld_a32_i64:
717
+ case INDEX_op_qemu_ld_i64:
718
if (TCG_TARGET_REG_BITS == 64) {
719
tcg_out_qemu_ld(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
720
} else {
721
tcg_out_qemu_ld(s, a0, a1, a2, -1, args[3], TCG_TYPE_I64);
722
}
723
break;
724
- case INDEX_op_qemu_ld_a64_i64:
725
- if (TCG_TARGET_REG_BITS == 64) {
726
- tcg_out_qemu_ld(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
727
- } else {
728
- tcg_out_qemu_ld(s, a0, a1, a2, args[3], args[4], TCG_TYPE_I64);
729
- }
730
- break;
731
- case INDEX_op_qemu_ld_a32_i128:
732
- case INDEX_op_qemu_ld_a64_i128:
733
+ case INDEX_op_qemu_ld_i128:
734
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
735
tcg_out_qemu_ld(s, a0, a1, a2, -1, args[3], TCG_TYPE_I128);
736
break;
737
738
- case INDEX_op_qemu_st_a64_i32:
739
- case INDEX_op_qemu_st8_a64_i32:
740
- if (TCG_TARGET_REG_BITS == 32) {
741
- tcg_out_qemu_st(s, a0, -1, a1, a2, args[3], TCG_TYPE_I32);
742
- break;
743
- }
744
- /* fall through */
745
- case INDEX_op_qemu_st_a32_i32:
746
- case INDEX_op_qemu_st8_a32_i32:
747
+ case INDEX_op_qemu_st_i32:
748
+ case INDEX_op_qemu_st8_i32:
749
tcg_out_qemu_st(s, a0, -1, a1, -1, a2, TCG_TYPE_I32);
750
break;
751
- case INDEX_op_qemu_st_a32_i64:
752
+ case INDEX_op_qemu_st_i64:
753
if (TCG_TARGET_REG_BITS == 64) {
754
tcg_out_qemu_st(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
755
} else {
756
tcg_out_qemu_st(s, a0, a1, a2, -1, args[3], TCG_TYPE_I64);
757
}
758
break;
759
- case INDEX_op_qemu_st_a64_i64:
760
- if (TCG_TARGET_REG_BITS == 64) {
761
- tcg_out_qemu_st(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
762
- } else {
763
- tcg_out_qemu_st(s, a0, a1, a2, args[3], args[4], TCG_TYPE_I64);
764
- }
765
- break;
766
- case INDEX_op_qemu_st_a32_i128:
767
- case INDEX_op_qemu_st_a64_i128:
768
+ case INDEX_op_qemu_st_i128:
769
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
770
tcg_out_qemu_st(s, a0, a1, a2, -1, args[3], TCG_TYPE_I128);
771
break;
772
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
773
case INDEX_op_clz_i64:
774
return have_lzcnt ? C_N1_I2(r, r, rW) : C_N1_I2(r, r, r);
775
776
- case INDEX_op_qemu_ld_a32_i32:
777
+ case INDEX_op_qemu_ld_i32:
778
return C_O1_I1(r, L);
779
- case INDEX_op_qemu_ld_a64_i32:
780
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L) : C_O1_I2(r, L, L);
781
782
- case INDEX_op_qemu_st_a32_i32:
783
+ case INDEX_op_qemu_st_i32:
784
return C_O0_I2(L, L);
785
- case INDEX_op_qemu_st_a64_i32:
786
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(L, L) : C_O0_I3(L, L, L);
787
- case INDEX_op_qemu_st8_a32_i32:
788
+ case INDEX_op_qemu_st8_i32:
789
return C_O0_I2(s, L);
790
- case INDEX_op_qemu_st8_a64_i32:
791
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(s, L) : C_O0_I3(s, L, L);
792
793
- case INDEX_op_qemu_ld_a32_i64:
794
+ case INDEX_op_qemu_ld_i64:
795
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L) : C_O2_I1(r, r, L);
796
- case INDEX_op_qemu_ld_a64_i64:
797
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L) : C_O2_I2(r, r, L, L);
798
799
- case INDEX_op_qemu_st_a32_i64:
800
+ case INDEX_op_qemu_st_i64:
801
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(L, L) : C_O0_I3(L, L, L);
802
- case INDEX_op_qemu_st_a64_i64:
803
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(L, L) : C_O0_I4(L, L, L, L);
804
805
- case INDEX_op_qemu_ld_a32_i128:
806
- case INDEX_op_qemu_ld_a64_i128:
807
+ case INDEX_op_qemu_ld_i128:
808
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
809
return C_O2_I1(r, r, L);
810
- case INDEX_op_qemu_st_a32_i128:
811
- case INDEX_op_qemu_st_a64_i128:
812
+ case INDEX_op_qemu_st_i128:
813
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
814
return C_O0_I3(L, L, L);
815
816
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
817
index XXXXXXX..XXXXXXX 100644
818
--- a/tcg/loongarch64/tcg-target.c.inc
819
+++ b/tcg/loongarch64/tcg-target.c.inc
820
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
821
tcg_out_ldst(s, OPC_ST_D, a0, a1, a2);
822
break;
823
824
- case INDEX_op_qemu_ld_a32_i32:
825
- case INDEX_op_qemu_ld_a64_i32:
826
+ case INDEX_op_qemu_ld_i32:
827
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
828
break;
829
- case INDEX_op_qemu_ld_a32_i64:
830
- case INDEX_op_qemu_ld_a64_i64:
831
+ case INDEX_op_qemu_ld_i64:
832
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
833
break;
834
- case INDEX_op_qemu_ld_a32_i128:
835
- case INDEX_op_qemu_ld_a64_i128:
836
+ case INDEX_op_qemu_ld_i128:
837
tcg_out_qemu_ldst_i128(s, a0, a1, a2, a3, true);
838
break;
839
- case INDEX_op_qemu_st_a32_i32:
840
- case INDEX_op_qemu_st_a64_i32:
841
+ case INDEX_op_qemu_st_i32:
842
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
843
break;
844
- case INDEX_op_qemu_st_a32_i64:
845
- case INDEX_op_qemu_st_a64_i64:
846
+ case INDEX_op_qemu_st_i64:
847
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
848
break;
849
- case INDEX_op_qemu_st_a32_i128:
850
- case INDEX_op_qemu_st_a64_i128:
851
+ case INDEX_op_qemu_st_i128:
852
tcg_out_qemu_ldst_i128(s, a0, a1, a2, a3, false);
853
break;
854
855
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
856
case INDEX_op_st32_i64:
857
case INDEX_op_st_i32:
858
case INDEX_op_st_i64:
859
- case INDEX_op_qemu_st_a32_i32:
860
- case INDEX_op_qemu_st_a64_i32:
861
- case INDEX_op_qemu_st_a32_i64:
862
- case INDEX_op_qemu_st_a64_i64:
863
+ case INDEX_op_qemu_st_i32:
864
+ case INDEX_op_qemu_st_i64:
865
return C_O0_I2(rZ, r);
866
867
- case INDEX_op_qemu_ld_a32_i128:
868
- case INDEX_op_qemu_ld_a64_i128:
869
+ case INDEX_op_qemu_ld_i128:
870
return C_N2_I1(r, r, r);
871
872
- case INDEX_op_qemu_st_a32_i128:
873
- case INDEX_op_qemu_st_a64_i128:
874
+ case INDEX_op_qemu_st_i128:
875
return C_O0_I3(r, r, r);
876
877
case INDEX_op_brcond_i32:
878
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
879
case INDEX_op_ld32u_i64:
880
case INDEX_op_ld_i32:
881
case INDEX_op_ld_i64:
882
- case INDEX_op_qemu_ld_a32_i32:
883
- case INDEX_op_qemu_ld_a64_i32:
884
- case INDEX_op_qemu_ld_a32_i64:
885
- case INDEX_op_qemu_ld_a64_i64:
886
+ case INDEX_op_qemu_ld_i32:
887
+ case INDEX_op_qemu_ld_i64:
888
return C_O1_I1(r, r);
889
890
case INDEX_op_andc_i32:
891
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
892
index XXXXXXX..XXXXXXX 100644
893
--- a/tcg/mips/tcg-target.c.inc
894
+++ b/tcg/mips/tcg-target.c.inc
895
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
896
tcg_out_setcond2(s, args[5], a0, a1, a2, args[3], args[4]);
897
break;
898
899
- case INDEX_op_qemu_ld_a64_i32:
900
- if (TCG_TARGET_REG_BITS == 32) {
901
- tcg_out_qemu_ld(s, a0, 0, a1, a2, args[3], TCG_TYPE_I32);
902
- break;
903
- }
904
- /* fall through */
905
- case INDEX_op_qemu_ld_a32_i32:
906
+ case INDEX_op_qemu_ld_i32:
907
tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I32);
908
break;
909
- case INDEX_op_qemu_ld_a32_i64:
910
+ case INDEX_op_qemu_ld_i64:
911
if (TCG_TARGET_REG_BITS == 64) {
912
tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
913
} else {
914
tcg_out_qemu_ld(s, a0, a1, a2, 0, args[3], TCG_TYPE_I64);
915
}
916
break;
917
- case INDEX_op_qemu_ld_a64_i64:
918
- if (TCG_TARGET_REG_BITS == 64) {
919
- tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
920
- } else {
921
- tcg_out_qemu_ld(s, a0, a1, a2, args[3], args[4], TCG_TYPE_I64);
922
- }
923
- break;
924
925
- case INDEX_op_qemu_st_a64_i32:
926
- if (TCG_TARGET_REG_BITS == 32) {
927
- tcg_out_qemu_st(s, a0, 0, a1, a2, args[3], TCG_TYPE_I32);
928
- break;
929
- }
930
- /* fall through */
931
- case INDEX_op_qemu_st_a32_i32:
932
+ case INDEX_op_qemu_st_i32:
933
tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I32);
934
break;
935
- case INDEX_op_qemu_st_a32_i64:
936
+ case INDEX_op_qemu_st_i64:
937
if (TCG_TARGET_REG_BITS == 64) {
938
tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
939
} else {
940
tcg_out_qemu_st(s, a0, a1, a2, 0, args[3], TCG_TYPE_I64);
941
}
942
break;
943
- case INDEX_op_qemu_st_a64_i64:
944
- if (TCG_TARGET_REG_BITS == 64) {
945
- tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
946
- } else {
947
- tcg_out_qemu_st(s, a0, a1, a2, args[3], args[4], TCG_TYPE_I64);
948
- }
949
- break;
950
951
case INDEX_op_add2_i32:
952
tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5],
953
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
954
case INDEX_op_brcond2_i32:
955
return C_O0_I4(rZ, rZ, rZ, rZ);
956
957
- case INDEX_op_qemu_ld_a32_i32:
958
+ case INDEX_op_qemu_ld_i32:
959
return C_O1_I1(r, r);
960
- case INDEX_op_qemu_ld_a64_i32:
961
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O1_I2(r, r, r);
962
- case INDEX_op_qemu_st_a32_i32:
963
+ case INDEX_op_qemu_st_i32:
964
return C_O0_I2(rZ, r);
965
- case INDEX_op_qemu_st_a64_i32:
966
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rZ, r) : C_O0_I3(rZ, r, r);
967
- case INDEX_op_qemu_ld_a32_i64:
968
+ case INDEX_op_qemu_ld_i64:
969
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
970
- case INDEX_op_qemu_ld_a64_i64:
971
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I2(r, r, r, r);
972
- case INDEX_op_qemu_st_a32_i64:
973
+ case INDEX_op_qemu_st_i64:
974
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rZ, r) : C_O0_I3(rZ, rZ, r);
975
- case INDEX_op_qemu_st_a64_i64:
976
- return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rZ, r)
977
- : C_O0_I4(rZ, rZ, r, r));
978
979
default:
980
return C_NotImplemented;
981
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
982
index XXXXXXX..XXXXXXX 100644
983
--- a/tcg/ppc/tcg-target.c.inc
984
+++ b/tcg/ppc/tcg-target.c.inc
985
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
986
tcg_out32(s, MODUD | TAB(args[0], args[1], args[2]));
987
break;
988
989
- case INDEX_op_qemu_ld_a64_i32:
990
- if (TCG_TARGET_REG_BITS == 32) {
991
- tcg_out_qemu_ld(s, args[0], -1, args[1], args[2],
992
- args[3], TCG_TYPE_I32);
993
- break;
994
- }
995
- /* fall through */
996
- case INDEX_op_qemu_ld_a32_i32:
997
+ case INDEX_op_qemu_ld_i32:
998
tcg_out_qemu_ld(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
999
break;
1000
- case INDEX_op_qemu_ld_a32_i64:
1001
+ case INDEX_op_qemu_ld_i64:
1002
if (TCG_TARGET_REG_BITS == 64) {
1003
tcg_out_qemu_ld(s, args[0], -1, args[1], -1,
1004
args[2], TCG_TYPE_I64);
1005
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
1006
args[3], TCG_TYPE_I64);
1007
}
1008
break;
1009
- case INDEX_op_qemu_ld_a64_i64:
1010
- if (TCG_TARGET_REG_BITS == 64) {
1011
- tcg_out_qemu_ld(s, args[0], -1, args[1], -1,
1012
- args[2], TCG_TYPE_I64);
1013
- } else {
1014
- tcg_out_qemu_ld(s, args[0], args[1], args[2], args[3],
1015
- args[4], TCG_TYPE_I64);
1016
- }
1017
- break;
1018
- case INDEX_op_qemu_ld_a32_i128:
1019
- case INDEX_op_qemu_ld_a64_i128:
1020
+ case INDEX_op_qemu_ld_i128:
1021
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
1022
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], true);
1023
break;
1024
1025
- case INDEX_op_qemu_st_a64_i32:
1026
- if (TCG_TARGET_REG_BITS == 32) {
1027
- tcg_out_qemu_st(s, args[0], -1, args[1], args[2],
1028
- args[3], TCG_TYPE_I32);
1029
- break;
1030
- }
1031
- /* fall through */
1032
- case INDEX_op_qemu_st_a32_i32:
1033
+ case INDEX_op_qemu_st_i32:
1034
tcg_out_qemu_st(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
1035
break;
1036
- case INDEX_op_qemu_st_a32_i64:
1037
+ case INDEX_op_qemu_st_i64:
1038
if (TCG_TARGET_REG_BITS == 64) {
1039
tcg_out_qemu_st(s, args[0], -1, args[1], -1,
1040
args[2], TCG_TYPE_I64);
1041
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
1042
args[3], TCG_TYPE_I64);
1043
}
1044
break;
1045
- case INDEX_op_qemu_st_a64_i64:
1046
- if (TCG_TARGET_REG_BITS == 64) {
1047
- tcg_out_qemu_st(s, args[0], -1, args[1], -1,
1048
- args[2], TCG_TYPE_I64);
1049
- } else {
1050
- tcg_out_qemu_st(s, args[0], args[1], args[2], args[3],
1051
- args[4], TCG_TYPE_I64);
1052
- }
1053
- break;
1054
- case INDEX_op_qemu_st_a32_i128:
1055
- case INDEX_op_qemu_st_a64_i128:
1056
+ case INDEX_op_qemu_st_i128:
1057
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
1058
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], false);
1059
break;
1060
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
1061
case INDEX_op_sub2_i32:
1062
return C_O2_I4(r, r, rI, rZM, r, r);
1063
1064
- case INDEX_op_qemu_ld_a32_i32:
1065
+ case INDEX_op_qemu_ld_i32:
1066
return C_O1_I1(r, r);
1067
- case INDEX_op_qemu_ld_a64_i32:
1068
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O1_I2(r, r, r);
1069
- case INDEX_op_qemu_ld_a32_i64:
1070
+ case INDEX_op_qemu_ld_i64:
1071
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
1072
- case INDEX_op_qemu_ld_a64_i64:
1073
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I2(r, r, r, r);
1074
1075
- case INDEX_op_qemu_st_a32_i32:
1076
+ case INDEX_op_qemu_st_i32:
1077
return C_O0_I2(r, r);
1078
- case INDEX_op_qemu_st_a64_i32:
1079
+ case INDEX_op_qemu_st_i64:
1080
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
1081
- case INDEX_op_qemu_st_a32_i64:
1082
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
1083
- case INDEX_op_qemu_st_a64_i64:
1084
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I4(r, r, r, r);
1085
1086
- case INDEX_op_qemu_ld_a32_i128:
1087
- case INDEX_op_qemu_ld_a64_i128:
1088
+ case INDEX_op_qemu_ld_i128:
1089
return C_N1O1_I1(o, m, r);
1090
- case INDEX_op_qemu_st_a32_i128:
1091
- case INDEX_op_qemu_st_a64_i128:
1092
+ case INDEX_op_qemu_st_i128:
1093
return C_O0_I3(o, m, r);
1094
1095
case INDEX_op_add_vec:
1096
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
1097
index XXXXXXX..XXXXXXX 100644
1098
--- a/tcg/riscv/tcg-target.c.inc
1099
+++ b/tcg/riscv/tcg-target.c.inc
1100
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
1101
args[3], const_args[3], args[4], const_args[4]);
1102
break;
1103
1104
- case INDEX_op_qemu_ld_a32_i32:
1105
- case INDEX_op_qemu_ld_a64_i32:
1106
+ case INDEX_op_qemu_ld_i32:
1107
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
1108
break;
1109
- case INDEX_op_qemu_ld_a32_i64:
1110
- case INDEX_op_qemu_ld_a64_i64:
1111
+ case INDEX_op_qemu_ld_i64:
1112
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
1113
break;
1114
- case INDEX_op_qemu_st_a32_i32:
1115
- case INDEX_op_qemu_st_a64_i32:
1116
+ case INDEX_op_qemu_st_i32:
1117
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
1118
break;
1119
- case INDEX_op_qemu_st_a32_i64:
1120
- case INDEX_op_qemu_st_a64_i64:
1121
+ case INDEX_op_qemu_st_i64:
1122
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
1123
break;
1124
1125
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
1126
case INDEX_op_sub2_i64:
1127
return C_O2_I4(r, r, rZ, rZ, rM, rM);
1128
1129
- case INDEX_op_qemu_ld_a32_i32:
1130
- case INDEX_op_qemu_ld_a64_i32:
1131
- case INDEX_op_qemu_ld_a32_i64:
1132
- case INDEX_op_qemu_ld_a64_i64:
1133
+ case INDEX_op_qemu_ld_i32:
1134
+ case INDEX_op_qemu_ld_i64:
1135
return C_O1_I1(r, r);
1136
- case INDEX_op_qemu_st_a32_i32:
1137
- case INDEX_op_qemu_st_a64_i32:
1138
- case INDEX_op_qemu_st_a32_i64:
1139
- case INDEX_op_qemu_st_a64_i64:
1140
+ case INDEX_op_qemu_st_i32:
1141
+ case INDEX_op_qemu_st_i64:
1142
return C_O0_I2(rZ, r);
1143
1144
case INDEX_op_st_vec:
1145
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
1146
index XXXXXXX..XXXXXXX 100644
1147
--- a/tcg/s390x/tcg-target.c.inc
1148
+++ b/tcg/s390x/tcg-target.c.inc
1149
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
1150
args[2], const_args[2], args[3], const_args[3], args[4]);
1151
break;
1152
1153
- case INDEX_op_qemu_ld_a32_i32:
1154
- case INDEX_op_qemu_ld_a64_i32:
1155
+ case INDEX_op_qemu_ld_i32:
1156
tcg_out_qemu_ld(s, args[0], args[1], args[2], TCG_TYPE_I32);
1157
break;
1158
- case INDEX_op_qemu_ld_a32_i64:
1159
- case INDEX_op_qemu_ld_a64_i64:
1160
+ case INDEX_op_qemu_ld_i64:
1161
tcg_out_qemu_ld(s, args[0], args[1], args[2], TCG_TYPE_I64);
1162
break;
1163
- case INDEX_op_qemu_st_a32_i32:
1164
- case INDEX_op_qemu_st_a64_i32:
1165
+ case INDEX_op_qemu_st_i32:
1166
tcg_out_qemu_st(s, args[0], args[1], args[2], TCG_TYPE_I32);
1167
break;
1168
- case INDEX_op_qemu_st_a32_i64:
1169
- case INDEX_op_qemu_st_a64_i64:
1170
+ case INDEX_op_qemu_st_i64:
1171
tcg_out_qemu_st(s, args[0], args[1], args[2], TCG_TYPE_I64);
1172
break;
1173
- case INDEX_op_qemu_ld_a32_i128:
1174
- case INDEX_op_qemu_ld_a64_i128:
1175
+ case INDEX_op_qemu_ld_i128:
1176
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], true);
1177
break;
1178
- case INDEX_op_qemu_st_a32_i128:
1179
- case INDEX_op_qemu_st_a64_i128:
1180
+ case INDEX_op_qemu_st_i128:
1181
tcg_out_qemu_ldst_i128(s, args[0], args[1], args[2], args[3], false);
1182
break;
1183
1184
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
1185
case INDEX_op_ctpop_i64:
1186
return C_O1_I1(r, r);
1187
1188
- case INDEX_op_qemu_ld_a32_i32:
1189
- case INDEX_op_qemu_ld_a64_i32:
1190
- case INDEX_op_qemu_ld_a32_i64:
1191
- case INDEX_op_qemu_ld_a64_i64:
1192
+ case INDEX_op_qemu_ld_i32:
1193
+ case INDEX_op_qemu_ld_i64:
1194
return C_O1_I1(r, r);
1195
- case INDEX_op_qemu_st_a32_i64:
1196
- case INDEX_op_qemu_st_a64_i64:
1197
- case INDEX_op_qemu_st_a32_i32:
1198
- case INDEX_op_qemu_st_a64_i32:
1199
+ case INDEX_op_qemu_st_i64:
1200
+ case INDEX_op_qemu_st_i32:
1201
return C_O0_I2(r, r);
1202
- case INDEX_op_qemu_ld_a32_i128:
1203
- case INDEX_op_qemu_ld_a64_i128:
1204
+ case INDEX_op_qemu_ld_i128:
1205
return C_O2_I1(o, m, r);
1206
- case INDEX_op_qemu_st_a32_i128:
1207
- case INDEX_op_qemu_st_a64_i128:
1208
+ case INDEX_op_qemu_st_i128:
1209
return C_O0_I3(o, m, r);
1210
1211
case INDEX_op_deposit_i32:
1212
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
1213
index XXXXXXX..XXXXXXX 100644
1214
--- a/tcg/sparc64/tcg-target.c.inc
1215
+++ b/tcg/sparc64/tcg-target.c.inc
1216
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
1217
tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
1218
break;
1219
1220
- case INDEX_op_qemu_ld_a32_i32:
1221
- case INDEX_op_qemu_ld_a64_i32:
1222
+ case INDEX_op_qemu_ld_i32:
1223
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I32);
1224
break;
1225
- case INDEX_op_qemu_ld_a32_i64:
1226
- case INDEX_op_qemu_ld_a64_i64:
1227
+ case INDEX_op_qemu_ld_i64:
1228
tcg_out_qemu_ld(s, a0, a1, a2, TCG_TYPE_I64);
1229
break;
1230
- case INDEX_op_qemu_st_a32_i32:
1231
- case INDEX_op_qemu_st_a64_i32:
1232
+ case INDEX_op_qemu_st_i32:
1233
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
1234
break;
1235
- case INDEX_op_qemu_st_a32_i64:
1236
- case INDEX_op_qemu_st_a64_i64:
1237
+ case INDEX_op_qemu_st_i64:
1238
tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
1239
break;
1240
1241
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
1242
case INDEX_op_extu_i32_i64:
1243
case INDEX_op_extract_i64:
1244
case INDEX_op_sextract_i64:
1245
- case INDEX_op_qemu_ld_a32_i32:
1246
- case INDEX_op_qemu_ld_a64_i32:
1247
- case INDEX_op_qemu_ld_a32_i64:
1248
- case INDEX_op_qemu_ld_a64_i64:
1249
+ case INDEX_op_qemu_ld_i32:
1250
+ case INDEX_op_qemu_ld_i64:
1251
return C_O1_I1(r, r);
1252
1253
case INDEX_op_st8_i32:
1254
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
1255
case INDEX_op_st_i32:
1256
case INDEX_op_st32_i64:
1257
case INDEX_op_st_i64:
1258
- case INDEX_op_qemu_st_a32_i32:
1259
- case INDEX_op_qemu_st_a64_i32:
1260
- case INDEX_op_qemu_st_a32_i64:
1261
- case INDEX_op_qemu_st_a64_i64:
1262
+ case INDEX_op_qemu_st_i32:
1263
+ case INDEX_op_qemu_st_i64:
1264
return C_O0_I2(rZ, r);
1265
1266
case INDEX_op_add_i32:
1267
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
1268
index XXXXXXX..XXXXXXX 100644
1269
--- a/tcg/tci/tcg-target.c.inc
1270
+++ b/tcg/tci/tcg-target.c.inc
1271
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
1272
case INDEX_op_setcond2_i32:
1273
return C_O1_I4(r, r, r, r, r);
1274
1275
- case INDEX_op_qemu_ld_a32_i32:
1276
+ case INDEX_op_qemu_ld_i32:
1277
return C_O1_I1(r, r);
1278
- case INDEX_op_qemu_ld_a64_i32:
1279
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O1_I2(r, r, r);
1280
- case INDEX_op_qemu_ld_a32_i64:
1281
+ case INDEX_op_qemu_ld_i64:
1282
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
1283
- case INDEX_op_qemu_ld_a64_i64:
1284
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I2(r, r, r, r);
1285
- case INDEX_op_qemu_st_a32_i32:
1286
+ case INDEX_op_qemu_st_i32:
1287
return C_O0_I2(r, r);
1288
- case INDEX_op_qemu_st_a64_i32:
1289
+ case INDEX_op_qemu_st_i64:
1290
return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
1291
- case INDEX_op_qemu_st_a32_i64:
1292
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
1293
- case INDEX_op_qemu_st_a64_i64:
1294
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I4(r, r, r, r);
1295
1296
default:
1297
return C_NotImplemented;
1298
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rrrbb(TCGContext *s, TCGOpcode op, TCGReg r0,
1299
tcg_out32(s, insn);
45
}
1300
}
46
1301
47
/**
1302
-static void tcg_out_op_rrrrr(TCGContext *s, TCGOpcode op, TCGReg r0,
48
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_range_by_mmuidx_async_0(CPUState *cpu,
1303
- TCGReg r1, TCGReg r2, TCGReg r3, TCGReg r4)
49
return;
1304
-{
50
}
1305
- tcg_insn_unit insn = 0;
51
1306
-
52
- for (target_ulong i = 0; i < d.len; i += TARGET_PAGE_SIZE) {
1307
- insn = deposit32(insn, 0, 8, op);
53
- tb_flush_jmp_cache(cpu, d.addr + i);
1308
- insn = deposit32(insn, 8, 4, r0);
54
+ /*
1309
- insn = deposit32(insn, 12, 4, r1);
55
+ * Discard jump cache entries for any tb which might potentially
1310
- insn = deposit32(insn, 16, 4, r2);
56
+ * overlap the flushed pages, which includes the previous.
1311
- insn = deposit32(insn, 20, 4, r3);
57
+ */
1312
- insn = deposit32(insn, 24, 4, r4);
58
+ d.addr -= TARGET_PAGE_SIZE;
1313
- tcg_out32(s, insn);
59
+ for (target_ulong i = 0, n = d.len / TARGET_PAGE_SIZE + 1; i < n; i++) {
1314
-}
60
+ tb_jmp_cache_clear_page(cpu, d.addr);
1315
-
61
+ d.addr += TARGET_PAGE_SIZE;
1316
static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
62
}
1317
TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3)
63
}
1318
{
1319
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
1320
tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], args[3]);
1321
break;
1322
1323
- case INDEX_op_qemu_ld_a32_i32:
1324
- case INDEX_op_qemu_st_a32_i32:
1325
- tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
1326
- break;
1327
- case INDEX_op_qemu_ld_a64_i32:
1328
- case INDEX_op_qemu_st_a64_i32:
1329
- case INDEX_op_qemu_ld_a32_i64:
1330
- case INDEX_op_qemu_st_a32_i64:
1331
- if (TCG_TARGET_REG_BITS == 64) {
1332
- tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
1333
- } else {
1334
+ case INDEX_op_qemu_ld_i64:
1335
+ case INDEX_op_qemu_st_i64:
1336
+ if (TCG_TARGET_REG_BITS == 32) {
1337
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[3]);
1338
tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], TCG_REG_TMP);
1339
+ break;
1340
}
1341
- break;
1342
- case INDEX_op_qemu_ld_a64_i64:
1343
- case INDEX_op_qemu_st_a64_i64:
1344
- if (TCG_TARGET_REG_BITS == 64) {
1345
- tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
1346
+ /* fall through */
1347
+ case INDEX_op_qemu_ld_i32:
1348
+ case INDEX_op_qemu_st_i32:
1349
+ if (TCG_TARGET_REG_BITS == 64 && s->addr_type == TCG_TYPE_I32) {
1350
+ tcg_out_ext32u(s, TCG_REG_TMP, args[1]);
1351
+ tcg_out_op_rrm(s, opc, args[0], TCG_REG_TMP, args[2]);
1352
} else {
1353
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[4]);
1354
- tcg_out_op_rrrrr(s, opc, args[0], args[1],
1355
- args[2], args[3], TCG_REG_TMP);
1356
+ tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
1357
}
1358
break;
64
1359
65
--
1360
--
66
2.34.1
1361
2.43.0
67
1362
68
1363
diff view generated by jsdifflib
New patch
1
1
The guest address will now always be TCG_TYPE_I32.
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/arm/tcg-target.c.inc | 73 +++++++++++++---------------------------
7
1 file changed, 23 insertions(+), 50 deletions(-)
8
9
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/arm/tcg-target.c.inc
12
+++ b/tcg/arm/tcg-target.c.inc
13
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ldrd_r(TCGContext *s, ARMCond cond, TCGReg rt,
14
tcg_out_memop_r(s, cond, INSN_LDRD_REG, rt, rn, rm, 1, 1, 0);
15
}
16
17
-static void __attribute__((unused))
18
-tcg_out_ldrd_rwb(TCGContext *s, ARMCond cond, TCGReg rt, TCGReg rn, TCGReg rm)
19
-{
20
- tcg_out_memop_r(s, cond, INSN_LDRD_REG, rt, rn, rm, 1, 1, 1);
21
-}
22
-
23
-static void __attribute__((unused))
24
-tcg_out_strd_8(TCGContext *s, ARMCond cond, TCGReg rt, TCGReg rn, int imm8)
25
+static void tcg_out_strd_8(TCGContext *s, ARMCond cond, TCGReg rt,
26
+ TCGReg rn, int imm8)
27
{
28
tcg_out_memop_8(s, cond, INSN_STRD_IMM, rt, rn, imm8, 1, 0);
29
}
30
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
31
#define MIN_TLB_MASK_TABLE_OFS -256
32
33
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
34
- TCGReg addrlo, TCGReg addrhi,
35
- MemOpIdx oi, bool is_ld)
36
+ TCGReg addr, MemOpIdx oi, bool is_ld)
37
{
38
TCGLabelQemuLdst *ldst = NULL;
39
MemOp opc = get_memop(oi);
40
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
41
if (tcg_use_softmmu) {
42
*h = (HostAddress){
43
.cond = COND_AL,
44
- .base = addrlo,
45
+ .base = addr,
46
.index = TCG_REG_R1,
47
.index_scratch = true,
48
};
49
} else {
50
*h = (HostAddress){
51
.cond = COND_AL,
52
- .base = addrlo,
53
+ .base = addr,
54
.index = guest_base ? TCG_REG_GUEST_BASE : -1,
55
.index_scratch = false,
56
};
57
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
58
ldst = new_ldst_label(s);
59
ldst->is_ld = is_ld;
60
ldst->oi = oi;
61
- ldst->addrlo_reg = addrlo;
62
- ldst->addrhi_reg = addrhi;
63
+ ldst->addrlo_reg = addr;
64
65
/* Load cpu->neg.tlb.f[mmu_idx].{mask,table} into {r0,r1}. */
66
QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, mask) != 0);
67
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
68
tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_AREG0, fast_off);
69
70
/* Extract the tlb index from the address into R0. */
71
- tcg_out_dat_reg(s, COND_AL, ARITH_AND, TCG_REG_R0, TCG_REG_R0, addrlo,
72
+ tcg_out_dat_reg(s, COND_AL, ARITH_AND, TCG_REG_R0, TCG_REG_R0, addr,
73
SHIFT_IMM_LSR(s->page_bits - CPU_TLB_ENTRY_BITS));
74
75
/*
76
* Add the tlb_table pointer, creating the CPUTLBEntry address in R1.
77
- * Load the tlb comparator into R2/R3 and the fast path addend into R1.
78
+ * Load the tlb comparator into R2 and the fast path addend into R1.
79
*/
80
QEMU_BUILD_BUG_ON(HOST_BIG_ENDIAN);
81
if (cmp_off == 0) {
82
- if (s->addr_type == TCG_TYPE_I32) {
83
- tcg_out_ld32_rwb(s, COND_AL, TCG_REG_R2,
84
- TCG_REG_R1, TCG_REG_R0);
85
- } else {
86
- tcg_out_ldrd_rwb(s, COND_AL, TCG_REG_R2,
87
- TCG_REG_R1, TCG_REG_R0);
88
- }
89
+ tcg_out_ld32_rwb(s, COND_AL, TCG_REG_R2, TCG_REG_R1, TCG_REG_R0);
90
} else {
91
tcg_out_dat_reg(s, COND_AL, ARITH_ADD,
92
TCG_REG_R1, TCG_REG_R1, TCG_REG_R0, 0);
93
- if (s->addr_type == TCG_TYPE_I32) {
94
- tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R1, cmp_off);
95
- } else {
96
- tcg_out_ldrd_8(s, COND_AL, TCG_REG_R2, TCG_REG_R1, cmp_off);
97
- }
98
+ tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R1, cmp_off);
99
}
100
101
/* Load the tlb addend. */
102
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
103
* This leaves the least significant alignment bits unchanged, and of
104
* course must be zero.
105
*/
106
- t_addr = addrlo;
107
+ t_addr = addr;
108
if (a_mask < s_mask) {
109
t_addr = TCG_REG_R0;
110
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, t_addr,
111
- addrlo, s_mask - a_mask);
112
+ addr, s_mask - a_mask);
113
}
114
if (use_armv7_instructions && s->page_bits <= 16) {
115
tcg_out_movi32(s, COND_AL, TCG_REG_TMP, ~(s->page_mask | a_mask));
116
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
117
} else {
118
if (a_mask) {
119
tcg_debug_assert(a_mask <= 0xff);
120
- tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addrlo, a_mask);
121
+ tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addr, a_mask);
122
}
123
tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP, 0, t_addr,
124
SHIFT_IMM_LSR(s->page_bits));
125
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
126
0, TCG_REG_R2, TCG_REG_TMP,
127
SHIFT_IMM_LSL(s->page_bits));
128
}
129
-
130
- if (s->addr_type != TCG_TYPE_I32) {
131
- tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0, TCG_REG_R3, addrhi, 0);
132
- }
133
} else if (a_mask) {
134
ldst = new_ldst_label(s);
135
ldst->is_ld = is_ld;
136
ldst->oi = oi;
137
- ldst->addrlo_reg = addrlo;
138
- ldst->addrhi_reg = addrhi;
139
+ ldst->addrlo_reg = addr;
140
141
/* We are expecting alignment to max out at 7 */
142
tcg_debug_assert(a_mask <= 0xff);
143
/* tst addr, #mask */
144
- tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addrlo, a_mask);
145
+ tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addr, a_mask);
146
}
147
148
return ldst;
149
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg datalo,
150
}
151
152
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
153
- TCGReg addrlo, TCGReg addrhi,
154
- MemOpIdx oi, TCGType data_type)
155
+ TCGReg addr, MemOpIdx oi, TCGType data_type)
156
{
157
MemOp opc = get_memop(oi);
158
TCGLabelQemuLdst *ldst;
159
HostAddress h;
160
161
- ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, true);
162
+ ldst = prepare_host_addr(s, &h, addr, oi, true);
163
if (ldst) {
164
ldst->type = data_type;
165
ldst->datalo_reg = datalo;
166
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg datalo,
167
}
168
169
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
170
- TCGReg addrlo, TCGReg addrhi,
171
- MemOpIdx oi, TCGType data_type)
172
+ TCGReg addr, MemOpIdx oi, TCGType data_type)
173
{
174
MemOp opc = get_memop(oi);
175
TCGLabelQemuLdst *ldst;
176
HostAddress h;
177
178
- ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, false);
179
+ ldst = prepare_host_addr(s, &h, addr, oi, false);
180
if (ldst) {
181
ldst->type = data_type;
182
ldst->datalo_reg = datalo;
183
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
184
break;
185
186
case INDEX_op_qemu_ld_i32:
187
- tcg_out_qemu_ld(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
188
+ tcg_out_qemu_ld(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
189
break;
190
case INDEX_op_qemu_ld_i64:
191
- tcg_out_qemu_ld(s, args[0], args[1], args[2], -1,
192
- args[3], TCG_TYPE_I64);
193
+ tcg_out_qemu_ld(s, args[0], args[1], args[2], args[3], TCG_TYPE_I64);
194
break;
195
196
case INDEX_op_qemu_st_i32:
197
- tcg_out_qemu_st(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
198
+ tcg_out_qemu_st(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
199
break;
200
case INDEX_op_qemu_st_i64:
201
- tcg_out_qemu_st(s, args[0], args[1], args[2], -1,
202
- args[3], TCG_TYPE_I64);
203
+ tcg_out_qemu_st(s, args[0], args[1], args[2], args[3], TCG_TYPE_I64);
204
break;
205
206
case INDEX_op_bswap16_i32:
207
--
208
2.43.0
209
210
diff view generated by jsdifflib
1
Let tb->page_addr[0] contain the address of the first byte of the
1
The guest address will now always fit in one register.
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
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
5
---
10
accel/tcg/cpu-exec.c | 16 ++++++++--------
6
tcg/i386/tcg-target.c.inc | 56 ++++++++++++++-------------------------
11
accel/tcg/cputlb.c | 3 ++-
7
1 file changed, 20 insertions(+), 36 deletions(-)
12
accel/tcg/translate-all.c | 9 +++++----
13
3 files changed, 15 insertions(+), 13 deletions(-)
14
8
15
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
9
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
16
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/tcg/cpu-exec.c
11
--- a/tcg/i386/tcg-target.c.inc
18
+++ b/accel/tcg/cpu-exec.c
12
+++ b/tcg/i386/tcg-target.c.inc
19
@@ -XXX,XX +XXX,XX @@ struct tb_desc {
13
@@ -XXX,XX +XXX,XX @@ static inline int setup_guest_base_seg(void)
20
target_ulong pc;
14
* is required and fill in @h with the host address for the fast path.
21
target_ulong cs_base;
15
*/
22
CPUArchState *env;
16
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
23
- tb_page_addr_t phys_page1;
17
- TCGReg addrlo, TCGReg addrhi,
24
+ tb_page_addr_t page_addr0;
18
- MemOpIdx oi, bool is_ld)
25
uint32_t flags;
19
+ TCGReg addr, MemOpIdx oi, bool is_ld)
26
uint32_t cflags;
20
{
27
uint32_t trace_vcpu_dstate;
21
TCGLabelQemuLdst *ldst = NULL;
28
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
22
MemOp opc = get_memop(oi);
29
const struct tb_desc *desc = d;
23
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
30
24
} else {
31
if (tb->pc == desc->pc &&
25
*h = x86_guest_base;
32
- tb->page_addr[0] == desc->phys_page1 &&
26
}
33
+ tb->page_addr[0] == desc->page_addr0 &&
27
- h->base = addrlo;
34
tb->cs_base == desc->cs_base &&
28
+ h->base = addr;
35
tb->flags == desc->flags &&
29
h->aa = atom_and_align_for_opc(s, opc, MO_ATOM_IFALIGN, s_bits == MO_128);
36
tb->trace_vcpu_dstate == desc->trace_vcpu_dstate &&
30
a_mask = (1 << h->aa.align) - 1;
37
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
31
38
if (tb->page_addr[1] == -1) {
32
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
39
return true;
33
ldst = new_ldst_label(s);
40
} else {
34
ldst->is_ld = is_ld;
41
- tb_page_addr_t phys_page2;
35
ldst->oi = oi;
42
- target_ulong virt_page2;
36
- ldst->addrlo_reg = addrlo;
43
+ tb_page_addr_t phys_page1;
37
- ldst->addrhi_reg = addrhi;
44
+ target_ulong virt_page1;
38
+ ldst->addrlo_reg = addr;
45
39
46
/*
40
if (TCG_TARGET_REG_BITS == 64) {
47
* We know that the first page matched, and an otherwise valid TB
41
ttype = s->addr_type;
48
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
42
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
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
}
43
}
60
}
44
}
61
@@ -XXX,XX +XXX,XX @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
45
62
if (phys_pc == -1) {
46
- tcg_out_mov(s, tlbtype, TCG_REG_L0, addrlo);
63
return NULL;
47
+ tcg_out_mov(s, tlbtype, TCG_REG_L0, addr);
64
}
48
tcg_out_shifti(s, SHIFT_SHR + tlbrexw, TCG_REG_L0,
65
- desc.phys_page1 = phys_pc & TARGET_PAGE_MASK;
49
s->page_bits - CPU_TLB_ENTRY_BITS);
66
+ desc.page_addr0 = phys_pc;
50
67
h = tb_hash_func(phys_pc, pc, flags, cflags, *cpu->trace_dstate);
51
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
68
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
52
* check that we don't cross pages for the complete access.
53
*/
54
if (a_mask >= s_mask) {
55
- tcg_out_mov(s, ttype, TCG_REG_L1, addrlo);
56
+ tcg_out_mov(s, ttype, TCG_REG_L1, addr);
57
} else {
58
tcg_out_modrm_offset(s, OPC_LEA + trexw, TCG_REG_L1,
59
- addrlo, s_mask - a_mask);
60
+ addr, s_mask - a_mask);
61
}
62
tlb_mask = s->page_mask | a_mask;
63
tgen_arithi(s, ARITH_AND + trexw, TCG_REG_L1, tlb_mask, 0);
64
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
65
ldst->label_ptr[0] = s->code_ptr;
66
s->code_ptr += 4;
67
68
- if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I64) {
69
- /* cmp 4(TCG_REG_L0), addrhi */
70
- tcg_out_modrm_offset(s, OPC_CMP_GvEv, addrhi,
71
- TCG_REG_L0, cmp_ofs + 4);
72
-
73
- /* jne slow_path */
74
- tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
75
- ldst->label_ptr[1] = s->code_ptr;
76
- s->code_ptr += 4;
77
- }
78
-
79
/* TLB Hit. */
80
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_L0, TCG_REG_L0,
81
offsetof(CPUTLBEntry, addend));
82
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
83
ldst = new_ldst_label(s);
84
ldst->is_ld = is_ld;
85
ldst->oi = oi;
86
- ldst->addrlo_reg = addrlo;
87
- ldst->addrhi_reg = addrhi;
88
+ ldst->addrlo_reg = addr;
89
90
/* jne slow_path */
91
- jcc = tcg_out_cmp(s, TCG_COND_TSTNE, addrlo, a_mask, true, false);
92
+ jcc = tcg_out_cmp(s, TCG_COND_TSTNE, addr, a_mask, true, false);
93
tcg_out_opc(s, OPC_JCC_long + jcc, 0, 0, 0);
94
ldst->label_ptr[0] = s->code_ptr;
95
s->code_ptr += 4;
96
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
69
}
97
}
70
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
98
71
index XXXXXXX..XXXXXXX 100644
99
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
72
--- a/accel/tcg/cputlb.c
100
- TCGReg addrlo, TCGReg addrhi,
73
+++ b/accel/tcg/cputlb.c
101
- MemOpIdx oi, TCGType data_type)
74
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
102
+ TCGReg addr, MemOpIdx oi, TCGType data_type)
75
can be detected */
76
void tlb_protect_code(ram_addr_t ram_addr)
77
{
103
{
78
- cpu_physical_memory_test_and_clear_dirty(ram_addr, TARGET_PAGE_SIZE,
104
TCGLabelQemuLdst *ldst;
79
+ cpu_physical_memory_test_and_clear_dirty(ram_addr & TARGET_PAGE_MASK,
105
HostAddress h;
80
+ TARGET_PAGE_SIZE,
106
81
DIRTY_MEMORY_CODE);
107
- ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, true);
108
+ ldst = prepare_host_addr(s, &h, addr, oi, true);
109
tcg_out_qemu_ld_direct(s, datalo, datahi, h, data_type, get_memop(oi));
110
111
if (ldst) {
112
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
82
}
113
}
83
114
84
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
115
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
85
index XXXXXXX..XXXXXXX 100644
116
- TCGReg addrlo, TCGReg addrhi,
86
--- a/accel/tcg/translate-all.c
117
- MemOpIdx oi, TCGType data_type)
87
+++ b/accel/tcg/translate-all.c
118
+ TCGReg addr, MemOpIdx oi, TCGType data_type)
88
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
119
{
89
qemu_spin_unlock(&tb->jmp_lock);
120
TCGLabelQemuLdst *ldst;
90
121
HostAddress h;
91
/* remove the TB from the hash list */
122
92
- phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
123
- ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, false);
93
+ phys_pc = tb->page_addr[0];
124
+ ldst = prepare_host_addr(s, &h, addr, oi, false);
94
h = tb_hash_func(phys_pc, tb->pc, tb->flags, orig_cflags,
125
tcg_out_qemu_st_direct(s, datalo, datahi, h, get_memop(oi));
95
tb->trace_vcpu_dstate);
126
96
if (!qht_remove(&tb_ctx.htable, tb, h)) {
127
if (ldst) {
97
@@ -XXX,XX +XXX,XX @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
128
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
98
* we can only insert TBs that are fully initialized.
129
break;
99
*/
130
100
page_lock_pair(&p, phys_pc, &p2, phys_page2, true);
131
case INDEX_op_qemu_ld_i32:
101
- tb_page_add(p, tb, 0, phys_pc & TARGET_PAGE_MASK);
132
- tcg_out_qemu_ld(s, a0, -1, a1, -1, a2, TCG_TYPE_I32);
102
+ tb_page_add(p, tb, 0, phys_pc);
133
+ tcg_out_qemu_ld(s, a0, -1, a1, a2, TCG_TYPE_I32);
103
if (p2) {
134
break;
104
tb_page_add(p2, tb, 1, phys_page2);
135
case INDEX_op_qemu_ld_i64:
105
} else {
136
if (TCG_TARGET_REG_BITS == 64) {
106
@@ -XXX,XX +XXX,XX @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
137
- tcg_out_qemu_ld(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
107
if (n == 0) {
138
+ tcg_out_qemu_ld(s, a0, -1, a1, a2, TCG_TYPE_I64);
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 {
139
} else {
114
tb_start = tb->page_addr[1];
140
- tcg_out_qemu_ld(s, a0, a1, a2, -1, args[3], TCG_TYPE_I64);
115
- tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
141
+ tcg_out_qemu_ld(s, a0, a1, a2, args[3], TCG_TYPE_I64);
116
+ tb_end = tb_start + ((tb->page_addr[0] + tb->size)
117
+ & ~TARGET_PAGE_MASK);
118
}
142
}
119
if (!(tb_end <= start || tb_start >= end)) {
143
break;
120
#ifdef TARGET_HAS_PRECISE_SMC
144
case INDEX_op_qemu_ld_i128:
145
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
146
- tcg_out_qemu_ld(s, a0, a1, a2, -1, args[3], TCG_TYPE_I128);
147
+ tcg_out_qemu_ld(s, a0, a1, a2, args[3], TCG_TYPE_I128);
148
break;
149
150
case INDEX_op_qemu_st_i32:
151
case INDEX_op_qemu_st8_i32:
152
- tcg_out_qemu_st(s, a0, -1, a1, -1, a2, TCG_TYPE_I32);
153
+ tcg_out_qemu_st(s, a0, -1, a1, a2, TCG_TYPE_I32);
154
break;
155
case INDEX_op_qemu_st_i64:
156
if (TCG_TARGET_REG_BITS == 64) {
157
- tcg_out_qemu_st(s, a0, -1, a1, -1, a2, TCG_TYPE_I64);
158
+ tcg_out_qemu_st(s, a0, -1, a1, a2, TCG_TYPE_I64);
159
} else {
160
- tcg_out_qemu_st(s, a0, a1, a2, -1, args[3], TCG_TYPE_I64);
161
+ tcg_out_qemu_st(s, a0, a1, a2, args[3], TCG_TYPE_I64);
162
}
163
break;
164
case INDEX_op_qemu_st_i128:
165
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
166
- tcg_out_qemu_st(s, a0, a1, a2, -1, args[3], TCG_TYPE_I128);
167
+ tcg_out_qemu_st(s, a0, a1, a2, args[3], TCG_TYPE_I128);
168
break;
169
170
OP_32_64(mulu2):
121
--
171
--
122
2.34.1
172
2.43.0
123
173
124
174
diff view generated by jsdifflib
1
Add an interface to return the CPUTLBEntryFull struct
1
The guest address will now always fit in one register.
2
that goes with the lookup. The result is not intended
3
to be valid across multiple lookups, so the user must
4
use the results immediately.
5
2
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
5
---
11
include/exec/exec-all.h | 15 +++++++++++++
6
tcg/mips/tcg-target.c.inc | 62 ++++++++++++++-------------------------
12
include/qemu/typedefs.h | 1 +
7
1 file changed, 22 insertions(+), 40 deletions(-)
13
accel/tcg/cputlb.c | 47 +++++++++++++++++++++++++----------------
14
3 files changed, 45 insertions(+), 18 deletions(-)
15
8
16
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
9
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
17
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
18
--- a/include/exec/exec-all.h
11
--- a/tcg/mips/tcg-target.c.inc
19
+++ b/include/exec/exec-all.h
12
+++ b/tcg/mips/tcg-target.c.inc
20
@@ -XXX,XX +XXX,XX @@ int probe_access_flags(CPUArchState *env, target_ulong addr,
13
@@ -XXX,XX +XXX,XX @@ bool tcg_target_has_memory_bswap(MemOp memop)
21
MMUAccessType access_type, int mmu_idx,
14
* is required and fill in @h with the host address for the fast path.
22
bool nonfault, void **phost, uintptr_t retaddr);
15
*/
23
16
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
24
+#ifndef CONFIG_USER_ONLY
17
- TCGReg addrlo, TCGReg addrhi,
25
+/**
18
- MemOpIdx oi, bool is_ld)
26
+ * probe_access_full:
19
+ TCGReg addr, MemOpIdx oi, bool is_ld)
27
+ * Like probe_access_flags, except also return into @pfull.
28
+ *
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
55
index XXXXXXX..XXXXXXX 100644
56
--- a/accel/tcg/cputlb.c
57
+++ 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
{
20
{
66
uintptr_t index = tlb_index(env, mmu_idx, addr);
21
TCGType addr_type = s->addr_type;
67
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
22
TCGLabelQemuLdst *ldst = NULL;
68
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
23
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
69
mmu_idx, nonfault, retaddr)) {
24
ldst = new_ldst_label(s);
70
/* Non-faulting page table read failed. */
25
ldst->is_ld = is_ld;
71
*phost = NULL;
26
ldst->oi = oi;
72
+ *pfull = NULL;
27
- ldst->addrlo_reg = addrlo;
73
return TLB_INVALID_MASK;
28
- ldst->addrhi_reg = addrhi;
29
+ ldst->addrlo_reg = addr;
30
31
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
32
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_AREG0, mask_off);
33
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
34
35
/* Extract the TLB index from the address into TMP3. */
36
if (TCG_TARGET_REG_BITS == 32 || addr_type == TCG_TYPE_I32) {
37
- tcg_out_opc_sa(s, OPC_SRL, TCG_TMP3, addrlo,
38
+ tcg_out_opc_sa(s, OPC_SRL, TCG_TMP3, addr,
39
s->page_bits - CPU_TLB_ENTRY_BITS);
40
} else {
41
- tcg_out_dsrl(s, TCG_TMP3, addrlo,
42
- s->page_bits - CPU_TLB_ENTRY_BITS);
43
+ tcg_out_dsrl(s, TCG_TMP3, addr, s->page_bits - CPU_TLB_ENTRY_BITS);
44
}
45
tcg_out_opc_reg(s, OPC_AND, TCG_TMP3, TCG_TMP3, TCG_TMP0);
46
47
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
48
tcg_out_opc_imm(s, (TCG_TARGET_REG_BITS == 32
49
|| addr_type == TCG_TYPE_I32
50
? OPC_ADDIU : OPC_DADDIU),
51
- TCG_TMP2, addrlo, s_mask - a_mask);
52
+ TCG_TMP2, addr, s_mask - a_mask);
53
tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, TCG_TMP2);
54
} else {
55
- tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addrlo);
56
+ tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, TCG_TMP1, addr);
57
}
58
59
/* Zero extend a 32-bit guest address for a 64-bit host. */
60
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
61
- tcg_out_ext32u(s, TCG_TMP2, addrlo);
62
- addrlo = TCG_TMP2;
63
+ tcg_out_ext32u(s, TCG_TMP2, addr);
64
+ addr = TCG_TMP2;
65
}
66
67
ldst->label_ptr[0] = s->code_ptr;
68
tcg_out_opc_br(s, OPC_BNE, TCG_TMP1, TCG_TMP0);
69
70
- /* Load and test the high half tlb comparator. */
71
- if (TCG_TARGET_REG_BITS == 32 && addr_type != TCG_TYPE_I32) {
72
- /* delay slot */
73
- tcg_out_ldst(s, OPC_LW, TCG_TMP0, TCG_TMP3, cmp_off + HI_OFF);
74
-
75
- /* Load the tlb addend for the fast path. */
76
- tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
77
-
78
- ldst->label_ptr[1] = s->code_ptr;
79
- tcg_out_opc_br(s, OPC_BNE, addrhi, TCG_TMP0);
80
- }
81
-
82
/* delay slot */
83
base = TCG_TMP3;
84
- tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_TMP3, addrlo);
85
+ tcg_out_opc_reg(s, ALIAS_PADD, base, TCG_TMP3, addr);
86
} else {
87
if (a_mask && (use_mips32r6_instructions || a_bits != s_bits)) {
88
ldst = new_ldst_label(s);
89
90
ldst->is_ld = is_ld;
91
ldst->oi = oi;
92
- ldst->addrlo_reg = addrlo;
93
- ldst->addrhi_reg = addrhi;
94
+ ldst->addrlo_reg = addr;
95
96
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
97
tcg_debug_assert(a_bits < 16);
98
- tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, addrlo, a_mask);
99
+ tcg_out_opc_imm(s, OPC_ANDI, TCG_TMP0, addr, a_mask);
100
101
ldst->label_ptr[0] = s->code_ptr;
102
if (use_mips32r6_instructions) {
103
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
74
}
104
}
75
105
}
76
/* TLB resize via tlb_fill may have moved the entry. */
106
77
+ index = tlb_index(env, mmu_idx, addr);
107
- base = addrlo;
78
entry = tlb_entry(env, mmu_idx, addr);
108
+ base = addr;
79
109
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
80
/*
110
tcg_out_ext32u(s, TCG_REG_A0, base);
81
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
111
base = TCG_REG_A0;
82
}
112
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_unalign(TCGContext *s, TCGReg lo, TCGReg hi,
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,
91
return flags;
92
}
113
}
93
114
94
-int probe_access_flags(CPUArchState *env, target_ulong addr,
115
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
95
- MMUAccessType access_type, int mmu_idx,
116
- TCGReg addrlo, TCGReg addrhi,
96
- bool nonfault, void **phost, uintptr_t retaddr)
117
- MemOpIdx oi, TCGType data_type)
97
+int probe_access_full(CPUArchState *env, target_ulong addr,
118
+ TCGReg addr, MemOpIdx oi, TCGType data_type)
98
+ MMUAccessType access_type, int mmu_idx,
99
+ bool nonfault, void **phost, CPUTLBEntryFull **pfull,
100
+ uintptr_t retaddr)
101
{
119
{
102
- int flags;
120
MemOp opc = get_memop(oi);
103
-
121
TCGLabelQemuLdst *ldst;
104
- flags = probe_access_internal(env, addr, 0, access_type, mmu_idx,
122
HostAddress h;
105
- nonfault, phost, retaddr);
123
106
+ int flags = probe_access_internal(env, addr, 0, access_type, mmu_idx,
124
- ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, true);
107
+ nonfault, phost, pfull, retaddr);
125
+ ldst = prepare_host_addr(s, &h, addr, oi, true);
108
126
109
/* Handle clean RAM pages. */
127
if (use_mips32r6_instructions || h.aa.align >= (opc & MO_SIZE)) {
110
if (unlikely(flags & TLB_NOTDIRTY)) {
128
tcg_out_qemu_ld_direct(s, datalo, datahi, h.base, opc, data_type);
111
- uintptr_t index = tlb_index(env, mmu_idx, addr);
129
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_unalign(TCGContext *s, TCGReg lo, TCGReg hi,
112
- CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
113
-
114
- notdirty_write(env_cpu(env), addr, 1, full, retaddr);
115
+ notdirty_write(env_cpu(env), addr, 1, *pfull, retaddr);
116
flags &= ~TLB_NOTDIRTY;
117
}
118
119
return flags;
120
}
130
}
121
131
122
+int probe_access_flags(CPUArchState *env, target_ulong addr,
132
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
123
+ MMUAccessType access_type, int mmu_idx,
133
- TCGReg addrlo, TCGReg addrhi,
124
+ bool nonfault, void **phost, uintptr_t retaddr)
134
- MemOpIdx oi, TCGType data_type)
125
+{
135
+ TCGReg addr, MemOpIdx oi, TCGType data_type)
126
+ CPUTLBEntryFull *full;
127
+
128
+ return probe_access_full(env, addr, access_type, mmu_idx,
129
+ nonfault, phost, &full, retaddr);
130
+}
131
+
132
void *probe_access(CPUArchState *env, target_ulong addr, int size,
133
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
134
{
136
{
135
+ CPUTLBEntryFull *full;
137
MemOp opc = get_memop(oi);
136
void *host;
138
TCGLabelQemuLdst *ldst;
137
int flags;
139
HostAddress h;
138
140
139
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
141
- ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, false);
140
142
+ ldst = prepare_host_addr(s, &h, addr, oi, false);
141
flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
143
142
- false, &host, retaddr);
144
if (use_mips32r6_instructions || h.aa.align >= (opc & MO_SIZE)) {
143
+ false, &host, &full, retaddr);
145
tcg_out_qemu_st_direct(s, datalo, datahi, h.base, opc);
144
146
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
145
/* Per the interface, size == 0 merely faults the access. */
147
break;
146
if (size == 0) {
148
147
@@ -XXX,XX +XXX,XX @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
149
case INDEX_op_qemu_ld_i32:
148
}
150
- tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I32);
149
151
+ tcg_out_qemu_ld(s, a0, 0, a1, a2, TCG_TYPE_I32);
150
if (unlikely(flags & (TLB_NOTDIRTY | TLB_WATCHPOINT))) {
152
break;
151
- uintptr_t index = tlb_index(env, mmu_idx, addr);
153
case INDEX_op_qemu_ld_i64:
152
- CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
154
if (TCG_TARGET_REG_BITS == 64) {
153
-
155
- tcg_out_qemu_ld(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
154
/* Handle watchpoints. */
156
+ tcg_out_qemu_ld(s, a0, 0, a1, a2, TCG_TYPE_I64);
155
if (flags & TLB_WATCHPOINT) {
157
} else {
156
int wp_access = (access_type == MMU_DATA_STORE
158
- tcg_out_qemu_ld(s, a0, a1, a2, 0, args[3], TCG_TYPE_I64);
157
@@ -XXX,XX +XXX,XX @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
159
+ tcg_out_qemu_ld(s, a0, a1, a2, args[3], TCG_TYPE_I64);
158
void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
160
}
159
MMUAccessType access_type, int mmu_idx)
161
break;
160
{
162
161
+ CPUTLBEntryFull *full;
163
case INDEX_op_qemu_st_i32:
162
void *host;
164
- tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I32);
163
int flags;
165
+ tcg_out_qemu_st(s, a0, 0, a1, a2, TCG_TYPE_I32);
164
166
break;
165
flags = probe_access_internal(env, addr, 0, access_type,
167
case INDEX_op_qemu_st_i64:
166
- mmu_idx, true, &host, 0);
168
if (TCG_TARGET_REG_BITS == 64) {
167
+ mmu_idx, true, &host, &full, 0);
169
- tcg_out_qemu_st(s, a0, 0, a1, 0, a2, TCG_TYPE_I64);
168
170
+ tcg_out_qemu_st(s, a0, 0, a1, a2, TCG_TYPE_I64);
169
/* No combination of flags are expected by the caller. */
171
} else {
170
return flags ? NULL : host;
172
- tcg_out_qemu_st(s, a0, a1, a2, 0, args[3], TCG_TYPE_I64);
171
@@ -XXX,XX +XXX,XX @@ void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
173
+ tcg_out_qemu_st(s, a0, a1, a2, args[3], TCG_TYPE_I64);
172
tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
174
}
173
void **hostp)
175
break;
174
{
176
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
--
177
--
185
2.34.1
178
2.43.0
186
179
187
180
diff view generated by jsdifflib
1
From: Leandro Lupori <leandro.lupori@eldorado.org.br>
1
The guest address will now always fit in one register.
2
2
3
PowerPC64 processors handle direct branches better than indirect
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@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/ppc/tcg-target.c.inc | 75 ++++++++++++----------------------------
18
1 file changed, 88 insertions(+), 31 deletions(-)
7
1 file changed, 23 insertions(+), 52 deletions(-)
19
8
20
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
9
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
21
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/ppc/tcg-target.c.inc
11
--- a/tcg/ppc/tcg-target.c.inc
23
+++ b/tcg/ppc/tcg-target.c.inc
12
+++ b/tcg/ppc/tcg-target.c.inc
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
13
@@ -XXX,XX +XXX,XX @@ bool tcg_target_has_memory_bswap(MemOp memop)
25
tcg_out32(s, insn);
14
* is required and fill in @h with the host address for the fast path.
15
*/
16
static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
17
- TCGReg addrlo, TCGReg addrhi,
18
- MemOpIdx oi, bool is_ld)
19
+ TCGReg addr, MemOpIdx oi, bool is_ld)
20
{
21
TCGType addr_type = s->addr_type;
22
TCGLabelQemuLdst *ldst = NULL;
23
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
24
ldst = new_ldst_label(s);
25
ldst->is_ld = is_ld;
26
ldst->oi = oi;
27
- ldst->addrlo_reg = addrlo;
28
- ldst->addrhi_reg = addrhi;
29
+ ldst->addrlo_reg = addr;
30
31
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
32
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, mask_off);
33
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
34
35
/* Extract the page index, shifted into place for tlb index. */
36
if (TCG_TARGET_REG_BITS == 32) {
37
- tcg_out_shri32(s, TCG_REG_R0, addrlo,
38
+ tcg_out_shri32(s, TCG_REG_R0, addr,
39
s->page_bits - CPU_TLB_ENTRY_BITS);
40
} else {
41
- tcg_out_shri64(s, TCG_REG_R0, addrlo,
42
+ tcg_out_shri64(s, TCG_REG_R0, addr,
43
s->page_bits - CPU_TLB_ENTRY_BITS);
44
}
45
tcg_out32(s, AND | SAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_R0));
46
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
47
if (a_bits < s_bits) {
48
a_bits = s_bits;
49
}
50
- tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0,
51
+ tcg_out_rlw(s, RLWINM, TCG_REG_R0, addr, 0,
52
(32 - a_bits) & 31, 31 - s->page_bits);
53
} else {
54
- TCGReg t = addrlo;
55
+ TCGReg t = addr;
56
57
/*
58
* If the access is unaligned, we need to make sure we fail if we
59
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
60
}
61
}
62
63
- if (TCG_TARGET_REG_BITS == 32 && addr_type != TCG_TYPE_I32) {
64
- /* Low part comparison into cr7. */
65
- tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2,
66
- 0, 7, TCG_TYPE_I32);
67
-
68
- /* Load the high part TLB comparator into TMP2. */
69
- tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP2, TCG_REG_TMP1,
70
- cmp_off + 4 * !HOST_BIG_ENDIAN);
71
-
72
- /* Load addend, deferred for this case. */
73
- tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_REG_TMP1,
74
- offsetof(CPUTLBEntry, addend));
75
-
76
- /* High part comparison into cr6. */
77
- tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_TMP2,
78
- 0, 6, TCG_TYPE_I32);
79
-
80
- /* Combine comparisons into cr0. */
81
- tcg_out32(s, CRAND | BT(0, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
82
- } else {
83
- /* Full comparison into cr0. */
84
- tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2,
85
- 0, 0, addr_type);
86
- }
87
+ /* Full comparison into cr0. */
88
+ tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2, 0, 0, addr_type);
89
90
/* Load a pointer into the current opcode w/conditional branch-link. */
91
ldst->label_ptr[0] = s->code_ptr;
92
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
93
ldst = new_ldst_label(s);
94
ldst->is_ld = is_ld;
95
ldst->oi = oi;
96
- ldst->addrlo_reg = addrlo;
97
- ldst->addrhi_reg = addrhi;
98
+ ldst->addrlo_reg = addr;
99
100
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
101
tcg_debug_assert(a_bits < 16);
102
- tcg_out32(s, ANDI | SAI(addrlo, TCG_REG_R0, (1 << a_bits) - 1));
103
+ tcg_out32(s, ANDI | SAI(addr, TCG_REG_R0, (1 << a_bits) - 1));
104
105
ldst->label_ptr[0] = s->code_ptr;
106
tcg_out32(s, BC | BI(0, CR_EQ) | BO_COND_FALSE | LK);
107
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
108
109
if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
110
/* Zero-extend the guest address for use in the host address. */
111
- tcg_out_ext32u(s, TCG_REG_TMP2, addrlo);
112
+ tcg_out_ext32u(s, TCG_REG_TMP2, addr);
113
h->index = TCG_REG_TMP2;
114
} else {
115
- h->index = addrlo;
116
+ h->index = addr;
117
}
118
119
return ldst;
26
}
120
}
27
121
28
+static inline uint64_t make_pair(tcg_insn_unit i1, tcg_insn_unit i2)
122
static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
29
+{
123
- TCGReg addrlo, TCGReg addrhi,
30
+ if (HOST_BIG_ENDIAN) {
124
- MemOpIdx oi, TCGType data_type)
31
+ return (uint64_t)i1 << 32 | i2;
125
+ TCGReg addr, MemOpIdx oi, TCGType data_type)
32
+ }
33
+ return (uint64_t)i2 << 32 | i1;
34
+}
35
+
36
+static inline void ppc64_replace2(uintptr_t rx, uintptr_t rw,
37
+ tcg_insn_unit i0, tcg_insn_unit i1)
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
{
126
{
70
- if (TCG_TARGET_REG_BITS == 64) {
127
MemOp opc = get_memop(oi);
71
- tcg_insn_unit i1, i2;
128
TCGLabelQemuLdst *ldst;
72
- intptr_t tb_diff = addr - tc_ptr;
129
HostAddress h;
73
- intptr_t br_diff = addr - (jmp_rx + 4);
130
74
- uint64_t pair;
131
- ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, true);
75
+ tcg_insn_unit i0, i1, i2, i3;
132
+ ldst = prepare_host_addr(s, &h, addr, oi, true);
76
+ intptr_t tb_diff = addr - tc_ptr;
133
77
+ intptr_t br_diff = addr - (jmp_rx + 4);
134
if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
78
+ intptr_t lo, hi;
135
if (opc & MO_BSWAP) {
79
136
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg datalo, TCGReg datahi,
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
+ }
137
+
138
+ /*
139
+ * For 26-bit displacements, we can use a direct branch.
140
+ * Otherwise we still need the indirect branch, which we
141
+ * must restore after a potential direct branch write.
142
+ */
143
+ br_diff -= 4;
144
+ if (in_range_b(br_diff)) {
145
+ i2 = B | (br_diff & 0x3fffffc);
146
+ i3 = NOP;
147
+ } else {
148
+ i2 = MTSPR | RS(TCG_REG_TB) | CTR;
149
+ i3 = BCCTR | BO_ALWAYS;
150
+ }
151
+ ppc64_replace4(jmp_rx, jmp_rw, i0, i1, i2, i3);
152
}
137
}
153
138
154
static void tcg_out_call_int(TCGContext *s, int lk,
139
static void tcg_out_qemu_st(TCGContext *s, TCGReg datalo, TCGReg datahi,
155
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
140
- TCGReg addrlo, TCGReg addrhi,
156
if (s->tb_jmp_insn_offset) {
141
- MemOpIdx oi, TCGType data_type)
157
/* Direct jump. */
142
+ TCGReg addr, MemOpIdx oi, TCGType data_type)
158
if (TCG_TARGET_REG_BITS == 64) {
143
{
159
- /* Ensure the next insns are 8-byte aligned. */
144
MemOp opc = get_memop(oi);
160
- if ((uintptr_t)s->code_ptr & 7) {
145
TCGLabelQemuLdst *ldst;
161
+ /* Ensure the next insns are 8 or 16-byte aligned. */
146
HostAddress h;
162
+ while ((uintptr_t)s->code_ptr & (have_isa_2_07 ? 15 : 7)) {
147
163
tcg_out32(s, NOP);
148
- ldst = prepare_host_addr(s, &h, addrlo, addrhi, oi, false);
164
}
149
+ ldst = prepare_host_addr(s, &h, addr, oi, false);
165
s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
150
151
if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
152
if (opc & MO_BSWAP) {
153
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ldst_i128(TCGContext *s, TCGReg datalo, TCGReg datahi,
154
uint32_t insn;
155
TCGReg index;
156
157
- ldst = prepare_host_addr(s, &h, addr_reg, -1, oi, is_ld);
158
+ ldst = prepare_host_addr(s, &h, addr_reg, oi, is_ld);
159
160
/* Compose the final address, as LQ/STQ have no indexing. */
161
index = h.index;
162
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
163
break;
164
165
case INDEX_op_qemu_ld_i32:
166
- tcg_out_qemu_ld(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
167
+ tcg_out_qemu_ld(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
168
break;
169
case INDEX_op_qemu_ld_i64:
170
if (TCG_TARGET_REG_BITS == 64) {
171
- tcg_out_qemu_ld(s, args[0], -1, args[1], -1,
172
- args[2], TCG_TYPE_I64);
173
+ tcg_out_qemu_ld(s, args[0], -1, args[1], args[2], TCG_TYPE_I64);
174
} else {
175
- tcg_out_qemu_ld(s, args[0], args[1], args[2], -1,
176
+ tcg_out_qemu_ld(s, args[0], args[1], args[2],
177
args[3], TCG_TYPE_I64);
178
}
179
break;
180
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
181
break;
182
183
case INDEX_op_qemu_st_i32:
184
- tcg_out_qemu_st(s, args[0], -1, args[1], -1, args[2], TCG_TYPE_I32);
185
+ tcg_out_qemu_st(s, args[0], -1, args[1], args[2], TCG_TYPE_I32);
186
break;
187
case INDEX_op_qemu_st_i64:
188
if (TCG_TARGET_REG_BITS == 64) {
189
- tcg_out_qemu_st(s, args[0], -1, args[1], -1,
190
- args[2], TCG_TYPE_I64);
191
+ tcg_out_qemu_st(s, args[0], -1, args[1], args[2], TCG_TYPE_I64);
192
} else {
193
- tcg_out_qemu_st(s, args[0], args[1], args[2], -1,
194
+ tcg_out_qemu_st(s, args[0], args[1], args[2],
195
args[3], TCG_TYPE_I64);
196
}
197
break;
166
--
198
--
167
2.34.1
199
2.43.0
200
201
diff view generated by jsdifflib
New patch
1
1
There is now always only one guest address register.
2
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/tcg.c | 18 +++++++++---------
7
tcg/aarch64/tcg-target.c.inc | 4 ++--
8
tcg/arm/tcg-target.c.inc | 4 ++--
9
tcg/i386/tcg-target.c.inc | 4 ++--
10
tcg/loongarch64/tcg-target.c.inc | 4 ++--
11
tcg/mips/tcg-target.c.inc | 4 ++--
12
tcg/ppc/tcg-target.c.inc | 4 ++--
13
tcg/riscv/tcg-target.c.inc | 4 ++--
14
tcg/s390x/tcg-target.c.inc | 4 ++--
15
tcg/sparc64/tcg-target.c.inc | 4 ++--
16
10 files changed, 27 insertions(+), 27 deletions(-)
17
18
diff --git a/tcg/tcg.c b/tcg/tcg.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/tcg/tcg.c
21
+++ b/tcg/tcg.c
22
@@ -XXX,XX +XXX,XX @@ struct TCGLabelQemuLdst {
23
bool is_ld; /* qemu_ld: true, qemu_st: false */
24
MemOpIdx oi;
25
TCGType type; /* result type of a load */
26
- TCGReg addrlo_reg; /* reg index for low word of guest virtual addr */
27
- TCGReg addrhi_reg; /* reg index for high word of guest virtual addr */
28
+ TCGReg addr_reg; /* reg index for guest virtual addr */
29
TCGReg datalo_reg; /* reg index for low word to be loaded or stored */
30
TCGReg datahi_reg; /* reg index for high word to be loaded or stored */
31
const tcg_insn_unit *raddr; /* addr of the next IR of qemu_ld/st IR */
32
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ld_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
33
*/
34
tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
35
TCG_TYPE_I32, TCG_TYPE_I32,
36
- ldst->addrlo_reg, -1);
37
+ ldst->addr_reg, -1);
38
tcg_out_helper_load_slots(s, 1, mov, parm);
39
40
tcg_out_helper_load_imm(s, loc[!HOST_BIG_ENDIAN].arg_slot,
41
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ld_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
42
next_arg += 2;
43
} else {
44
nmov = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type,
45
- ldst->addrlo_reg, ldst->addrhi_reg);
46
+ ldst->addr_reg, -1);
47
tcg_out_helper_load_slots(s, nmov, mov, parm);
48
next_arg += nmov;
49
}
50
@@ -XXX,XX +XXX,XX @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
51
52
/* Handle addr argument. */
53
loc = &info->in[next_arg];
54
- if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) {
55
+ tcg_debug_assert(s->addr_type <= TCG_TYPE_REG);
56
+ if (TCG_TARGET_REG_BITS == 32) {
57
/*
58
- * 32-bit host with 32-bit guest: zero-extend the guest address
59
+ * 32-bit host (and thus 32-bit guest): zero-extend the guest address
60
* to 64-bits for the helper by storing the low part. Later,
61
* after we have processed the register inputs, we will load a
62
* zero for the high part.
63
*/
64
tcg_out_helper_add_mov(mov, loc + HOST_BIG_ENDIAN,
65
TCG_TYPE_I32, TCG_TYPE_I32,
66
- ldst->addrlo_reg, -1);
67
+ ldst->addr_reg, -1);
68
next_arg += 2;
69
nmov += 1;
70
} else {
71
n = tcg_out_helper_add_mov(mov, loc, TCG_TYPE_I64, s->addr_type,
72
- ldst->addrlo_reg, ldst->addrhi_reg);
73
+ ldst->addr_reg, -1);
74
next_arg += n;
75
nmov += n;
76
}
77
@@ -XXX,XX +XXX,XX @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
78
g_assert_not_reached();
79
}
80
81
- if (TCG_TARGET_REG_BITS == 32 && s->addr_type == TCG_TYPE_I32) {
82
+ if (TCG_TARGET_REG_BITS == 32) {
83
/* Zero extend the address by loading a zero for the high part. */
84
loc = &info->in[1 + !HOST_BIG_ENDIAN];
85
tcg_out_helper_load_imm(s, loc->arg_slot, TCG_TYPE_I32, 0, parm);
86
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
87
index XXXXXXX..XXXXXXX 100644
88
--- a/tcg/aarch64/tcg-target.c.inc
89
+++ b/tcg/aarch64/tcg-target.c.inc
90
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
91
ldst = new_ldst_label(s);
92
ldst->is_ld = is_ld;
93
ldst->oi = oi;
94
- ldst->addrlo_reg = addr_reg;
95
+ ldst->addr_reg = addr_reg;
96
97
mask_type = (s->page_bits + s->tlb_dyn_max_bits > 32
98
? TCG_TYPE_I64 : TCG_TYPE_I32);
99
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
100
101
ldst->is_ld = is_ld;
102
ldst->oi = oi;
103
- ldst->addrlo_reg = addr_reg;
104
+ ldst->addr_reg = addr_reg;
105
106
/* tst addr, #mask */
107
tcg_out_logicali(s, I3404_ANDSI, 0, TCG_REG_XZR, addr_reg, a_mask);
108
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
109
index XXXXXXX..XXXXXXX 100644
110
--- a/tcg/arm/tcg-target.c.inc
111
+++ b/tcg/arm/tcg-target.c.inc
112
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
113
ldst = new_ldst_label(s);
114
ldst->is_ld = is_ld;
115
ldst->oi = oi;
116
- ldst->addrlo_reg = addr;
117
+ ldst->addr_reg = addr;
118
119
/* Load cpu->neg.tlb.f[mmu_idx].{mask,table} into {r0,r1}. */
120
QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, mask) != 0);
121
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
122
ldst = new_ldst_label(s);
123
ldst->is_ld = is_ld;
124
ldst->oi = oi;
125
- ldst->addrlo_reg = addr;
126
+ ldst->addr_reg = addr;
127
128
/* We are expecting alignment to max out at 7 */
129
tcg_debug_assert(a_mask <= 0xff);
130
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
131
index XXXXXXX..XXXXXXX 100644
132
--- a/tcg/i386/tcg-target.c.inc
133
+++ b/tcg/i386/tcg-target.c.inc
134
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
135
ldst = new_ldst_label(s);
136
ldst->is_ld = is_ld;
137
ldst->oi = oi;
138
- ldst->addrlo_reg = addr;
139
+ ldst->addr_reg = addr;
140
141
if (TCG_TARGET_REG_BITS == 64) {
142
ttype = s->addr_type;
143
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
144
ldst = new_ldst_label(s);
145
ldst->is_ld = is_ld;
146
ldst->oi = oi;
147
- ldst->addrlo_reg = addr;
148
+ ldst->addr_reg = addr;
149
150
/* jne slow_path */
151
jcc = tcg_out_cmp(s, TCG_COND_TSTNE, addr, a_mask, true, false);
152
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
153
index XXXXXXX..XXXXXXX 100644
154
--- a/tcg/loongarch64/tcg-target.c.inc
155
+++ b/tcg/loongarch64/tcg-target.c.inc
156
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
157
ldst = new_ldst_label(s);
158
ldst->is_ld = is_ld;
159
ldst->oi = oi;
160
- ldst->addrlo_reg = addr_reg;
161
+ ldst->addr_reg = addr_reg;
162
163
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs);
164
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs);
165
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
166
167
ldst->is_ld = is_ld;
168
ldst->oi = oi;
169
- ldst->addrlo_reg = addr_reg;
170
+ ldst->addr_reg = addr_reg;
171
172
/*
173
* Without micro-architecture details, we don't know which of
174
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
175
index XXXXXXX..XXXXXXX 100644
176
--- a/tcg/mips/tcg-target.c.inc
177
+++ b/tcg/mips/tcg-target.c.inc
178
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
179
ldst = new_ldst_label(s);
180
ldst->is_ld = is_ld;
181
ldst->oi = oi;
182
- ldst->addrlo_reg = addr;
183
+ ldst->addr_reg = addr;
184
185
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
186
tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_AREG0, mask_off);
187
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
188
189
ldst->is_ld = is_ld;
190
ldst->oi = oi;
191
- ldst->addrlo_reg = addr;
192
+ ldst->addr_reg = addr;
193
194
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
195
tcg_debug_assert(a_bits < 16);
196
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
197
index XXXXXXX..XXXXXXX 100644
198
--- a/tcg/ppc/tcg-target.c.inc
199
+++ b/tcg/ppc/tcg-target.c.inc
200
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
201
ldst = new_ldst_label(s);
202
ldst->is_ld = is_ld;
203
ldst->oi = oi;
204
- ldst->addrlo_reg = addr;
205
+ ldst->addr_reg = addr;
206
207
/* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
208
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, mask_off);
209
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
210
ldst = new_ldst_label(s);
211
ldst->is_ld = is_ld;
212
ldst->oi = oi;
213
- ldst->addrlo_reg = addr;
214
+ ldst->addr_reg = addr;
215
216
/* We are expecting a_bits to max out at 7, much lower than ANDI. */
217
tcg_debug_assert(a_bits < 16);
218
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
219
index XXXXXXX..XXXXXXX 100644
220
--- a/tcg/riscv/tcg-target.c.inc
221
+++ b/tcg/riscv/tcg-target.c.inc
222
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
223
ldst = new_ldst_label(s);
224
ldst->is_ld = is_ld;
225
ldst->oi = oi;
226
- ldst->addrlo_reg = addr_reg;
227
+ ldst->addr_reg = addr_reg;
228
229
init_setting_vtype(s);
230
231
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
232
ldst = new_ldst_label(s);
233
ldst->is_ld = is_ld;
234
ldst->oi = oi;
235
- ldst->addrlo_reg = addr_reg;
236
+ ldst->addr_reg = addr_reg;
237
238
init_setting_vtype(s);
239
240
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
241
index XXXXXXX..XXXXXXX 100644
242
--- a/tcg/s390x/tcg-target.c.inc
243
+++ b/tcg/s390x/tcg-target.c.inc
244
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
245
ldst = new_ldst_label(s);
246
ldst->is_ld = is_ld;
247
ldst->oi = oi;
248
- ldst->addrlo_reg = addr_reg;
249
+ ldst->addr_reg = addr_reg;
250
251
tcg_out_sh64(s, RSY_SRLG, TCG_TMP0, addr_reg, TCG_REG_NONE,
252
s->page_bits - CPU_TLB_ENTRY_BITS);
253
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
254
ldst = new_ldst_label(s);
255
ldst->is_ld = is_ld;
256
ldst->oi = oi;
257
- ldst->addrlo_reg = addr_reg;
258
+ ldst->addr_reg = addr_reg;
259
260
tcg_debug_assert(a_mask <= 0xffff);
261
tcg_out_insn(s, RI, TMLL, addr_reg, a_mask);
262
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
263
index XXXXXXX..XXXXXXX 100644
264
--- a/tcg/sparc64/tcg-target.c.inc
265
+++ b/tcg/sparc64/tcg-target.c.inc
266
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
267
ldst = new_ldst_label(s);
268
ldst->is_ld = is_ld;
269
ldst->oi = oi;
270
- ldst->addrlo_reg = addr_reg;
271
+ ldst->addr_reg = addr_reg;
272
ldst->label_ptr[0] = s->code_ptr;
273
274
/* bne,pn %[xi]cc, label0 */
275
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
276
ldst = new_ldst_label(s);
277
ldst->is_ld = is_ld;
278
ldst->oi = oi;
279
- ldst->addrlo_reg = addr_reg;
280
+ ldst->addr_reg = addr_reg;
281
ldst->label_ptr[0] = s->code_ptr;
282
283
/* bne,pn %icc, label0 */
284
--
285
2.43.0
286
287
diff view generated by jsdifflib
1
Bool is more appropriate type for the alloc parameter.
1
The declaration uses uint64_t for addr.
2
2
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
Fixes: 595cd9ce2ec ("plugins: add plugin API to read guest memory")
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
6
---
7
accel/tcg/translate-all.c | 14 +++++++-------
7
plugins/api.c | 2 +-
8
1 file changed, 7 insertions(+), 7 deletions(-)
8
1 file changed, 1 insertion(+), 1 deletion(-)
9
9
10
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
10
diff --git a/plugins/api.c b/plugins/api.c
11
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
12
--- a/accel/tcg/translate-all.c
12
--- a/plugins/api.c
13
+++ b/accel/tcg/translate-all.c
13
+++ b/plugins/api.c
14
@@ -XXX,XX +XXX,XX @@ void page_init(void)
14
@@ -XXX,XX +XXX,XX @@ GArray *qemu_plugin_get_registers(void)
15
#endif
15
return create_register_handles(regs);
16
}
16
}
17
17
18
-static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
18
-bool qemu_plugin_read_memory_vaddr(vaddr addr, GByteArray *data, size_t len)
19
+static PageDesc *page_find_alloc(tb_page_addr_t index, bool alloc)
19
+bool qemu_plugin_read_memory_vaddr(uint64_t addr, GByteArray *data, size_t len)
20
{
20
{
21
PageDesc *pd;
21
g_assert(current_cpu);
22
void **lp;
22
23
@@ -XXX,XX +XXX,XX @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
24
25
static inline PageDesc *page_find(tb_page_addr_t index)
26
{
27
- return page_find_alloc(index, 0);
28
+ return page_find_alloc(index, false);
29
}
30
31
static void page_lock_pair(PageDesc **ret_p1, tb_page_addr_t phys1,
32
- PageDesc **ret_p2, tb_page_addr_t phys2, int alloc);
33
+ PageDesc **ret_p2, tb_page_addr_t phys2, bool alloc);
34
35
/* In user-mode page locks aren't used; mmap_lock is enough */
36
#ifdef CONFIG_USER_ONLY
37
@@ -XXX,XX +XXX,XX @@ static inline void page_unlock(PageDesc *pd)
38
/* lock the page(s) of a TB in the correct acquisition order */
39
static inline void page_lock_tb(const TranslationBlock *tb)
40
{
41
- page_lock_pair(NULL, tb->page_addr[0], NULL, tb->page_addr[1], 0);
42
+ page_lock_pair(NULL, tb->page_addr[0], NULL, tb->page_addr[1], false);
43
}
44
45
static inline void page_unlock_tb(const TranslationBlock *tb)
46
@@ -XXX,XX +XXX,XX @@ void page_collection_unlock(struct page_collection *set)
47
#endif /* !CONFIG_USER_ONLY */
48
49
static void page_lock_pair(PageDesc **ret_p1, tb_page_addr_t phys1,
50
- PageDesc **ret_p2, tb_page_addr_t phys2, int alloc)
51
+ PageDesc **ret_p2, tb_page_addr_t phys2, bool alloc)
52
{
53
PageDesc *p1, *p2;
54
tb_page_addr_t page1;
55
@@ -XXX,XX +XXX,XX @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
56
* Note that inserting into the hash table first isn't an option, since
57
* we can only insert TBs that are fully initialized.
58
*/
59
- page_lock_pair(&p, phys_pc, &p2, phys_page2, 1);
60
+ page_lock_pair(&p, phys_pc, &p2, phys_page2, true);
61
tb_page_add(p, tb, 0, phys_pc & TARGET_PAGE_MASK);
62
if (p2) {
63
tb_page_add(p2, tb, 1, phys_page2);
64
@@ -XXX,XX +XXX,XX @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
65
for (addr = start, len = end - start;
66
len != 0;
67
len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
68
- PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
69
+ PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, true);
70
71
/* If the write protection bit is set, then we invalidate
72
the code inside. */
73
--
23
--
74
2.34.1
24
2.43.0
75
25
76
26
diff view generated by jsdifflib
1
When PAGE_WRITE_INV is set when calling tlb_set_page,
1
The declarations use vaddr for size.
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.
8
There doesn't seem to be a reason to change the code though.
9
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: David Hildenbrand <david@redhat.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
---
4
---
15
accel/tcg/cputlb.c | 10 +++++++++-
5
accel/tcg/cputlb.c | 4 ++--
16
target/s390x/tcg/mem_helper.c | 4 ----
6
1 file changed, 2 insertions(+), 2 deletions(-)
17
2 files changed, 9 insertions(+), 5 deletions(-)
18
7
19
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
8
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
20
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
21
--- a/accel/tcg/cputlb.c
10
--- a/accel/tcg/cputlb.c
22
+++ b/accel/tcg/cputlb.c
11
+++ b/accel/tcg/cputlb.c
23
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
12
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
24
}
13
25
tlb_addr = tlb_read_ofs(entry, elt_ofs);
14
void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr,
26
15
hwaddr paddr, MemTxAttrs attrs, int prot,
27
+ flags = TLB_FLAGS_MASK;
16
- int mmu_idx, uint64_t size)
28
page_addr = addr & TARGET_PAGE_MASK;
17
+ int mmu_idx, vaddr size)
29
if (!tlb_hit_page(tlb_addr, page_addr)) {
18
{
30
if (!victim_tlb_hit(env, mmu_idx, index, elt_ofs, page_addr)) {
19
CPUTLBEntryFull full = {
31
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
20
.phys_addr = paddr,
32
21
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr,
33
/* TLB resize via tlb_fill may have moved the entry. */
22
34
entry = tlb_entry(env, mmu_idx, addr);
23
void tlb_set_page(CPUState *cpu, vaddr addr,
35
+
24
hwaddr paddr, int prot,
36
+ /*
25
- int mmu_idx, uint64_t size)
37
+ * With PAGE_WRITE_INV, we set TLB_INVALID_MASK immediately,
26
+ int mmu_idx, vaddr size)
38
+ * to force the next access through tlb_fill. We've just
27
{
39
+ * called tlb_fill, so we know that this entry *is* valid.
28
tlb_set_page_with_attrs(cpu, addr, paddr, MEMTXATTRS_UNSPECIFIED,
40
+ */
29
prot, mmu_idx, size);
41
+ flags &= ~TLB_INVALID_MASK;
42
}
43
tlb_addr = tlb_read_ofs(entry, elt_ofs);
44
}
45
- flags = tlb_addr & TLB_FLAGS_MASK;
46
+ flags &= tlb_addr;
47
48
/* Fold all "mmio-like" bits into TLB_MMIO. This is not RAM. */
49
if (unlikely(flags & ~(TLB_WATCHPOINT | TLB_NOTDIRTY))) {
50
diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/s390x/tcg/mem_helper.c
53
+++ b/target/s390x/tcg/mem_helper.c
54
@@ -XXX,XX +XXX,XX @@ static int s390_probe_access(CPUArchState *env, target_ulong addr, int size,
55
#else
56
int flags;
57
58
- /*
59
- * For !CONFIG_USER_ONLY, we cannot rely on TLB_INVALID_MASK or haddr==NULL
60
- * to detect if there was an exception during tlb_fill().
61
- */
62
env->tlb_fill_exc = 0;
63
flags = probe_access_flags(env, addr, access_type, mmu_idx, nonfault, phost,
64
ra);
65
--
30
--
66
2.34.1
31
2.43.0
67
68
diff view generated by jsdifflib
New patch
1
DisasContextBase.pc_next has type vaddr; use the correct log format.
1
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
target/loongarch/tcg/translate.c | 2 +-
6
target/loongarch/tcg/insn_trans/trans_atomic.c.inc | 2 +-
7
2 files changed, 2 insertions(+), 2 deletions(-)
8
9
diff --git a/target/loongarch/tcg/translate.c b/target/loongarch/tcg/translate.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/target/loongarch/tcg/translate.c
12
+++ b/target/loongarch/tcg/translate.c
13
@@ -XXX,XX +XXX,XX @@ static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
14
15
if (!decode(ctx, ctx->opcode)) {
16
qemu_log_mask(LOG_UNIMP, "Error: unknown opcode. "
17
- TARGET_FMT_lx ": 0x%x\n",
18
+ "0x%" VADDR_PRIx ": 0x%x\n",
19
ctx->base.pc_next, ctx->opcode);
20
generate_exception(ctx, EXCCODE_INE);
21
}
22
diff --git a/target/loongarch/tcg/insn_trans/trans_atomic.c.inc b/target/loongarch/tcg/insn_trans/trans_atomic.c.inc
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/loongarch/tcg/insn_trans/trans_atomic.c.inc
25
+++ b/target/loongarch/tcg/insn_trans/trans_atomic.c.inc
26
@@ -XXX,XX +XXX,XX @@ static bool gen_am(DisasContext *ctx, arg_rrr *a,
27
if (a->rd != 0 && (a->rj == a->rd || a->rk == a->rd)) {
28
qemu_log_mask(LOG_GUEST_ERROR,
29
"Warning: source register overlaps destination register"
30
- "in atomic insn at pc=0x" TARGET_FMT_lx "\n",
31
+ "in atomic insn at pc=0x%" VADDR_PRIx "\n",
32
ctx->base.pc_next - 4);
33
return false;
34
}
35
--
36
2.43.0
diff view generated by jsdifflib
1
Use the pc coming from db->pc_first rather than the TB.
1
Since we no longer support 64-bit guests on 32-bit hosts,
2
we can use a 32-bit type on a 32-bit host.
2
3
3
Use the cached host_addr rather than re-computing for the
4
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>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
6
---
11
include/exec/plugin-gen.h | 7 ++++---
7
include/exec/vaddr.h | 16 +++++++++-------
12
accel/tcg/plugin-gen.c | 22 +++++++++++-----------
8
1 file changed, 9 insertions(+), 7 deletions(-)
13
accel/tcg/translator.c | 2 +-
14
3 files changed, 16 insertions(+), 15 deletions(-)
15
9
16
diff --git a/include/exec/plugin-gen.h b/include/exec/plugin-gen.h
10
diff --git a/include/exec/vaddr.h b/include/exec/vaddr.h
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/include/exec/plugin-gen.h
12
--- a/include/exec/vaddr.h
19
+++ b/include/exec/plugin-gen.h
13
+++ b/include/exec/vaddr.h
20
@@ -XXX,XX +XXX,XX @@ struct DisasContextBase;
14
@@ -XXX,XX +XXX,XX @@
21
15
/**
22
#ifdef CONFIG_PLUGIN
16
* vaddr:
23
17
* Type wide enough to contain any #target_ulong virtual address.
24
-bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool supress);
18
+ * We do not support 64-bit guest on 32-host and detect at configure time.
25
+bool plugin_gen_tb_start(CPUState *cpu, const struct DisasContextBase *db,
19
+ * Therefore, a host pointer width will always fit a guest pointer.
26
+ bool supress);
20
*/
27
void plugin_gen_tb_end(CPUState *cpu);
21
-typedef uint64_t vaddr;
28
void plugin_gen_insn_start(CPUState *cpu, const struct DisasContextBase *db);
22
-#define VADDR_PRId PRId64
29
void plugin_gen_insn_end(void);
23
-#define VADDR_PRIu PRIu64
30
@@ -XXX,XX +XXX,XX @@ static inline void plugin_insn_append(abi_ptr pc, const void *from, size_t size)
24
-#define VADDR_PRIo PRIo64
31
25
-#define VADDR_PRIx PRIx64
32
#else /* !CONFIG_PLUGIN */
26
-#define VADDR_PRIX PRIX64
33
27
-#define VADDR_MAX UINT64_MAX
34
-static inline
28
+typedef uintptr_t vaddr;
35
-bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool supress)
29
+#define VADDR_PRId PRIdPTR
36
+static inline bool
30
+#define VADDR_PRIu PRIuPTR
37
+plugin_gen_tb_start(CPUState *cpu, const struct DisasContextBase *db, bool sup)
31
+#define VADDR_PRIo PRIoPTR
38
{
32
+#define VADDR_PRIx PRIxPTR
39
return false;
33
+#define VADDR_PRIX PRIXPTR
40
}
34
+#define VADDR_MAX UINTPTR_MAX
41
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
35
42
index XXXXXXX..XXXXXXX 100644
36
#endif
43
--- a/accel/tcg/plugin-gen.c
44
+++ b/accel/tcg/plugin-gen.c
45
@@ -XXX,XX +XXX,XX @@ static void plugin_gen_inject(const struct qemu_plugin_tb *plugin_tb)
46
pr_ops();
47
}
48
49
-bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool mem_only)
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.43.0
106
39
107
40
diff view generated by jsdifflib
1
This structure will shortly contain more than just
1
Since we no longer support 64-bit guests on 32-bit hosts,
2
data for accessing MMIO. Rename the 'addr' member
2
we can use a 32-bit type on a 32-bit host. This shrinks
3
to 'xlat_section' to more clearly indicate its purpose.
3
the size of the structure to 16 bytes on a 32-bit host.
4
4
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
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>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
7
---
10
include/exec/cpu-defs.h | 22 ++++----
8
include/exec/tlb-common.h | 10 +++++-----
11
accel/tcg/cputlb.c | 102 +++++++++++++++++++------------------
9
accel/tcg/cputlb.c | 21 ++++-----------------
12
target/arm/mte_helper.c | 14 ++---
10
tcg/arm/tcg-target.c.inc | 1 -
13
target/arm/sve_helper.c | 4 +-
11
tcg/mips/tcg-target.c.inc | 12 +++++-------
14
target/arm/translate-a64.c | 2 +-
12
tcg/ppc/tcg-target.c.inc | 21 +++++----------------
15
5 files changed, 73 insertions(+), 71 deletions(-)
13
5 files changed, 19 insertions(+), 46 deletions(-)
16
14
17
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
15
diff --git a/include/exec/tlb-common.h b/include/exec/tlb-common.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/cpu-defs.h
17
--- a/include/exec/tlb-common.h
20
+++ b/include/exec/cpu-defs.h
18
+++ b/include/exec/tlb-common.h
21
@@ -XXX,XX +XXX,XX @@ typedef uint64_t target_ulong;
19
@@ -XXX,XX +XXX,XX @@
22
# endif
20
#ifndef EXEC_TLB_COMMON_H
23
# endif
21
#define EXEC_TLB_COMMON_H 1
24
22
25
+/* Minimalized TLB entry for use by TCG fast path. */
23
-#define CPU_TLB_ENTRY_BITS 5
26
typedef struct CPUTLBEntry {
24
+#define CPU_TLB_ENTRY_BITS (HOST_LONG_BITS == 32 ? 4 : 5)
27
/* bit TARGET_LONG_BITS to TARGET_PAGE_BITS : virtual address
25
28
bit TARGET_PAGE_BITS-1..4 : Nonzero for accesses that should not
26
/* Minimalized TLB entry for use by TCG fast path. */
29
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBEntry {
27
typedef union CPUTLBEntry {
28
struct {
29
- uint64_t addr_read;
30
- uint64_t addr_write;
31
- uint64_t addr_code;
32
+ uintptr_t addr_read;
33
+ uintptr_t addr_write;
34
+ uintptr_t addr_code;
35
/*
36
* Addend to virtual address to get host address. IO accesses
37
* use the corresponding iotlb value.
38
@@ -XXX,XX +XXX,XX @@ typedef union CPUTLBEntry {
39
* Padding to get a power of two size, as well as index
40
* access to addr_{read,write,code}.
41
*/
42
- uint64_t addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(uint64_t)];
43
+ uintptr_t addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(uintptr_t)];
44
} CPUTLBEntry;
30
45
31
QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
46
QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
32
33
-/* The IOTLB is not accessed directly inline by generated TCG code,
34
- * so the CPUIOTLBEntry layout is not as critical as that of the
35
- * CPUTLBEntry. (This is also why we don't want to combine the two
36
- * structs into one.)
37
+/*
38
+ * The full TLB entry, which is not accessed by generated TCG code,
39
+ * so the layout is not as critical as that of CPUTLBEntry. This is
40
+ * also why we don't want to combine the two structs.
41
*/
42
-typedef struct CPUIOTLBEntry {
43
+typedef struct CPUTLBEntryFull {
44
/*
45
- * @addr contains:
46
+ * @xlat_section contains:
47
* - in the lower TARGET_PAGE_BITS, a physical section number
48
* - with the lower TARGET_PAGE_BITS masked off, an offset which
49
* must be added to the virtual address to obtain:
50
@@ -XXX,XX +XXX,XX @@ typedef struct CPUIOTLBEntry {
51
* number is PHYS_SECTION_NOTDIRTY or PHYS_SECTION_ROM)
52
* + the offset within the target MemoryRegion (otherwise)
53
*/
54
- hwaddr addr;
55
+ hwaddr xlat_section;
56
MemTxAttrs attrs;
57
-} CPUIOTLBEntry;
58
+} CPUTLBEntryFull;
59
60
/*
61
* Data elements that are per MMU mode, minus the bits accessed by
62
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBDesc {
63
size_t vindex;
64
/* The tlb victim table, in two parts. */
65
CPUTLBEntry vtable[CPU_VTLB_SIZE];
66
- CPUIOTLBEntry viotlb[CPU_VTLB_SIZE];
67
- /* The iotlb. */
68
- CPUIOTLBEntry *iotlb;
69
+ CPUTLBEntryFull vfulltlb[CPU_VTLB_SIZE];
70
+ CPUTLBEntryFull *fulltlb;
71
} CPUTLBDesc;
72
73
/*
74
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
47
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
75
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
76
--- a/accel/tcg/cputlb.c
49
--- a/accel/tcg/cputlb.c
77
+++ b/accel/tcg/cputlb.c
50
+++ b/accel/tcg/cputlb.c
78
@@ -XXX,XX +XXX,XX @@ static void tlb_mmu_resize_locked(CPUTLBDesc *desc, CPUTLBDescFast *fast,
51
@@ -XXX,XX +XXX,XX @@ static inline uint64_t tlb_read_idx(const CPUTLBEntry *entry,
79
}
52
{
80
53
/* Do not rearrange the CPUTLBEntry structure members. */
81
g_free(fast->table);
54
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_read) !=
82
- g_free(desc->iotlb);
55
- MMU_DATA_LOAD * sizeof(uint64_t));
83
+ g_free(desc->fulltlb);
56
+ MMU_DATA_LOAD * sizeof(uintptr_t));
84
57
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_write) !=
85
tlb_window_reset(desc, now, 0);
58
- MMU_DATA_STORE * sizeof(uint64_t));
86
/* desc->n_used_entries is cleared by the caller */
59
+ MMU_DATA_STORE * sizeof(uintptr_t));
87
fast->mask = (new_size - 1) << CPU_TLB_ENTRY_BITS;
60
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_code) !=
88
fast->table = g_try_new(CPUTLBEntry, new_size);
61
- MMU_INST_FETCH * sizeof(uint64_t));
89
- desc->iotlb = g_try_new(CPUIOTLBEntry, new_size);
62
+ MMU_INST_FETCH * sizeof(uintptr_t));
90
+ desc->fulltlb = g_try_new(CPUTLBEntryFull, new_size);
63
91
64
-#if TARGET_LONG_BITS == 32
92
/*
65
- /* Use qatomic_read, in case of addr_write; only care about low bits. */
93
* If the allocations fail, try smaller sizes. We just freed some
66
- const uint32_t *ptr = (uint32_t *)&entry->addr_idx[access_type];
94
@@ -XXX,XX +XXX,XX @@ static void tlb_mmu_resize_locked(CPUTLBDesc *desc, CPUTLBDescFast *fast,
67
- ptr += HOST_BIG_ENDIAN;
95
* allocations to fail though, so we progressively reduce the allocation
68
- return qatomic_read(ptr);
96
* size, aborting if we cannot even allocate the smallest TLB we support.
69
-#else
97
*/
70
- const uint64_t *ptr = &entry->addr_idx[access_type];
98
- while (fast->table == NULL || desc->iotlb == NULL) {
71
+ const uintptr_t *ptr = &entry->addr_idx[access_type];
99
+ while (fast->table == NULL || desc->fulltlb == NULL) {
72
/* ofs might correspond to .addr_write, so use qatomic_read */
100
if (new_size == (1 << CPU_TLB_DYN_MIN_BITS)) {
73
return qatomic_read(ptr);
101
error_report("%s: %s", __func__, strerror(errno));
74
-#endif
102
abort();
75
}
103
@@ -XXX,XX +XXX,XX @@ static void tlb_mmu_resize_locked(CPUTLBDesc *desc, CPUTLBDescFast *fast,
76
104
fast->mask = (new_size - 1) << CPU_TLB_ENTRY_BITS;
77
static inline uint64_t tlb_addr_write(const CPUTLBEntry *entry)
105
78
@@ -XXX,XX +XXX,XX @@ static void tlb_reset_dirty_range_locked(CPUTLBEntry *tlb_entry,
106
g_free(fast->table);
79
addr &= TARGET_PAGE_MASK;
107
- g_free(desc->iotlb);
80
addr += tlb_entry->addend;
108
+ g_free(desc->fulltlb);
81
if ((addr - start) < length) {
109
fast->table = g_try_new(CPUTLBEntry, new_size);
82
-#if TARGET_LONG_BITS == 32
110
- desc->iotlb = g_try_new(CPUIOTLBEntry, new_size);
83
- uint32_t *ptr_write = (uint32_t *)&tlb_entry->addr_write;
111
+ desc->fulltlb = g_try_new(CPUTLBEntryFull, new_size);
84
- ptr_write += HOST_BIG_ENDIAN;
85
- qatomic_set(ptr_write, *ptr_write | TLB_NOTDIRTY);
86
-#else
87
qatomic_set(&tlb_entry->addr_write,
88
tlb_entry->addr_write | TLB_NOTDIRTY);
89
-#endif
90
}
112
}
91
}
113
}
92
}
114
93
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
115
@@ -XXX,XX +XXX,XX @@ static void tlb_mmu_init(CPUTLBDesc *desc, CPUTLBDescFast *fast, int64_t now)
94
index XXXXXXX..XXXXXXX 100644
116
desc->n_used_entries = 0;
95
--- a/tcg/arm/tcg-target.c.inc
117
fast->mask = (n_entries - 1) << CPU_TLB_ENTRY_BITS;
96
+++ b/tcg/arm/tcg-target.c.inc
118
fast->table = g_new(CPUTLBEntry, n_entries);
97
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
119
- desc->iotlb = g_new(CPUIOTLBEntry, n_entries);
98
* Add the tlb_table pointer, creating the CPUTLBEntry address in R1.
120
+ desc->fulltlb = g_new(CPUTLBEntryFull, n_entries);
99
* Load the tlb comparator into R2 and the fast path addend into R1.
121
tlb_mmu_flush_locked(desc, fast);
100
*/
122
}
101
- QEMU_BUILD_BUG_ON(HOST_BIG_ENDIAN);
123
102
if (cmp_off == 0) {
124
@@ -XXX,XX +XXX,XX @@ void tlb_destroy(CPUState *cpu)
103
tcg_out_ld32_rwb(s, COND_AL, TCG_REG_R2, TCG_REG_R1, TCG_REG_R0);
125
CPUTLBDescFast *fast = &env_tlb(env)->f[i];
104
} else {
126
105
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
127
g_free(fast->table);
106
index XXXXXXX..XXXXXXX 100644
128
- g_free(desc->iotlb);
107
--- a/tcg/mips/tcg-target.c.inc
129
+ g_free(desc->fulltlb);
108
+++ b/tcg/mips/tcg-target.c.inc
130
}
109
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
131
}
110
/* Add the tlb_table pointer, creating the CPUTLBEntry address. */
132
111
tcg_out_opc_reg(s, ALIAS_PADD, TCG_TMP3, TCG_TMP3, TCG_TMP1);
133
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
112
134
113
- if (TCG_TARGET_REG_BITS == 32 || addr_type == TCG_TYPE_I32) {
135
/* Evict the old entry into the victim tlb. */
114
- /* Load the (low half) tlb comparator. */
136
copy_tlb_helper_locked(tv, te);
115
+ /* Load the tlb comparator. */
137
- desc->viotlb[vidx] = desc->iotlb[index];
116
+ if (TCG_TARGET_REG_BITS == 64 && addr_type == TCG_TYPE_I32) {
138
+ desc->vfulltlb[vidx] = desc->fulltlb[index];
117
tcg_out_ld(s, TCG_TYPE_I32, TCG_TMP0, TCG_TMP3,
139
tlb_n_used_entries_dec(env, mmu_idx);
118
cmp_off + HOST_BIG_ENDIAN * 4);
140
}
119
} else {
141
120
- tcg_out_ld(s, TCG_TYPE_I64, TCG_TMP0, TCG_TMP3, cmp_off);
142
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
121
+ tcg_out_ld(s, TCG_TYPE_REG, TCG_TMP0, TCG_TMP3, cmp_off);
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
{
162
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
163
bool locked = false;
164
MemTxResult r;
165
166
- section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
167
+ section = iotlb_to_section(cpu, full->xlat_section, full->attrs);
168
mr = section->mr;
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
}
122
}
260
}
123
261
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
124
- if (TCG_TARGET_REG_BITS == 64 || addr_type == TCG_TYPE_I32) {
262
(ADDR) & TARGET_PAGE_MASK)
125
- /* Load the tlb addend for the fast path. */
263
126
- tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
264
static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size,
127
- }
265
- CPUIOTLBEntry *iotlbentry, uintptr_t retaddr)
128
+ /* Load the tlb addend for the fast path. */
266
+ CPUTLBEntryFull *full, uintptr_t retaddr)
129
+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP3, TCG_TMP3, add_off);
267
{
130
268
- ram_addr_t ram_addr = mem_vaddr + iotlbentry->addr;
131
/*
269
+ ram_addr_t ram_addr = mem_vaddr + full->xlat_section;
132
* Mask the page bits, keeping the alignment bits to compare against.
270
133
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
271
trace_memory_notdirty_write_access(mem_vaddr, ram_addr, size);
134
index XXXXXXX..XXXXXXX 100644
272
135
--- a/tcg/ppc/tcg-target.c.inc
273
@@ -XXX,XX +XXX,XX @@ int probe_access_flags(CPUArchState *env, target_ulong addr,
136
+++ b/tcg/ppc/tcg-target.c.inc
274
/* Handle clean RAM pages. */
137
@@ -XXX,XX +XXX,XX @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
275
if (unlikely(flags & TLB_NOTDIRTY)) {
138
tcg_out32(s, AND | SAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_R0));
276
uintptr_t index = tlb_index(env, mmu_idx, addr);
139
277
- CPUIOTLBEntry *iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
140
/*
278
+ CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
141
- * Load the (low part) TLB comparator into TMP2.
279
142
+ * Load the TLB comparator into TMP2.
280
- notdirty_write(env_cpu(env), addr, 1, iotlbentry, retaddr);
143
* For 64-bit host, always load the entire 64-bit slot for simplicity.
281
+ notdirty_write(env_cpu(env), addr, 1, full, retaddr);
144
* We will ignore the high bits with tcg_out_cmp(..., addr_type).
282
flags &= ~TLB_NOTDIRTY;
145
*/
283
}
146
- if (TCG_TARGET_REG_BITS == 64) {
284
147
- if (cmp_off == 0) {
285
@@ -XXX,XX +XXX,XX @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
148
- tcg_out32(s, LDUX | TAB(TCG_REG_TMP2,
286
149
- TCG_REG_TMP1, TCG_REG_TMP2));
287
if (unlikely(flags & (TLB_NOTDIRTY | TLB_WATCHPOINT))) {
150
- } else {
288
uintptr_t index = tlb_index(env, mmu_idx, addr);
151
- tcg_out32(s, ADD | TAB(TCG_REG_TMP1,
289
- CPUIOTLBEntry *iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];
152
- TCG_REG_TMP1, TCG_REG_TMP2));
290
+ CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
153
- tcg_out_ld(s, TCG_TYPE_I64, TCG_REG_TMP2,
291
154
- TCG_REG_TMP1, cmp_off);
292
/* Handle watchpoints. */
155
- }
293
if (flags & TLB_WATCHPOINT) {
156
- } else if (cmp_off == 0 && !HOST_BIG_ENDIAN) {
294
int wp_access = (access_type == MMU_DATA_STORE
157
- tcg_out32(s, LWZUX | TAB(TCG_REG_TMP2,
295
? BP_MEM_WRITE : BP_MEM_READ);
158
- TCG_REG_TMP1, TCG_REG_TMP2));
296
cpu_check_watchpoint(env_cpu(env), addr, size,
159
+ if (cmp_off == 0) {
297
- iotlbentry->attrs, wp_access, retaddr);
160
+ tcg_out32(s, (TCG_TARGET_REG_BITS == 64 ? LDUX : LWZUX)
298
+ full->attrs, wp_access, retaddr);
161
+ | TAB(TCG_REG_TMP2, TCG_REG_TMP1, TCG_REG_TMP2));
162
} else {
163
tcg_out32(s, ADD | TAB(TCG_REG_TMP1, TCG_REG_TMP1, TCG_REG_TMP2));
164
- tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP2, TCG_REG_TMP1,
165
- cmp_off + 4 * HOST_BIG_ENDIAN);
166
+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP1, cmp_off);
299
}
167
}
300
168
301
/* Handle clean RAM pages. */
169
/*
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
}
504
#endif
505
506
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
507
index XXXXXXX..XXXXXXX 100644
508
--- a/target/arm/translate-a64.c
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
}
518
519
--
170
--
520
2.34.1
171
2.43.0
521
172
522
173
diff view generated by jsdifflib
1
The availability of tb->pc will shortly be conditional.
1
For loongarch, mips, riscv and sparc, a zero register is
2
Introduce accessor functions to minimize ifdefs.
2
available all the time. For aarch64, register index 31
3
depends on context: sometimes it is the stack pointer,
4
and sometimes it is the zero register.
3
5
4
Pass around a known pc to places like tcg_gen_code,
6
Introduce a new general-purpose constraint which maps 0
5
where the caller must already have the value.
7
to TCG_REG_ZERO, if defined. This differs from existing
8
constant constraints in that const_arg[*] is recorded as
9
false, indicating that the value is in a register.
6
10
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
13
---
10
accel/tcg/internal.h | 6 ++++
14
include/tcg/tcg.h | 3 ++-
11
include/exec/exec-all.h | 6 ++++
15
tcg/aarch64/tcg-target.h | 2 ++
12
include/tcg/tcg.h | 2 +-
16
tcg/loongarch64/tcg-target.h | 2 ++
13
accel/tcg/cpu-exec.c | 46 ++++++++++++++-----------
17
tcg/mips/tcg-target.h | 2 ++
14
accel/tcg/translate-all.c | 37 +++++++++++---------
18
tcg/riscv/tcg-target.h | 2 ++
15
target/arm/cpu.c | 4 +--
19
tcg/sparc64/tcg-target.h | 3 ++-
16
target/avr/cpu.c | 2 +-
20
tcg/tcg.c | 29 ++++++++++++++++++++++-------
17
target/hexagon/cpu.c | 2 +-
21
docs/devel/tcg-ops.rst | 4 +++-
18
target/hppa/cpu.c | 4 +--
22
8 files changed, 37 insertions(+), 10 deletions(-)
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
23
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
24
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
66
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
67
--- a/include/tcg/tcg.h
26
--- a/include/tcg/tcg.h
68
+++ b/include/tcg/tcg.h
27
+++ b/include/tcg/tcg.h
69
@@ -XXX,XX +XXX,XX @@ void tcg_register_thread(void);
28
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(const TranslationBlock *, int,
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
29
76
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
30
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
77
31
78
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
32
-#define TCG_CT_CONST 1 /* any constant of register size */
33
+#define TCG_CT_CONST 1 /* any constant of register size */
34
+#define TCG_CT_REG_ZERO 2 /* zero, in TCG_REG_ZERO */
35
36
typedef struct TCGArgConstraint {
37
unsigned ct : 16;
38
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
79
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
80
--- a/accel/tcg/cpu-exec.c
40
--- a/tcg/aarch64/tcg-target.h
81
+++ b/accel/tcg/cpu-exec.c
41
+++ b/tcg/aarch64/tcg-target.h
82
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
42
@@ -XXX,XX +XXX,XX @@ typedef enum {
83
const TranslationBlock *tb = p;
43
TCG_AREG0 = TCG_REG_X19,
84
const struct tb_desc *desc = d;
44
} TCGReg;
85
45
86
- if (tb->pc == desc->pc &&
46
+#define TCG_REG_ZERO TCG_REG_XZR
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
+
47
+
139
if (cc->tcg_ops->synchronize_from_tb) {
48
#define TCG_TARGET_NB_REGS 64
140
cc->tcg_ops->synchronize_from_tb(cpu, last_tb);
49
141
} else {
50
#endif /* AARCH64_TCG_TARGET_H */
142
assert(cc->set_pc);
51
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
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
52
index XXXXXXX..XXXXXXX 100644
195
--- a/accel/tcg/translate-all.c
53
--- a/tcg/loongarch64/tcg-target.h
196
+++ b/accel/tcg/translate-all.c
54
+++ b/tcg/loongarch64/tcg-target.h
197
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
55
@@ -XXX,XX +XXX,XX @@ typedef enum {
198
56
TCG_VEC_TMP0 = TCG_REG_V23,
199
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
57
} TCGReg;
200
if (i == 0) {
58
201
- prev = (j == 0 ? tb->pc : 0);
59
+#define TCG_REG_ZERO TCG_REG_ZERO
202
+ prev = (j == 0 ? tb_pc(tb) : 0);
60
+
203
} else {
61
#endif /* LOONGARCH_TCG_TARGET_H */
204
prev = tcg_ctx->gen_insn_data[i - 1][j];
62
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
205
}
63
index XXXXXXX..XXXXXXX 100644
206
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
64
--- a/tcg/mips/tcg-target.h
207
static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
65
+++ b/tcg/mips/tcg-target.h
208
uintptr_t searched_pc, bool reset_icount)
66
@@ -XXX,XX +XXX,XX @@ typedef enum {
209
{
67
TCG_AREG0 = TCG_REG_S8,
210
- target_ulong data[TARGET_INSN_START_WORDS] = { tb->pc };
68
} TCGReg;
211
+ target_ulong data[TARGET_INSN_START_WORDS] = { tb_pc(tb) };
69
212
uintptr_t host_pc = (uintptr_t)tb->tc.ptr;
70
+#define TCG_REG_ZERO TCG_REG_ZERO
213
CPUArchState *env = cpu->env_ptr;
71
+
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
72
#endif
282
73
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
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
74
index XXXXXXX..XXXXXXX 100644
316
--- a/target/arm/cpu.c
75
--- a/tcg/riscv/tcg-target.h
317
+++ b/target/arm/cpu.c
76
+++ b/tcg/riscv/tcg-target.h
318
@@ -XXX,XX +XXX,XX @@ void arm_cpu_synchronize_from_tb(CPUState *cs,
77
@@ -XXX,XX +XXX,XX @@ typedef enum {
319
* never possible for an AArch64 TB to chain to an AArch32 TB.
78
TCG_REG_TMP2 = TCG_REG_T4,
320
*/
79
} TCGReg;
321
if (is_a64(env)) {
80
322
- env->pc = tb->pc;
81
+#define TCG_REG_ZERO TCG_REG_ZERO
323
+ env->pc = tb_pc(tb);
82
+
324
} else {
83
#endif
325
- env->regs[15] = tb->pc;
84
diff --git a/tcg/sparc64/tcg-target.h b/tcg/sparc64/tcg-target.h
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
85
index XXXXXXX..XXXXXXX 100644
332
--- a/target/avr/cpu.c
86
--- a/tcg/sparc64/tcg-target.h
333
+++ b/target/avr/cpu.c
87
+++ b/tcg/sparc64/tcg-target.h
334
@@ -XXX,XX +XXX,XX @@ static void avr_cpu_synchronize_from_tb(CPUState *cs,
88
@@ -XXX,XX +XXX,XX @@ typedef enum {
335
AVRCPU *cpu = AVR_CPU(cs);
89
TCG_REG_I7,
336
CPUAVRState *env = &cpu->env;
90
} TCGReg;
337
91
338
- env->pc_w = tb->pc / 2; /* internally PC points to words */
92
-#define TCG_AREG0 TCG_REG_I0
339
+ env->pc_w = tb_pc(tb) / 2; /* internally PC points to words */
93
+#define TCG_AREG0 TCG_REG_I0
340
}
94
+#define TCG_REG_ZERO TCG_REG_G0
341
95
342
static void avr_cpu_reset(DeviceState *ds)
96
#endif
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
418
index XXXXXXX..XXXXXXX 100644
419
--- a/target/mips/tcg/exception.c
420
+++ b/target/mips/tcg/exception.c
421
@@ -XXX,XX +XXX,XX @@ void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb)
422
MIPSCPU *cpu = MIPS_CPU(cs);
423
CPUMIPSState *env = &cpu->env;
424
425
- env->active_tc.PC = tb->pc;
426
+ env->active_tc.PC = tb_pc(tb);
427
env->hflags &= ~MIPS_HFLAG_BMASK;
428
env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
429
}
430
diff --git a/target/mips/tcg/sysemu/special_helper.c b/target/mips/tcg/sysemu/special_helper.c
431
index XXXXXXX..XXXXXXX 100644
432
--- a/target/mips/tcg/sysemu/special_helper.c
433
+++ b/target/mips/tcg/sysemu/special_helper.c
434
@@ -XXX,XX +XXX,XX @@ bool mips_io_recompile_replay_branch(CPUState *cs, const TranslationBlock *tb)
435
CPUMIPSState *env = &cpu->env;
436
437
if ((env->hflags & MIPS_HFLAG_BMASK) != 0
438
- && env->active_tc.PC != tb->pc) {
439
+ && env->active_tc.PC != tb_pc(tb)) {
440
env->active_tc.PC -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4);
441
env->hflags &= ~MIPS_HFLAG_BMASK;
442
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
97
diff --git a/tcg/tcg.c b/tcg/tcg.c
534
index XXXXXXX..XXXXXXX 100644
98
index XXXXXXX..XXXXXXX 100644
535
--- a/tcg/tcg.c
99
--- a/tcg/tcg.c
536
+++ b/tcg/tcg.c
100
+++ b/tcg/tcg.c
537
@@ -XXX,XX +XXX,XX @@ int64_t tcg_cpu_exec_time(void)
101
@@ -XXX,XX +XXX,XX @@ static void process_constraint_sets(void)
538
#endif
102
case 'i':
539
103
args_ct[i].ct |= TCG_CT_CONST;
540
104
break;
541
-int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
105
+#ifdef TCG_REG_ZERO
542
+int tcg_gen_code(TCGContext *s, TranslationBlock *tb, target_ulong pc_start)
106
+ case 'z':
543
{
107
+ args_ct[i].ct |= TCG_CT_REG_ZERO;
544
#ifdef CONFIG_PROFILER
108
+ break;
545
TCGProfile *prof = &s->prof;
109
+#endif
546
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
110
547
111
/* Include all of the target-specific constraints. */
548
#ifdef DEBUG_DISAS
112
549
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
113
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
550
- && qemu_log_in_addr_range(tb->pc))) {
114
arg_ct = &args_ct[i];
551
+ && qemu_log_in_addr_range(pc_start))) {
115
ts = arg_temp(arg);
552
FILE *logfile = qemu_log_trylock();
116
553
if (logfile) {
117
- if (ts->val_type == TEMP_VAL_CONST
554
fprintf(logfile, "OP:\n");
118
- && tcg_target_const_match(ts->val, arg_ct->ct, ts->type,
555
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
119
- op_cond, TCGOP_VECE(op))) {
556
if (s->nb_indirects > 0) {
120
- /* constant is OK for instruction */
557
#ifdef DEBUG_DISAS
121
- const_args[i] = 1;
558
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND)
122
- new_args[i] = ts->val;
559
- && qemu_log_in_addr_range(tb->pc))) {
123
- continue;
560
+ && qemu_log_in_addr_range(pc_start))) {
124
+ if (ts->val_type == TEMP_VAL_CONST) {
561
FILE *logfile = qemu_log_trylock();
125
+#ifdef TCG_REG_ZERO
562
if (logfile) {
126
+ if (ts->val == 0 && (arg_ct->ct & TCG_CT_REG_ZERO)) {
563
fprintf(logfile, "OP before indirect lowering:\n");
127
+ /* Hardware zero register: indicate register via non-const. */
564
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
128
+ const_args[i] = 0;
565
129
+ new_args[i] = TCG_REG_ZERO;
566
#ifdef DEBUG_DISAS
130
+ continue;
567
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
131
+ }
568
- && qemu_log_in_addr_range(tb->pc))) {
132
+#endif
569
+ && qemu_log_in_addr_range(pc_start))) {
133
+
570
FILE *logfile = qemu_log_trylock();
134
+ if (tcg_target_const_match(ts->val, arg_ct->ct, ts->type,
571
if (logfile) {
135
+ op_cond, TCGOP_VECE(op))) {
572
fprintf(logfile, "OP after optimization and liveness analysis:\n");
136
+ /* constant is OK for instruction */
137
+ const_args[i] = 1;
138
+ new_args[i] = ts->val;
139
+ continue;
140
+ }
141
}
142
143
reg = ts->reg;
144
diff --git a/docs/devel/tcg-ops.rst b/docs/devel/tcg-ops.rst
145
index XXXXXXX..XXXXXXX 100644
146
--- a/docs/devel/tcg-ops.rst
147
+++ b/docs/devel/tcg-ops.rst
148
@@ -XXX,XX +XXX,XX @@ operation uses a constant input constraint which does not allow all
149
constants, it must also accept registers in order to have a fallback.
150
The constraint '``i``' is defined generically to accept any constant.
151
The constraint '``r``' is not defined generically, but is consistently
152
-used by each backend to indicate all registers.
153
+used by each backend to indicate all registers. If ``TCG_REG_ZERO``
154
+is defined by the backend, the constraint '``z``' is defined generically
155
+to map constant 0 to the hardware zero register.
156
157
The movi_i32 and movi_i64 operations must accept any constants.
158
573
--
159
--
574
2.34.1
160
2.43.0
575
161
576
162
diff view generated by jsdifflib
1
The value previously chosen overlaps GUSA_MASK.
1
Note that 'Z' is still used for addsub2.
2
2
3
Rename all DELAY_SLOT_* and GUSA_* defines to emphasize
4
that they are included in TB_FLAGs. Add aliases for the
5
FPSCR and SR bits that are included in TB_FLAGS, so that
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>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
4
---
13
target/sh4/cpu.h | 56 +++++++++++++------------
5
tcg/aarch64/tcg-target-con-set.h | 12 ++++-----
14
linux-user/sh4/signal.c | 6 +--
6
tcg/aarch64/tcg-target.c.inc | 46 ++++++++++++++------------------
15
target/sh4/cpu.c | 6 +--
7
2 files changed, 26 insertions(+), 32 deletions(-)
16
target/sh4/helper.c | 6 +--
17
target/sh4/translate.c | 90 ++++++++++++++++++++++-------------------
18
5 files changed, 88 insertions(+), 76 deletions(-)
19
8
20
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
9
diff --git a/tcg/aarch64/tcg-target-con-set.h b/tcg/aarch64/tcg-target-con-set.h
21
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
22
--- a/target/sh4/cpu.h
11
--- a/tcg/aarch64/tcg-target-con-set.h
23
+++ b/target/sh4/cpu.h
12
+++ b/tcg/aarch64/tcg-target-con-set.h
24
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@
25
#define FPSCR_RM_NEAREST (0 << 0)
14
*/
26
#define FPSCR_RM_ZERO (1 << 0)
15
C_O0_I1(r)
27
16
C_O0_I2(r, rC)
28
-#define DELAY_SLOT_MASK 0x7
17
-C_O0_I2(rZ, r)
29
-#define DELAY_SLOT (1 << 0)
18
+C_O0_I2(rz, r)
30
-#define DELAY_SLOT_CONDITIONAL (1 << 1)
19
C_O0_I2(w, r)
31
-#define DELAY_SLOT_RTE (1 << 2)
20
-C_O0_I3(rZ, rZ, r)
32
+#define TB_FLAG_DELAY_SLOT (1 << 0)
21
+C_O0_I3(rz, rz, r)
33
+#define TB_FLAG_DELAY_SLOT_COND (1 << 1)
22
C_O1_I1(r, r)
34
+#define TB_FLAG_DELAY_SLOT_RTE (1 << 2)
23
C_O1_I1(w, r)
35
+#define TB_FLAG_PENDING_MOVCA (1 << 3)
24
C_O1_I1(w, w)
36
+#define TB_FLAG_GUSA_SHIFT 4 /* [11:4] */
25
C_O1_I1(w, wr)
37
+#define TB_FLAG_GUSA_EXCLUSIVE (1 << 12)
26
-C_O1_I2(r, 0, rZ)
38
+#define TB_FLAG_UNALIGN (1 << 13)
27
+C_O1_I2(r, 0, rz)
39
+#define TB_FLAG_SR_FD (1 << SR_FD) /* 15 */
28
C_O1_I2(r, r, r)
40
+#define TB_FLAG_FPSCR_PR FPSCR_PR /* 19 */
29
C_O1_I2(r, r, rA)
41
+#define TB_FLAG_FPSCR_SZ FPSCR_SZ /* 20 */
30
C_O1_I2(r, r, rAL)
42
+#define TB_FLAG_FPSCR_FR FPSCR_FR /* 21 */
31
C_O1_I2(r, r, rC)
43
+#define TB_FLAG_SR_RB (1 << SR_RB) /* 29 */
32
C_O1_I2(r, r, ri)
44
+#define TB_FLAG_SR_MD (1 << SR_MD) /* 30 */
33
C_O1_I2(r, r, rL)
45
34
-C_O1_I2(r, rZ, rZ)
46
-#define TB_FLAG_PENDING_MOVCA (1 << 3)
35
+C_O1_I2(r, rz, rz)
47
-#define TB_FLAG_UNALIGN (1 << 4)
36
C_O1_I2(w, 0, w)
37
C_O1_I2(w, w, w)
38
C_O1_I2(w, w, wN)
39
C_O1_I2(w, w, wO)
40
C_O1_I2(w, w, wZ)
41
C_O1_I3(w, w, w, w)
42
-C_O1_I4(r, r, rC, rZ, rZ)
43
+C_O1_I4(r, r, rC, rz, rz)
44
C_O2_I1(r, r, r)
45
-C_O2_I4(r, r, rZ, rZ, rA, rMZ)
46
+C_O2_I4(r, r, rz, rz, rA, rMZ)
47
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
48
index XXXXXXX..XXXXXXX 100644
49
--- a/tcg/aarch64/tcg-target.c.inc
50
+++ b/tcg/aarch64/tcg-target.c.inc
51
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
52
TCGArg a2 = args[2];
53
int c2 = const_args[2];
54
55
- /* Some operands are defined with "rZ" constraint, a register or
56
- the zero register. These need not actually test args[I] == 0. */
57
-#define REG0(I) (const_args[I] ? TCG_REG_XZR : (TCGReg)args[I])
48
-
58
-
49
-#define GUSA_SHIFT 4
59
switch (opc) {
50
-#ifdef CONFIG_USER_ONLY
60
case INDEX_op_goto_ptr:
51
-#define GUSA_EXCLUSIVE (1 << 12)
61
tcg_out_insn(s, 3207, BR, a0);
52
-#define GUSA_MASK ((0xff << GUSA_SHIFT) | GUSA_EXCLUSIVE)
62
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
53
-#else
63
54
-/* Provide dummy versions of the above to allow tests against tbflags
64
case INDEX_op_st8_i32:
55
- to be elided while avoiding ifdefs. */
65
case INDEX_op_st8_i64:
56
-#define GUSA_EXCLUSIVE 0
66
- tcg_out_ldst(s, I3312_STRB, REG0(0), a1, a2, 0);
57
-#define GUSA_MASK 0
67
+ tcg_out_ldst(s, I3312_STRB, a0, a1, a2, 0);
58
-#endif
68
break;
69
case INDEX_op_st16_i32:
70
case INDEX_op_st16_i64:
71
- tcg_out_ldst(s, I3312_STRH, REG0(0), a1, a2, 1);
72
+ tcg_out_ldst(s, I3312_STRH, a0, a1, a2, 1);
73
break;
74
case INDEX_op_st_i32:
75
case INDEX_op_st32_i64:
76
- tcg_out_ldst(s, I3312_STRW, REG0(0), a1, a2, 2);
77
+ tcg_out_ldst(s, I3312_STRW, a0, a1, a2, 2);
78
break;
79
case INDEX_op_st_i64:
80
- tcg_out_ldst(s, I3312_STRX, REG0(0), a1, a2, 3);
81
+ tcg_out_ldst(s, I3312_STRX, a0, a1, a2, 3);
82
break;
83
84
case INDEX_op_add_i32:
85
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
86
/* FALLTHRU */
87
case INDEX_op_movcond_i64:
88
tcg_out_cmp(s, ext, args[5], a1, a2, c2);
89
- tcg_out_insn(s, 3506, CSEL, ext, a0, REG0(3), REG0(4), args[5]);
90
+ tcg_out_insn(s, 3506, CSEL, ext, a0, args[3], args[4], args[5]);
91
break;
92
93
case INDEX_op_qemu_ld_i32:
94
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
95
break;
96
case INDEX_op_qemu_st_i32:
97
case INDEX_op_qemu_st_i64:
98
- tcg_out_qemu_st(s, REG0(0), a1, a2, ext);
99
+ tcg_out_qemu_st(s, a0, a1, a2, ext);
100
break;
101
case INDEX_op_qemu_ld_i128:
102
tcg_out_qemu_ldst_i128(s, a0, a1, a2, args[3], true);
103
break;
104
case INDEX_op_qemu_st_i128:
105
- tcg_out_qemu_ldst_i128(s, REG0(0), REG0(1), a2, args[3], false);
106
+ tcg_out_qemu_ldst_i128(s, a0, a1, a2, args[3], false);
107
break;
108
109
case INDEX_op_bswap64_i64:
110
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
111
112
case INDEX_op_deposit_i64:
113
case INDEX_op_deposit_i32:
114
- tcg_out_dep(s, ext, a0, REG0(2), args[3], args[4]);
115
+ tcg_out_dep(s, ext, a0, a2, args[3], args[4]);
116
break;
117
118
case INDEX_op_extract_i64:
119
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
120
121
case INDEX_op_extract2_i64:
122
case INDEX_op_extract2_i32:
123
- tcg_out_extr(s, ext, a0, REG0(2), REG0(1), args[3]);
124
+ tcg_out_extr(s, ext, a0, a2, a1, args[3]);
125
break;
126
127
case INDEX_op_add2_i32:
128
- tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, REG0(2), REG0(3),
129
+ tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, a2, args[3],
130
(int32_t)args[4], args[5], const_args[4],
131
const_args[5], false);
132
break;
133
case INDEX_op_add2_i64:
134
- tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, REG0(2), REG0(3), args[4],
135
+ tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, a2, args[3], args[4],
136
args[5], const_args[4], const_args[5], false);
137
break;
138
case INDEX_op_sub2_i32:
139
- tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, REG0(2), REG0(3),
140
+ tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, a2, args[3],
141
(int32_t)args[4], args[5], const_args[4],
142
const_args[5], true);
143
break;
144
case INDEX_op_sub2_i64:
145
- tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, REG0(2), REG0(3), args[4],
146
+ tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, a2, args[3], args[4],
147
args[5], const_args[4], const_args[5], true);
148
break;
149
150
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
151
default:
152
g_assert_not_reached();
153
}
59
-
154
-
60
-#define TB_FLAG_ENVFLAGS_MASK (DELAY_SLOT_MASK | GUSA_MASK)
155
-#undef REG0
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
}
156
}
113
157
114
void setup_frame(int sig, struct target_sigaction *ka,
158
static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
115
@@ -XXX,XX +XXX,XX @@ void setup_frame(int sig, struct target_sigaction *ka,
159
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
116
regs->gregs[5] = 0;
160
case INDEX_op_st16_i64:
117
regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
161
case INDEX_op_st32_i64:
118
regs->pc = (unsigned long) ka->_sa_handler;
162
case INDEX_op_st_i64:
119
- regs->flags &= ~(DELAY_SLOT_MASK | GUSA_MASK);
163
- return C_O0_I2(rZ, r);
120
+ regs->flags &= ~(TB_FLAG_DELAY_SLOT_MASK | TB_FLAG_GUSA_MASK);
164
+ return C_O0_I2(rz, r);
121
165
122
unlock_user_struct(frame, frame_addr, 1);
166
case INDEX_op_add_i32:
123
return;
167
case INDEX_op_add_i64:
124
@@ -XXX,XX +XXX,XX @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
168
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
125
regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
169
126
regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
170
case INDEX_op_movcond_i32:
127
regs->pc = (unsigned long) ka->_sa_handler;
171
case INDEX_op_movcond_i64:
128
- regs->flags &= ~(DELAY_SLOT_MASK | GUSA_MASK);
172
- return C_O1_I4(r, r, rC, rZ, rZ);
129
+ regs->flags &= ~(TB_FLAG_DELAY_SLOT_MASK | TB_FLAG_GUSA_MASK);
173
+ return C_O1_I4(r, r, rC, rz, rz);
130
174
131
unlock_user_struct(frame, frame_addr, 1);
175
case INDEX_op_qemu_ld_i32:
132
return;
176
case INDEX_op_qemu_ld_i64:
133
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
177
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
134
index XXXXXXX..XXXXXXX 100644
178
return C_O2_I1(r, r, r);
135
--- a/target/sh4/cpu.c
179
case INDEX_op_qemu_st_i32:
136
+++ b/target/sh4/cpu.c
180
case INDEX_op_qemu_st_i64:
137
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_synchronize_from_tb(CPUState *cs,
181
- return C_O0_I2(rZ, r);
138
SuperHCPU *cpu = SUPERH_CPU(cs);
182
+ return C_O0_I2(rz, r);
139
183
case INDEX_op_qemu_st_i128:
140
cpu->env.pc = tb_pc(tb);
184
- return C_O0_I3(rZ, rZ, r);
141
- cpu->env.flags = tb->flags & TB_FLAG_ENVFLAGS_MASK;
185
+ return C_O0_I3(rz, rz, r);
142
+ cpu->env.flags = tb->flags;
186
143
}
187
case INDEX_op_deposit_i32:
144
188
case INDEX_op_deposit_i64:
145
#ifndef CONFIG_USER_ONLY
189
- return C_O1_I2(r, 0, rZ);
146
@@ -XXX,XX +XXX,XX @@ static bool superh_io_recompile_replay_branch(CPUState *cs,
190
+ return C_O1_I2(r, 0, rz);
147
SuperHCPU *cpu = SUPERH_CPU(cs);
191
148
CPUSH4State *env = &cpu->env;
192
case INDEX_op_extract2_i32:
149
193
case INDEX_op_extract2_i64:
150
- if ((env->flags & ((DELAY_SLOT | DELAY_SLOT_CONDITIONAL))) != 0
194
- return C_O1_I2(r, rZ, rZ);
151
+ if ((env->flags & (TB_FLAG_DELAY_SLOT | TB_FLAG_DELAY_SLOT_COND))
195
+ return C_O1_I2(r, rz, rz);
152
&& env->pc != tb_pc(tb)) {
196
153
env->pc -= 2;
197
case INDEX_op_add2_i32:
154
- env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
198
case INDEX_op_add2_i64:
155
+ env->flags &= ~(TB_FLAG_DELAY_SLOT | TB_FLAG_DELAY_SLOT_COND);
199
case INDEX_op_sub2_i32:
156
return true;
200
case INDEX_op_sub2_i64:
157
}
201
- return C_O2_I4(r, r, rZ, rZ, rA, rMZ);
158
return false;
202
+ return C_O2_I4(r, r, rz, rz, rA, rMZ);
159
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
203
160
index XXXXXXX..XXXXXXX 100644
204
case INDEX_op_add_vec:
161
--- a/target/sh4/helper.c
205
case INDEX_op_sub_vec:
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
--
206
--
487
2.34.1
207
2.43.0
diff view generated by jsdifflib
1
Allow the target to cache items from the guest page tables.
1
Replace target-specific 'Z' with generic 'z'.
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/exec/cpu-defs.h | 9 +++++++++
6
tcg/loongarch64/tcg-target-con-set.h | 15 ++++++-------
9
1 file changed, 9 insertions(+)
7
tcg/loongarch64/tcg-target-con-str.h | 1 -
8
tcg/loongarch64/tcg-target.c.inc | 32 ++++++++++++----------------
9
3 files changed, 21 insertions(+), 27 deletions(-)
10
10
11
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
11
diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/exec/cpu-defs.h
13
--- a/tcg/loongarch64/tcg-target-con-set.h
14
+++ b/include/exec/cpu-defs.h
14
+++ b/tcg/loongarch64/tcg-target-con-set.h
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBEntryFull {
15
@@ -XXX,XX +XXX,XX @@
16
16
* tcg-target-con-str.h; the constraint combination is inclusive or.
17
/* @lg_page_size contains the log2 of the page size. */
17
*/
18
uint8_t lg_page_size;
18
C_O0_I1(r)
19
+
19
-C_O0_I2(rZ, r)
20
+ /*
20
-C_O0_I2(rZ, rZ)
21
+ * Allow target-specific additions to this structure.
21
+C_O0_I2(rz, r)
22
+ * This may be used to cache items from the guest cpu
22
+C_O0_I2(rz, rz)
23
+ * page tables for later use by the implementation.
23
C_O0_I2(w, r)
24
+ */
24
C_O0_I3(r, r, r)
25
+#ifdef TARGET_PAGE_ENTRY_EXTRA
25
C_O1_I1(r, r)
26
+ TARGET_PAGE_ENTRY_EXTRA
26
@@ -XXX,XX +XXX,XX @@ C_O1_I2(r, r, rI)
27
+#endif
27
C_O1_I2(r, r, rJ)
28
} CPUTLBEntryFull;
28
C_O1_I2(r, r, rU)
29
29
C_O1_I2(r, r, rW)
30
/*
30
-C_O1_I2(r, r, rZ)
31
-C_O1_I2(r, 0, rZ)
32
-C_O1_I2(r, rZ, ri)
33
-C_O1_I2(r, rZ, rJ)
34
-C_O1_I2(r, rZ, rZ)
35
+C_O1_I2(r, 0, rz)
36
+C_O1_I2(r, rz, ri)
37
+C_O1_I2(r, rz, rJ)
38
+C_O1_I2(r, rz, rz)
39
C_O1_I2(w, w, w)
40
C_O1_I2(w, w, wM)
41
C_O1_I2(w, w, wA)
42
C_O1_I3(w, w, w, w)
43
-C_O1_I4(r, rZ, rJ, rZ, rZ)
44
+C_O1_I4(r, rz, rJ, rz, rz)
45
C_N2_I1(r, r, r)
46
diff --git a/tcg/loongarch64/tcg-target-con-str.h b/tcg/loongarch64/tcg-target-con-str.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/tcg/loongarch64/tcg-target-con-str.h
49
+++ b/tcg/loongarch64/tcg-target-con-str.h
50
@@ -XXX,XX +XXX,XX @@ REGS('w', ALL_VECTOR_REGS)
51
CONST('I', TCG_CT_CONST_S12)
52
CONST('J', TCG_CT_CONST_S32)
53
CONST('U', TCG_CT_CONST_U12)
54
-CONST('Z', TCG_CT_CONST_ZERO)
55
CONST('C', TCG_CT_CONST_C12)
56
CONST('W', TCG_CT_CONST_WSZ)
57
CONST('M', TCG_CT_CONST_VCMP)
58
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
59
index XXXXXXX..XXXXXXX 100644
60
--- a/tcg/loongarch64/tcg-target.c.inc
61
+++ b/tcg/loongarch64/tcg-target.c.inc
62
@@ -XXX,XX +XXX,XX @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
63
64
#define TCG_GUEST_BASE_REG TCG_REG_S1
65
66
-#define TCG_CT_CONST_ZERO 0x100
67
-#define TCG_CT_CONST_S12 0x200
68
-#define TCG_CT_CONST_S32 0x400
69
-#define TCG_CT_CONST_U12 0x800
70
-#define TCG_CT_CONST_C12 0x1000
71
-#define TCG_CT_CONST_WSZ 0x2000
72
-#define TCG_CT_CONST_VCMP 0x4000
73
-#define TCG_CT_CONST_VADD 0x8000
74
+#define TCG_CT_CONST_S12 0x100
75
+#define TCG_CT_CONST_S32 0x200
76
+#define TCG_CT_CONST_U12 0x400
77
+#define TCG_CT_CONST_C12 0x800
78
+#define TCG_CT_CONST_WSZ 0x1000
79
+#define TCG_CT_CONST_VCMP 0x2000
80
+#define TCG_CT_CONST_VADD 0x4000
81
82
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
83
#define ALL_VECTOR_REGS MAKE_64BIT_MASK(32, 32)
84
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
85
if (ct & TCG_CT_CONST) {
86
return true;
87
}
88
- if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
89
- return true;
90
- }
91
if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
92
return true;
93
}
94
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
95
case INDEX_op_st_i64:
96
case INDEX_op_qemu_st_i32:
97
case INDEX_op_qemu_st_i64:
98
- return C_O0_I2(rZ, r);
99
+ return C_O0_I2(rz, r);
100
101
case INDEX_op_qemu_ld_i128:
102
return C_N2_I1(r, r, r);
103
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
104
105
case INDEX_op_brcond_i32:
106
case INDEX_op_brcond_i64:
107
- return C_O0_I2(rZ, rZ);
108
+ return C_O0_I2(rz, rz);
109
110
case INDEX_op_ext8s_i32:
111
case INDEX_op_ext8s_i64:
112
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
113
case INDEX_op_deposit_i32:
114
case INDEX_op_deposit_i64:
115
/* Must deposit into the same register as input */
116
- return C_O1_I2(r, 0, rZ);
117
+ return C_O1_I2(r, 0, rz);
118
119
case INDEX_op_sub_i32:
120
case INDEX_op_setcond_i32:
121
- return C_O1_I2(r, rZ, ri);
122
+ return C_O1_I2(r, rz, ri);
123
case INDEX_op_sub_i64:
124
case INDEX_op_setcond_i64:
125
- return C_O1_I2(r, rZ, rJ);
126
+ return C_O1_I2(r, rz, rJ);
127
128
case INDEX_op_mul_i32:
129
case INDEX_op_mul_i64:
130
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
131
case INDEX_op_rem_i64:
132
case INDEX_op_remu_i32:
133
case INDEX_op_remu_i64:
134
- return C_O1_I2(r, rZ, rZ);
135
+ return C_O1_I2(r, rz, rz);
136
137
case INDEX_op_movcond_i32:
138
case INDEX_op_movcond_i64:
139
- return C_O1_I4(r, rZ, rJ, rZ, rZ);
140
+ return C_O1_I4(r, rz, rJ, rz, rz);
141
142
case INDEX_op_ld_vec:
143
case INDEX_op_dupm_vec:
31
--
144
--
32
2.34.1
145
2.43.0
33
146
34
147
diff view generated by jsdifflib
1
Now that we have collected all of the page data into
1
Replace target-specific 'Z' with generic 'z'.
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
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
5
---
12
include/exec/cpu-defs.h | 14 +++++++++++
6
tcg/mips/tcg-target-con-set.h | 26 ++++++++++-----------
13
include/exec/exec-all.h | 22 ++++++++++++++++++
7
tcg/mips/tcg-target-con-str.h | 1 -
14
accel/tcg/cputlb.c | 51 ++++++++++++++++++++++++++---------------
8
tcg/mips/tcg-target.c.inc | 44 ++++++++++++++---------------------
15
3 files changed, 69 insertions(+), 18 deletions(-)
9
3 files changed, 31 insertions(+), 40 deletions(-)
16
10
17
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
11
diff --git a/tcg/mips/tcg-target-con-set.h b/tcg/mips/tcg-target-con-set.h
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/cpu-defs.h
13
--- a/tcg/mips/tcg-target-con-set.h
20
+++ b/include/exec/cpu-defs.h
14
+++ b/tcg/mips/tcg-target-con-set.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLBEntryFull {
15
@@ -XXX,XX +XXX,XX @@
22
* + the offset within the target MemoryRegion (otherwise)
16
* tcg-target-con-str.h; the constraint combination is inclusive or.
23
*/
17
*/
24
hwaddr xlat_section;
18
C_O0_I1(r)
25
+
19
-C_O0_I2(rZ, r)
26
+ /*
20
-C_O0_I2(rZ, rZ)
27
+ * @phys_addr contains the physical address in the address space
21
-C_O0_I3(rZ, r, r)
28
+ * given by cpu_asidx_from_attrs(cpu, @attrs).
22
-C_O0_I3(rZ, rZ, r)
29
+ */
23
-C_O0_I4(rZ, rZ, rZ, rZ)
30
+ hwaddr phys_addr;
24
-C_O0_I4(rZ, rZ, r, r)
31
+
25
+C_O0_I2(rz, r)
32
+ /* @attrs contains the memory transaction attributes for the page. */
26
+C_O0_I2(rz, rz)
33
MemTxAttrs attrs;
27
+C_O0_I3(rz, r, r)
34
+
28
+C_O0_I3(rz, rz, r)
35
+ /* @prot contains the complete protections for the page. */
29
+C_O0_I4(rz, rz, rz, rz)
36
+ uint8_t prot;
30
+C_O0_I4(rz, rz, r, r)
37
+
31
C_O1_I1(r, r)
38
+ /* @lg_page_size contains the log2 of the page size. */
32
-C_O1_I2(r, 0, rZ)
39
+ uint8_t lg_page_size;
33
+C_O1_I2(r, 0, rz)
40
} CPUTLBEntryFull;
34
C_O1_I2(r, r, r)
41
35
C_O1_I2(r, r, ri)
42
/*
36
C_O1_I2(r, r, rI)
43
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
37
C_O1_I2(r, r, rIK)
38
C_O1_I2(r, r, rJ)
39
-C_O1_I2(r, r, rWZ)
40
-C_O1_I2(r, rZ, rN)
41
-C_O1_I2(r, rZ, rZ)
42
-C_O1_I4(r, rZ, rZ, rZ, 0)
43
-C_O1_I4(r, rZ, rZ, rZ, rZ)
44
+C_O1_I2(r, r, rzW)
45
+C_O1_I2(r, rz, rN)
46
+C_O1_I2(r, rz, rz)
47
+C_O1_I4(r, rz, rz, rz, 0)
48
+C_O1_I4(r, rz, rz, rz, rz)
49
C_O2_I1(r, r, r)
50
C_O2_I2(r, r, r, r)
51
-C_O2_I4(r, r, rZ, rZ, rN, rN)
52
+C_O2_I4(r, r, rz, rz, rN, rN)
53
diff --git a/tcg/mips/tcg-target-con-str.h b/tcg/mips/tcg-target-con-str.h
44
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
45
--- a/include/exec/exec-all.h
55
--- a/tcg/mips/tcg-target-con-str.h
46
+++ b/include/exec/exec-all.h
56
+++ b/tcg/mips/tcg-target-con-str.h
47
@@ -XXX,XX +XXX,XX @@ void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu,
57
@@ -XXX,XX +XXX,XX @@ CONST('J', TCG_CT_CONST_S16)
48
uint16_t idxmap,
58
CONST('K', TCG_CT_CONST_P2M1)
49
unsigned bits);
59
CONST('N', TCG_CT_CONST_N16)
50
60
CONST('W', TCG_CT_CONST_WSZ)
51
+/**
61
-CONST('Z', TCG_CT_CONST_ZERO)
52
+ * tlb_set_page_full:
62
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
53
+ * @cpu: CPU context
54
+ * @mmu_idx: mmu index of the tlb to modify
55
+ * @vaddr: virtual address of the entry to add
56
+ * @full: the details of the tlb entry
57
+ *
58
+ * Add an entry to @cpu tlb index @mmu_idx. All of the fields of
59
+ * @full must be filled, except for xlat_section, and constitute
60
+ * the complete description of the translated page.
61
+ *
62
+ * This is generally called by the target tlb_fill function after
63
+ * having performed a successful page table walk to find the physical
64
+ * address and attributes for the translation.
65
+ *
66
+ * At most one entry for a given virtual address is permitted. Only a
67
+ * single TARGET_PAGE_SIZE region is mapped; @full->lg_page_size is only
68
+ * used by tlb_flush_page.
69
+ */
70
+void tlb_set_page_full(CPUState *cpu, int mmu_idx, target_ulong vaddr,
71
+ CPUTLBEntryFull *full);
72
+
73
/**
74
* tlb_set_page_with_attrs:
75
* @cpu: CPU to add this TLB entry for
76
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
77
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
78
--- a/accel/tcg/cputlb.c
64
--- a/tcg/mips/tcg-target.c.inc
79
+++ b/accel/tcg/cputlb.c
65
+++ b/tcg/mips/tcg-target.c.inc
80
@@ -XXX,XX +XXX,XX @@ static void tlb_add_large_page(CPUArchState *env, int mmu_idx,
66
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
81
env_tlb(env)->d[mmu_idx].large_page_mask = lp_mask;
67
g_assert_not_reached();
82
}
68
}
83
69
84
-/* Add a new TLB entry. At most one entry for a given virtual address
70
-#define TCG_CT_CONST_ZERO 0x100
85
+/*
71
-#define TCG_CT_CONST_U16 0x200 /* Unsigned 16-bit: 0 - 0xffff. */
86
+ * Add a new TLB entry. At most one entry for a given virtual address
72
-#define TCG_CT_CONST_S16 0x400 /* Signed 16-bit: -32768 - 32767 */
87
* is permitted. Only a single TARGET_PAGE_SIZE region is mapped, the
73
-#define TCG_CT_CONST_P2M1 0x800 /* Power of 2 minus 1. */
88
* supplied size is only used by tlb_flush_page.
74
-#define TCG_CT_CONST_N16 0x1000 /* "Negatable" 16-bit: -32767 - 32767 */
89
*
75
-#define TCG_CT_CONST_WSZ 0x2000 /* word size */
90
* Called from TCG-generated code, which is under an RCU read-side
76
+#define TCG_CT_CONST_U16 0x100 /* Unsigned 16-bit: 0 - 0xffff. */
91
* critical section.
77
+#define TCG_CT_CONST_S16 0x200 /* Signed 16-bit: -32768 - 32767 */
92
*/
78
+#define TCG_CT_CONST_P2M1 0x400 /* Power of 2 minus 1. */
93
-void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
79
+#define TCG_CT_CONST_N16 0x800 /* "Negatable" 16-bit: -32767 - 32767 */
94
- hwaddr paddr, MemTxAttrs attrs, int prot,
80
+#define TCG_CT_CONST_WSZ 0x1000 /* word size */
95
- int mmu_idx, target_ulong size)
81
96
+void tlb_set_page_full(CPUState *cpu, int mmu_idx,
82
#define ALL_GENERAL_REGS 0xffffffffu
97
+ target_ulong vaddr, CPUTLBEntryFull *full)
83
84
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
98
{
85
{
99
CPUArchState *env = cpu->env_ptr;
86
if (ct & TCG_CT_CONST) {
100
CPUTLB *tlb = env_tlb(env);
87
return 1;
101
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
88
- } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
102
CPUTLBEntry *te, tn;
89
- return 1;
103
hwaddr iotlb, xlat, sz, paddr_page;
90
} else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
104
target_ulong vaddr_page;
91
return 1;
105
- int asidx = cpu_asidx_from_attrs(cpu, attrs);
92
} else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
106
- int wp_flags;
93
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
107
+ int asidx, wp_flags, prot;
94
TCGArg a0, a1, a2;
108
bool is_ram, is_romd;
95
int c2;
109
96
110
assert_cpu_is_self(cpu);
97
- /*
111
98
- * Note that many operands use the constraint set "rZ".
112
- if (size <= TARGET_PAGE_SIZE) {
99
- * We make use of the fact that 0 is the ZERO register,
113
+ if (full->lg_page_size <= TARGET_PAGE_BITS) {
100
- * and hence such cases need not check for const_args.
114
sz = TARGET_PAGE_SIZE;
101
- */
115
} else {
102
a0 = args[0];
116
- tlb_add_large_page(env, mmu_idx, vaddr, size);
103
a1 = args[1];
117
- sz = size;
104
a2 = args[2];
118
+ sz = (hwaddr)1 << full->lg_page_size;
105
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
119
+ tlb_add_large_page(env, mmu_idx, vaddr, sz);
106
case INDEX_op_st16_i64:
120
}
107
case INDEX_op_st32_i64:
121
vaddr_page = vaddr & TARGET_PAGE_MASK;
108
case INDEX_op_st_i64:
122
- paddr_page = paddr & TARGET_PAGE_MASK;
109
- return C_O0_I2(rZ, r);
123
+ paddr_page = full->phys_addr & TARGET_PAGE_MASK;
110
+ return C_O0_I2(rz, r);
124
111
125
+ prot = full->prot;
112
case INDEX_op_add_i32:
126
+ asidx = cpu_asidx_from_attrs(cpu, full->attrs);
113
case INDEX_op_add_i64:
127
section = address_space_translate_for_iotlb(cpu, asidx, paddr_page,
114
return C_O1_I2(r, r, rJ);
128
- &xlat, &sz, attrs, &prot);
115
case INDEX_op_sub_i32:
129
+ &xlat, &sz, full->attrs, &prot);
116
case INDEX_op_sub_i64:
130
assert(sz >= TARGET_PAGE_SIZE);
117
- return C_O1_I2(r, rZ, rN);
131
118
+ return C_O1_I2(r, rz, rN);
132
tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
119
case INDEX_op_mul_i32:
133
" prot=%x idx=%d\n",
120
case INDEX_op_mulsh_i32:
134
- vaddr, paddr, prot, mmu_idx);
121
case INDEX_op_muluh_i32:
135
+ vaddr, full->phys_addr, prot, mmu_idx);
122
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
136
123
case INDEX_op_remu_i64:
137
address = vaddr_page;
124
case INDEX_op_nor_i64:
138
- if (size < TARGET_PAGE_SIZE) {
125
case INDEX_op_setcond_i64:
139
+ if (full->lg_page_size < TARGET_PAGE_BITS) {
126
- return C_O1_I2(r, rZ, rZ);
140
/* Repeat the MMU check and TLB fill on every access. */
127
+ return C_O1_I2(r, rz, rz);
141
address |= TLB_INVALID_MASK;
128
case INDEX_op_muls2_i32:
142
}
129
case INDEX_op_mulu2_i32:
143
- if (attrs.byte_swap) {
130
case INDEX_op_muls2_i64:
144
+ if (full->attrs.byte_swap) {
131
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
145
address |= TLB_BSWAP;
132
return C_O1_I2(r, r, ri);
146
}
133
case INDEX_op_clz_i32:
147
134
case INDEX_op_clz_i64:
148
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
135
- return C_O1_I2(r, r, rWZ);
149
* subtract here is that of the page base, and not the same as the
136
+ return C_O1_I2(r, r, rzW);
150
* vaddr we add back in io_readx()/io_writex()/get_page_addr_code().
137
151
*/
138
case INDEX_op_deposit_i32:
152
+ desc->fulltlb[index] = *full;
139
case INDEX_op_deposit_i64:
153
desc->fulltlb[index].xlat_section = iotlb - vaddr_page;
140
- return C_O1_I2(r, 0, rZ);
154
- desc->fulltlb[index].attrs = attrs;
141
+ return C_O1_I2(r, 0, rz);
155
+ desc->fulltlb[index].phys_addr = paddr_page;
142
case INDEX_op_brcond_i32:
156
+ desc->fulltlb[index].prot = prot;
143
case INDEX_op_brcond_i64:
157
144
- return C_O0_I2(rZ, rZ);
158
/* Now calculate the new entry */
145
+ return C_O0_I2(rz, rz);
159
tn.addend = addend - vaddr_page;
146
case INDEX_op_movcond_i32:
160
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
147
case INDEX_op_movcond_i64:
161
qemu_spin_unlock(&tlb->c.lock);
148
return (use_mips32r6_instructions
162
}
149
- ? C_O1_I4(r, rZ, rZ, rZ, rZ)
163
150
- : C_O1_I4(r, rZ, rZ, rZ, 0));
164
-/* Add a new TLB entry, but without specifying the memory
151
+ ? C_O1_I4(r, rz, rz, rz, rz)
165
- * transaction attributes to be used.
152
+ : C_O1_I4(r, rz, rz, rz, 0));
166
- */
153
case INDEX_op_add2_i32:
167
+void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
154
case INDEX_op_sub2_i32:
168
+ hwaddr paddr, MemTxAttrs attrs, int prot,
155
- return C_O2_I4(r, r, rZ, rZ, rN, rN);
169
+ int mmu_idx, target_ulong size)
156
+ return C_O2_I4(r, r, rz, rz, rN, rN);
170
+{
157
case INDEX_op_setcond2_i32:
171
+ CPUTLBEntryFull full = {
158
- return C_O1_I4(r, rZ, rZ, rZ, rZ);
172
+ .phys_addr = paddr,
159
+ return C_O1_I4(r, rz, rz, rz, rz);
173
+ .attrs = attrs,
160
case INDEX_op_brcond2_i32:
174
+ .prot = prot,
161
- return C_O0_I4(rZ, rZ, rZ, rZ);
175
+ .lg_page_size = ctz64(size)
162
+ return C_O0_I4(rz, rz, rz, rz);
176
+ };
163
177
+
164
case INDEX_op_qemu_ld_i32:
178
+ assert(is_power_of_2(size));
165
return C_O1_I1(r, r);
179
+ tlb_set_page_full(cpu, mmu_idx, vaddr, &full);
166
case INDEX_op_qemu_st_i32:
180
+}
167
- return C_O0_I2(rZ, r);
181
+
168
+ return C_O0_I2(rz, r);
182
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
169
case INDEX_op_qemu_ld_i64:
183
hwaddr paddr, int prot,
170
return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
184
int mmu_idx, target_ulong size)
171
case INDEX_op_qemu_st_i64:
172
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rZ, r) : C_O0_I3(rZ, rZ, r);
173
+ return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(rz, r) : C_O0_I3(rz, rz, r);
174
175
default:
176
return C_NotImplemented;
185
--
177
--
186
2.34.1
178
2.43.0
187
179
188
180
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Replace target-specific 'Z' with generic 'z'.
2
2
3
Before: 35.912 s ± 0.168 s
3
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>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
5
---
13
accel/tcg/cputlb.c | 15 ++++++---------
6
tcg/riscv/tcg-target-con-set.h | 10 +++++-----
14
1 file changed, 6 insertions(+), 9 deletions(-)
7
tcg/riscv/tcg-target-con-str.h | 1 -
8
tcg/riscv/tcg-target.c.inc | 28 ++++++++++++----------------
9
3 files changed, 17 insertions(+), 22 deletions(-)
15
10
16
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
11
diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/accel/tcg/cputlb.c
13
--- a/tcg/riscv/tcg-target-con-set.h
19
+++ b/accel/tcg/cputlb.c
14
+++ b/tcg/riscv/tcg-target-con-set.h
20
@@ -XXX,XX +XXX,XX @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
15
@@ -XXX,XX +XXX,XX @@
21
static void tlb_fill(CPUState *cpu, target_ulong addr, int size,
16
* tcg-target-con-str.h; the constraint combination is inclusive or.
22
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
17
*/
23
{
18
C_O0_I1(r)
24
- CPUClass *cc = CPU_GET_CLASS(cpu);
19
-C_O0_I2(rZ, r)
25
bool ok;
20
-C_O0_I2(rZ, rZ)
26
21
+C_O0_I2(rz, r)
27
/*
22
+C_O0_I2(rz, rz)
28
* This is not a probe, so only valid return is success; failure
23
C_O1_I1(r, r)
29
* should result in exception + longjmp to the cpu loop.
24
C_O1_I2(r, r, ri)
30
*/
25
C_O1_I2(r, r, rI)
31
- ok = cc->tcg_ops->tlb_fill(cpu, addr, size,
26
C_O1_I2(r, r, rJ)
32
- access_type, mmu_idx, false, retaddr);
27
-C_O1_I2(r, rZ, rN)
33
+ ok = cpu->cc->tcg_ops->tlb_fill(cpu, addr, size,
28
-C_O1_I2(r, rZ, rZ)
34
+ access_type, mmu_idx, false, retaddr);
29
+C_O1_I2(r, rz, rN)
35
assert(ok);
30
+C_O1_I2(r, rz, rz)
31
C_N1_I2(r, r, rM)
32
C_O1_I4(r, r, rI, rM, rM)
33
-C_O2_I4(r, r, rZ, rZ, rM, rM)
34
+C_O2_I4(r, r, rz, rz, rM, rM)
35
C_O0_I2(v, r)
36
C_O1_I1(v, r)
37
C_O1_I1(v, v)
38
diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/tcg/riscv/tcg-target-con-str.h
41
+++ b/tcg/riscv/tcg-target-con-str.h
42
@@ -XXX,XX +XXX,XX @@ CONST('K', TCG_CT_CONST_S5)
43
CONST('L', TCG_CT_CONST_CMP_VI)
44
CONST('N', TCG_CT_CONST_N12)
45
CONST('M', TCG_CT_CONST_M12)
46
-CONST('Z', TCG_CT_CONST_ZERO)
47
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
48
index XXXXXXX..XXXXXXX 100644
49
--- a/tcg/riscv/tcg-target.c.inc
50
+++ b/tcg/riscv/tcg-target.c.inc
51
@@ -XXX,XX +XXX,XX @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
52
return TCG_REG_A0 + slot;
36
}
53
}
37
54
38
@@ -XXX,XX +XXX,XX @@ static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
55
-#define TCG_CT_CONST_ZERO 0x100
39
MMUAccessType access_type,
56
-#define TCG_CT_CONST_S12 0x200
40
int mmu_idx, uintptr_t retaddr)
57
-#define TCG_CT_CONST_N12 0x400
41
{
58
-#define TCG_CT_CONST_M12 0x800
42
- CPUClass *cc = CPU_GET_CLASS(cpu);
59
-#define TCG_CT_CONST_J12 0x1000
43
-
60
-#define TCG_CT_CONST_S5 0x2000
44
- cc->tcg_ops->do_unaligned_access(cpu, addr, access_type, mmu_idx, retaddr);
61
-#define TCG_CT_CONST_CMP_VI 0x4000
45
+ cpu->cc->tcg_ops->do_unaligned_access(cpu, addr, access_type,
62
+#define TCG_CT_CONST_S12 0x100
46
+ mmu_idx, retaddr);
63
+#define TCG_CT_CONST_N12 0x200
47
}
64
+#define TCG_CT_CONST_M12 0x400
48
65
+#define TCG_CT_CONST_J12 0x800
49
static inline void cpu_transaction_failed(CPUState *cpu, hwaddr physaddr,
66
+#define TCG_CT_CONST_S5 0x1000
50
@@ -XXX,XX +XXX,XX @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
67
+#define TCG_CT_CONST_CMP_VI 0x2000
51
if (!tlb_hit_page(tlb_addr, page_addr)) {
68
52
if (!victim_tlb_hit(env, mmu_idx, index, elt_ofs, page_addr)) {
69
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
53
CPUState *cs = env_cpu(env);
70
#define ALL_VECTOR_REGS MAKE_64BIT_MASK(32, 32)
54
- CPUClass *cc = CPU_GET_CLASS(cs);
71
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
55
72
if (ct & TCG_CT_CONST) {
56
- if (!cc->tcg_ops->tlb_fill(cs, addr, fault_size, access_type,
73
return 1;
57
- mmu_idx, nonfault, retaddr)) {
74
}
58
+ if (!cs->cc->tcg_ops->tlb_fill(cs, addr, fault_size, access_type,
75
- if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
59
+ mmu_idx, nonfault, retaddr)) {
76
- return 1;
60
/* Non-faulting page table read failed. */
77
- }
61
*phost = NULL;
78
if (type >= TCG_TYPE_V64) {
62
return TLB_INVALID_MASK;
79
/* Val is replicated by VECE; extract the highest element. */
80
val >>= (-8 << vece) & 63;
81
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
82
case INDEX_op_st16_i64:
83
case INDEX_op_st32_i64:
84
case INDEX_op_st_i64:
85
- return C_O0_I2(rZ, r);
86
+ return C_O0_I2(rz, r);
87
88
case INDEX_op_add_i32:
89
case INDEX_op_and_i32:
90
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
91
92
case INDEX_op_sub_i32:
93
case INDEX_op_sub_i64:
94
- return C_O1_I2(r, rZ, rN);
95
+ return C_O1_I2(r, rz, rN);
96
97
case INDEX_op_mul_i32:
98
case INDEX_op_mulsh_i32:
99
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
100
case INDEX_op_divu_i64:
101
case INDEX_op_rem_i64:
102
case INDEX_op_remu_i64:
103
- return C_O1_I2(r, rZ, rZ);
104
+ return C_O1_I2(r, rz, rz);
105
106
case INDEX_op_shl_i32:
107
case INDEX_op_shr_i32:
108
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
109
110
case INDEX_op_brcond_i32:
111
case INDEX_op_brcond_i64:
112
- return C_O0_I2(rZ, rZ);
113
+ return C_O0_I2(rz, rz);
114
115
case INDEX_op_movcond_i32:
116
case INDEX_op_movcond_i64:
117
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
118
case INDEX_op_add2_i64:
119
case INDEX_op_sub2_i32:
120
case INDEX_op_sub2_i64:
121
- return C_O2_I4(r, r, rZ, rZ, rM, rM);
122
+ return C_O2_I4(r, r, rz, rz, rM, rM);
123
124
case INDEX_op_qemu_ld_i32:
125
case INDEX_op_qemu_ld_i64:
126
return C_O1_I1(r, r);
127
case INDEX_op_qemu_st_i32:
128
case INDEX_op_qemu_st_i64:
129
- return C_O0_I2(rZ, r);
130
+ return C_O0_I2(rz, r);
131
132
case INDEX_op_st_vec:
133
return C_O0_I2(v, r);
63
--
134
--
64
2.34.1
135
2.43.0
65
136
66
137
diff view generated by jsdifflib
1
This field is only written, not read; remove it.
1
Replace target-specific 'Z' with generic 'z'.
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
tcg/sparc64/tcg-target-con-set.h | 12 ++++++------
9
accel/tcg/cputlb.c | 7 +++----
7
tcg/sparc64/tcg-target-con-str.h | 1 -
10
2 files changed, 3 insertions(+), 5 deletions(-)
8
tcg/sparc64/tcg-target.c.inc | 17 +++++++----------
9
3 files changed, 13 insertions(+), 17 deletions(-)
11
10
12
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
11
diff --git a/tcg/sparc64/tcg-target-con-set.h b/tcg/sparc64/tcg-target-con-set.h
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/core/cpu.h
13
--- a/tcg/sparc64/tcg-target-con-set.h
15
+++ b/include/hw/core/cpu.h
14
+++ b/tcg/sparc64/tcg-target-con-set.h
16
@@ -XXX,XX +XXX,XX @@ struct CPUWatchpoint {
15
@@ -XXX,XX +XXX,XX @@
17
* the memory regions get moved around by io_writex.
16
* tcg-target-con-str.h; the constraint combination is inclusive or.
18
*/
17
*/
19
typedef struct SavedIOTLB {
18
C_O0_I1(r)
20
- hwaddr addr;
19
-C_O0_I2(rZ, r)
21
MemoryRegionSection *section;
20
-C_O0_I2(rZ, rJ)
22
hwaddr mr_offset;
21
+C_O0_I2(rz, r)
23
} SavedIOTLB;
22
+C_O0_I2(rz, rJ)
24
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
23
C_O1_I1(r, r)
24
C_O1_I2(r, r, r)
25
-C_O1_I2(r, rZ, rJ)
26
-C_O1_I4(r, rZ, rJ, rI, 0)
27
-C_O2_I2(r, r, rZ, rJ)
28
-C_O2_I4(r, r, rZ, rZ, rJ, rJ)
29
+C_O1_I2(r, rz, rJ)
30
+C_O1_I4(r, rz, rJ, rI, 0)
31
+C_O2_I2(r, r, rz, rJ)
32
+C_O2_I4(r, r, rz, rz, rJ, rJ)
33
diff --git a/tcg/sparc64/tcg-target-con-str.h b/tcg/sparc64/tcg-target-con-str.h
25
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
26
--- a/accel/tcg/cputlb.c
35
--- a/tcg/sparc64/tcg-target-con-str.h
27
+++ b/accel/tcg/cputlb.c
36
+++ b/tcg/sparc64/tcg-target-con-str.h
28
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUTLBEntryFull *full,
37
@@ -XXX,XX +XXX,XX @@ REGS('r', ALL_GENERAL_REGS)
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
*/
38
*/
32
-static void save_iotlb_data(CPUState *cs, hwaddr addr,
39
CONST('I', TCG_CT_CONST_S11)
33
- MemoryRegionSection *section, hwaddr mr_offset)
40
CONST('J', TCG_CT_CONST_S13)
34
+static void save_iotlb_data(CPUState *cs, MemoryRegionSection *section,
41
-CONST('Z', TCG_CT_CONST_ZERO)
35
+ hwaddr mr_offset)
42
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
36
{
43
index XXXXXXX..XXXXXXX 100644
37
#ifdef CONFIG_PLUGIN
44
--- a/tcg/sparc64/tcg-target.c.inc
38
SavedIOTLB *saved = &cs->saved_iotlb;
45
+++ b/tcg/sparc64/tcg-target.c.inc
39
- saved->addr = addr;
46
@@ -XXX,XX +XXX,XX @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
40
saved->section = section;
47
41
saved->mr_offset = mr_offset;
48
#define TCG_CT_CONST_S11 0x100
42
#endif
49
#define TCG_CT_CONST_S13 0x200
43
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUTLBEntryFull *full,
50
-#define TCG_CT_CONST_ZERO 0x400
44
* The memory_region_dispatch may trigger a flush/resize
51
45
* so for plugins we save the iotlb_data just in case.
52
#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32)
46
*/
53
47
- save_iotlb_data(cpu, full->xlat_section, section, mr_offset);
54
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, int ct,
48
+ save_iotlb_data(cpu, section, mr_offset);
55
val = (int32_t)val;
49
56
}
50
if (!qemu_mutex_iothread_locked()) {
57
51
qemu_mutex_lock_iothread();
58
- if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
59
- return 1;
60
- } else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
61
+ if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
62
return 1;
63
} else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
64
return 1;
65
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
66
case INDEX_op_st_i64:
67
case INDEX_op_qemu_st_i32:
68
case INDEX_op_qemu_st_i64:
69
- return C_O0_I2(rZ, r);
70
+ return C_O0_I2(rz, r);
71
72
case INDEX_op_add_i32:
73
case INDEX_op_add_i64:
74
@@ -XXX,XX +XXX,XX @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
75
case INDEX_op_setcond_i64:
76
case INDEX_op_negsetcond_i32:
77
case INDEX_op_negsetcond_i64:
78
- return C_O1_I2(r, rZ, rJ);
79
+ return C_O1_I2(r, rz, rJ);
80
81
case INDEX_op_brcond_i32:
82
case INDEX_op_brcond_i64:
83
- return C_O0_I2(rZ, rJ);
84
+ return C_O0_I2(rz, rJ);
85
case INDEX_op_movcond_i32:
86
case INDEX_op_movcond_i64:
87
- return C_O1_I4(r, rZ, rJ, rI, 0);
88
+ return C_O1_I4(r, rz, rJ, rI, 0);
89
case INDEX_op_add2_i32:
90
case INDEX_op_add2_i64:
91
case INDEX_op_sub2_i32:
92
case INDEX_op_sub2_i64:
93
- return C_O2_I4(r, r, rZ, rZ, rJ, rJ);
94
+ return C_O2_I4(r, r, rz, rz, rJ, rJ);
95
case INDEX_op_mulu2_i32:
96
case INDEX_op_muls2_i32:
97
- return C_O2_I2(r, r, rZ, rJ);
98
+ return C_O2_I2(r, r, rz, rJ);
99
case INDEX_op_muluh_i64:
100
return C_O1_I2(r, r, r);
101
52
--
102
--
53
2.34.1
103
2.43.0
54
104
55
105
diff view generated by jsdifflib
New patch
1
From: Fabiano Rosas <farosas@suse.de>
1
2
3
When complying with the alignment requested in the ELF and unmapping
4
the excess reservation, having align_end not aligned to the guest page
5
causes the unmap to be rejected by the alignment check at
6
target_munmap and later brk adjustments hit an EEXIST.
7
8
Fix by aligning the start of region to be unmapped.
9
10
Fixes: c81d1fafa6 ("linux-user: Honor elf alignment when placing images")
11
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1913
12
Signed-off-by: Fabiano Rosas <farosas@suse.de>
13
[rth: Align load_end as well.]
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-ID: <20250213143558.10504-1-farosas@suse.de>
16
---
17
linux-user/elfload.c | 4 ++--
18
1 file changed, 2 insertions(+), 2 deletions(-)
19
20
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/linux-user/elfload.c
23
+++ b/linux-user/elfload.c
24
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, const ImageSource *src,
25
26
if (align_size != reserve_size) {
27
abi_ulong align_addr = ROUND_UP(load_addr, align);
28
- abi_ulong align_end = align_addr + reserve_size;
29
- abi_ulong load_end = load_addr + align_size;
30
+ abi_ulong align_end = TARGET_PAGE_ALIGN(align_addr + reserve_size);
31
+ abi_ulong load_end = TARGET_PAGE_ALIGN(load_addr + align_size);
32
33
if (align_addr != load_addr) {
34
target_munmap(load_addr, align_addr - load_addr);
35
--
36
2.43.0
diff view generated by jsdifflib
1
Prepare for targets to be able to produce TBs that can
1
From: Andreas Schwab <schwab@suse.de>
2
run in more than one virtual context.
3
2
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
SA_RESTORER and the associated sa_restorer field of struct sigaction are
4
an obsolete feature, not expected to be used by future architectures.
5
They are also absent on RISC-V, LoongArch, Hexagon and OpenRISC, but
6
defined due to their use of generic/signal.h. This leads to corrupted
7
data and out-of-bounds accesses.
8
9
Move the definition of TARGET_SA_RESTORER out of generic/signal.h into the
10
target_signal.h files that need it. Note that m68k has the sa_restorer
11
field, but does not use it and does not define SA_RESTORER.
12
13
Reported-by: Thomas Weißschuh <thomas@t-8ch.de>
14
Signed-off-by: Andreas Schwab <schwab@suse.de>
15
Reviewed-by: Thomas Weißschuh <thomas@t-8ch.de>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-ID: <mvmed060xc9.fsf@suse.de>
6
---
19
---
7
accel/tcg/internal.h | 4 +++
20
linux-user/aarch64/target_signal.h | 2 ++
8
accel/tcg/tb-jmp-cache.h | 41 +++++++++++++++++++++++++
21
linux-user/arm/target_signal.h | 2 ++
9
include/exec/cpu-defs.h | 3 ++
22
linux-user/generic/signal.h | 1 -
10
include/exec/exec-all.h | 32 ++++++++++++++++++--
23
linux-user/i386/target_signal.h | 2 ++
11
accel/tcg/cpu-exec.c | 16 ++++++----
24
linux-user/m68k/target_signal.h | 1 +
12
accel/tcg/translate-all.c | 64 ++++++++++++++++++++++++++-------------
25
linux-user/microblaze/target_signal.h | 2 ++
13
6 files changed, 131 insertions(+), 29 deletions(-)
26
linux-user/ppc/target_signal.h | 2 ++
27
linux-user/s390x/target_signal.h | 2 ++
28
linux-user/sh4/target_signal.h | 2 ++
29
linux-user/x86_64/target_signal.h | 2 ++
30
linux-user/xtensa/target_signal.h | 2 ++
31
11 files changed, 19 insertions(+), 1 deletion(-)
14
32
15
diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
33
diff --git a/linux-user/aarch64/target_signal.h b/linux-user/aarch64/target_signal.h
16
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/tcg/internal.h
35
--- a/linux-user/aarch64/target_signal.h
18
+++ b/accel/tcg/internal.h
36
+++ b/linux-user/aarch64/target_signal.h
19
@@ -XXX,XX +XXX,XX @@ void tb_htable_init(void);
37
@@ -XXX,XX +XXX,XX @@
20
/* Return the current PC from CPU, which may be cached in TB. */
38
21
static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
39
#include "../generic/signal.h"
22
{
40
23
+#if TARGET_TB_PCREL
41
+#define TARGET_SA_RESTORER 0x04000000
24
+ return cpu->cc->get_pc(cpu);
42
+
25
+#else
43
#define TARGET_SEGV_MTEAERR 8 /* Asynchronous ARM MTE error */
26
return tb_pc(tb);
44
#define TARGET_SEGV_MTESERR 9 /* Synchronous ARM MTE exception */
27
+#endif
45
28
}
46
diff --git a/linux-user/arm/target_signal.h b/linux-user/arm/target_signal.h
29
30
#endif /* ACCEL_TCG_INTERNAL_H */
31
diff --git a/accel/tcg/tb-jmp-cache.h b/accel/tcg/tb-jmp-cache.h
32
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
33
--- a/accel/tcg/tb-jmp-cache.h
48
--- a/linux-user/arm/target_signal.h
34
+++ b/accel/tcg/tb-jmp-cache.h
49
+++ b/linux-user/arm/target_signal.h
35
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@
36
51
37
/*
52
#include "../generic/signal.h"
38
* Accessed in parallel; all accesses to 'tb' must be atomic.
53
39
+ * For TARGET_TB_PCREL, accesses to 'pc' must be protected by
54
+#define TARGET_SA_RESTORER 0x04000000
40
+ * a load_acquire/store_release to 'tb'.
41
*/
42
struct CPUJumpCache {
43
struct {
44
TranslationBlock *tb;
45
+#if TARGET_TB_PCREL
46
+ target_ulong pc;
47
+#endif
48
} array[TB_JMP_CACHE_SIZE];
49
};
50
51
+static inline TranslationBlock *
52
+tb_jmp_cache_get_tb(CPUJumpCache *jc, uint32_t hash)
53
+{
54
+#if TARGET_TB_PCREL
55
+ /* Use acquire to ensure current load of pc from jc. */
56
+ return qatomic_load_acquire(&jc->array[hash].tb);
57
+#else
58
+ /* Use rcu_read to ensure current load of pc from *tb. */
59
+ return qatomic_rcu_read(&jc->array[hash].tb);
60
+#endif
61
+}
62
+
55
+
63
+static inline target_ulong
56
#define TARGET_ARCH_HAS_SETUP_FRAME
64
+tb_jmp_cache_get_pc(CPUJumpCache *jc, uint32_t hash, TranslationBlock *tb)
57
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
65
+{
58
66
+#if TARGET_TB_PCREL
59
diff --git a/linux-user/generic/signal.h b/linux-user/generic/signal.h
67
+ return jc->array[hash].pc;
60
index XXXXXXX..XXXXXXX 100644
68
+#else
61
--- a/linux-user/generic/signal.h
69
+ return tb_pc(tb);
62
+++ b/linux-user/generic/signal.h
70
+#endif
63
@@ -XXX,XX +XXX,XX @@
71
+}
64
#define TARGET_SA_RESTART 0x10000000
65
#define TARGET_SA_NODEFER 0x40000000
66
#define TARGET_SA_RESETHAND 0x80000000
67
-#define TARGET_SA_RESTORER 0x04000000
68
69
#define TARGET_SIGHUP 1
70
#define TARGET_SIGINT 2
71
diff --git a/linux-user/i386/target_signal.h b/linux-user/i386/target_signal.h
72
index XXXXXXX..XXXXXXX 100644
73
--- a/linux-user/i386/target_signal.h
74
+++ b/linux-user/i386/target_signal.h
75
@@ -XXX,XX +XXX,XX @@
76
77
#include "../generic/signal.h"
78
79
+#define TARGET_SA_RESTORER 0x04000000
72
+
80
+
73
+static inline void
81
#define TARGET_ARCH_HAS_SETUP_FRAME
74
+tb_jmp_cache_set(CPUJumpCache *jc, uint32_t hash,
82
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
75
+ TranslationBlock *tb, target_ulong pc)
83
76
+{
84
diff --git a/linux-user/m68k/target_signal.h b/linux-user/m68k/target_signal.h
77
+#if TARGET_TB_PCREL
85
index XXXXXXX..XXXXXXX 100644
78
+ jc->array[hash].pc = pc;
86
--- a/linux-user/m68k/target_signal.h
79
+ /* Use store_release on tb to ensure pc is written first. */
87
+++ b/linux-user/m68k/target_signal.h
80
+ qatomic_store_release(&jc->array[hash].tb, tb);
88
@@ -XXX,XX +XXX,XX @@
81
+#else
89
82
+ /* Use the pc value already stored in tb->pc. */
90
#include "../generic/signal.h"
83
+ qatomic_set(&jc->array[hash].tb, tb);
91
84
+#endif
92
+#define TARGET_ARCH_HAS_SA_RESTORER 1
85
+}
93
#define TARGET_ARCH_HAS_SETUP_FRAME
94
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
95
96
diff --git a/linux-user/microblaze/target_signal.h b/linux-user/microblaze/target_signal.h
97
index XXXXXXX..XXXXXXX 100644
98
--- a/linux-user/microblaze/target_signal.h
99
+++ b/linux-user/microblaze/target_signal.h
100
@@ -XXX,XX +XXX,XX @@
101
102
#include "../generic/signal.h"
103
104
+#define TARGET_SA_RESTORER 0x04000000
86
+
105
+
87
#endif /* ACCEL_TCG_TB_JMP_CACHE_H */
106
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
88
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
107
108
#endif /* MICROBLAZE_TARGET_SIGNAL_H */
109
diff --git a/linux-user/ppc/target_signal.h b/linux-user/ppc/target_signal.h
89
index XXXXXXX..XXXXXXX 100644
110
index XXXXXXX..XXXXXXX 100644
90
--- a/include/exec/cpu-defs.h
111
--- a/linux-user/ppc/target_signal.h
91
+++ b/include/exec/cpu-defs.h
112
+++ b/linux-user/ppc/target_signal.h
92
@@ -XXX,XX +XXX,XX @@
113
@@ -XXX,XX +XXX,XX @@
93
# error TARGET_PAGE_BITS must be defined in cpu-param.h
114
94
# endif
115
#include "../generic/signal.h"
116
117
+#define TARGET_SA_RESTORER 0x04000000
118
+
119
#if !defined(TARGET_PPC64)
120
#define TARGET_ARCH_HAS_SETUP_FRAME
95
#endif
121
#endif
96
+#ifndef TARGET_TB_PCREL
122
diff --git a/linux-user/s390x/target_signal.h b/linux-user/s390x/target_signal.h
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
123
index XXXXXXX..XXXXXXX 100644
104
--- a/include/exec/exec-all.h
124
--- a/linux-user/s390x/target_signal.h
105
+++ b/include/exec/exec-all.h
125
+++ b/linux-user/s390x/target_signal.h
106
@@ -XXX,XX +XXX,XX @@ struct tb_tc {
126
@@ -XXX,XX +XXX,XX @@
107
};
127
108
128
#include "../generic/signal.h"
109
struct TranslationBlock {
129
110
- target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */
130
+#define TARGET_SA_RESTORER 0x04000000
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
+
131
+
129
+ /*
132
#define TARGET_ARCH_HAS_SETUP_FRAME
130
+ * Target-specific data associated with the TranslationBlock, e.g.:
133
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
131
+ * x86: the original user, the Code Segment virtual base,
134
132
+ * arm: an extension of tb->flags,
135
diff --git a/linux-user/sh4/target_signal.h b/linux-user/sh4/target_signal.h
133
+ * s390x: instruction data for EXECUTE,
136
index XXXXXXX..XXXXXXX 100644
134
+ * sparc: the next pc of the instruction queue (for delay slots).
137
--- a/linux-user/sh4/target_signal.h
135
+ */
138
+++ b/linux-user/sh4/target_signal.h
136
+ target_ulong cs_base;
139
@@ -XXX,XX +XXX,XX @@
140
141
#include "../generic/signal.h"
142
143
+#define TARGET_SA_RESTORER 0x04000000
137
+
144
+
138
uint32_t flags; /* flags defining in which context the code was generated */
145
#define TARGET_ARCH_HAS_SETUP_FRAME
139
uint32_t cflags; /* compile flags */
146
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
140
147
141
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock {
148
diff --git a/linux-user/x86_64/target_signal.h b/linux-user/x86_64/target_signal.h
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
154
index XXXXXXX..XXXXXXX 100644
149
index XXXXXXX..XXXXXXX 100644
155
--- a/accel/tcg/cpu-exec.c
150
--- a/linux-user/x86_64/target_signal.h
156
+++ b/accel/tcg/cpu-exec.c
151
+++ b/linux-user/x86_64/target_signal.h
157
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
152
@@ -XXX,XX +XXX,XX @@
158
const TranslationBlock *tb = p;
153
159
const struct tb_desc *desc = d;
154
#include "../generic/signal.h"
160
155
161
- if (tb_pc(tb) == desc->pc &&
156
+#define TARGET_SA_RESTORER 0x04000000
162
+ if ((TARGET_TB_PCREL || tb_pc(tb) == desc->pc) &&
157
+
163
tb->page_addr[0] == desc->page_addr0 &&
158
/* For x86_64, use of SA_RESTORER is mandatory. */
164
tb->cs_base == desc->cs_base &&
159
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
165
tb->flags == desc->flags &&
160
166
@@ -XXX,XX +XXX,XX @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
161
diff --git a/linux-user/xtensa/target_signal.h b/linux-user/xtensa/target_signal.h
167
return NULL;
168
}
169
desc.page_addr0 = phys_pc;
170
- h = tb_hash_func(phys_pc, pc, flags, cflags, *cpu->trace_dstate);
171
+ h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : pc),
172
+ flags, cflags, *cpu->trace_dstate);
173
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
174
}
175
176
@@ -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
186
hash = tb_jmp_cache_hash_func(pc);
187
- tb = qatomic_rcu_read(&cpu->tb_jmp_cache->array[hash].tb);
188
+ jc = cpu->tb_jmp_cache;
189
+ tb = tb_jmp_cache_get_tb(jc, hash);
190
191
if (likely(tb &&
192
- tb->pc == 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)
207
if (cc->tcg_ops->synchronize_from_tb) {
208
cc->tcg_ops->synchronize_from_tb(cpu, last_tb);
209
} else {
210
+ assert(!TARGET_TB_PCREL);
211
assert(cc->set_pc);
212
cc->set_pc(cpu, tb_pc(last_tb));
213
}
214
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
215
* for the fast lookup
216
*/
217
h = tb_jmp_cache_hash_func(pc);
218
- qatomic_set(&cpu->tb_jmp_cache->array[h].tb, tb);
219
+ tb_jmp_cache_set(cpu->tb_jmp_cache, h, tb, pc);
220
}
221
222
#ifndef CONFIG_USER_ONLY
223
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
224
index XXXXXXX..XXXXXXX 100644
162
index XXXXXXX..XXXXXXX 100644
225
--- a/accel/tcg/translate-all.c
163
--- a/linux-user/xtensa/target_signal.h
226
+++ b/accel/tcg/translate-all.c
164
+++ b/linux-user/xtensa/target_signal.h
227
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
165
@@ -XXX,XX +XXX,XX @@
228
166
229
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) {
167
#include "../generic/signal.h"
230
if (i == 0) {
168
231
- prev = (j == 0 ? tb_pc(tb) : 0);
169
+#define TARGET_SA_RESTORER 0x04000000
232
+ prev = (!TARGET_TB_PCREL && j == 0 ? tb_pc(tb) : 0);
233
} else {
234
prev = tcg_ctx->gen_insn_data[i - 1][j];
235
}
236
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
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
}
248
249
+ memset(data, 0, sizeof(data));
250
+ if (!TARGET_TB_PCREL) {
251
+ data[0] = tb_pc(tb);
252
+ }
253
+
170
+
254
/* Reconstruct the stored insn data while looking for the point at
171
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
255
which the end of the insn exceeds the searched_pc. */
172
256
for (i = 0; i < num_insns; ++i) {
173
#endif
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
}
326
@@ -XXX,XX +XXX,XX @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
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,
353
354
gen_code_buf = tcg_ctx->code_gen_ptr;
355
tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf);
356
+#if !TARGET_TB_PCREL
357
tb->pc = pc;
358
+#endif
359
tb->cs_base = cs_base;
360
tb->flags = flags;
361
tb->cflags = cflags;
362
--
174
--
363
2.34.1
175
2.43.0
364
176
365
177
diff view generated by jsdifflib
New patch
1
From: Mikael Szreder <git@miszr.win>
1
2
3
A bug was introduced in commit 0bba7572d40d which causes the fdtox
4
and fqtox instructions to incorrectly select the destination registers.
5
More information and a test program can be found in issue #2802.
6
7
Cc: qemu-stable@nongnu.org
8
Fixes: 0bba7572d40d ("target/sparc: Perform DFPREG/QFPREG in decodetree")
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2802
10
Signed-off-by: Mikael Szreder <git@miszr.win>
11
Acked-by: Artyom Tarasenko <atar4qemu@gmail.com>
12
[rth: Squash patches together, since the second fixes a typo in the first.]
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-ID: <20250205090333.19626-3-git@miszr.win>
15
---
16
target/sparc/insns.decode | 12 ++++++------
17
1 file changed, 6 insertions(+), 6 deletions(-)
18
19
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/sparc/insns.decode
22
+++ b/target/sparc/insns.decode
23
@@ -XXX,XX +XXX,XX @@ FdMULq 10 ..... 110100 ..... 0 0110 1110 ..... @q_d_d
24
FNHADDs 10 ..... 110100 ..... 0 0111 0001 ..... @r_r_r
25
FNHADDd 10 ..... 110100 ..... 0 0111 0010 ..... @d_d_d
26
FNsMULd 10 ..... 110100 ..... 0 0111 1001 ..... @d_r_r
27
-FsTOx 10 ..... 110100 00000 0 1000 0001 ..... @r_r2
28
-FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @r_d2
29
-FqTOx 10 ..... 110100 00000 0 1000 0011 ..... @r_q2
30
-FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_r2
31
-FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @d_r2
32
-FxTOq 10 ..... 110100 00000 0 1000 1100 ..... @q_r2
33
+FsTOx 10 ..... 110100 00000 0 1000 0001 ..... @d_r2
34
+FdTOx 10 ..... 110100 00000 0 1000 0010 ..... @d_d2
35
+FqTOx 10 ..... 110100 00000 0 1000 0011 ..... @d_q2
36
+FxTOs 10 ..... 110100 00000 0 1000 0100 ..... @r_d2
37
+FxTOd 10 ..... 110100 00000 0 1000 1000 ..... @d_d2
38
+FxTOq 10 ..... 110100 00000 0 1000 1100 ..... @q_d2
39
FiTOs 10 ..... 110100 00000 0 1100 0100 ..... @r_r2
40
FdTOs 10 ..... 110100 00000 0 1100 0110 ..... @r_d2
41
FqTOs 10 ..... 110100 00000 0 1100 0111 ..... @r_q2
42
--
43
2.43.0
diff view generated by jsdifflib
New patch
1
From: Mikael Szreder <git@miszr.win>
1
2
3
The gdbstub implementation for the Sparc architecture would
4
incorrectly calculate the the floating point register offset.
5
This resulted in, for example, registers f32 and f34 to point to
6
the same value.
7
8
The issue was caused by the confusion between even register numbers
9
and even register indexes. For example, the register index of f32 is 64
10
and f34 is 65.
11
12
Cc: qemu-stable@nongnu.org
13
Fixes: 30038fd81808 ("target-sparc: Change fpr representation to doubles.")
14
Signed-off-by: Mikael Szreder <git@miszr.win>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-ID: <20250214070343.11501-1-git@miszr.win>
18
---
19
target/sparc/gdbstub.c | 18 ++++++++++++++----
20
1 file changed, 14 insertions(+), 4 deletions(-)
21
22
diff --git a/target/sparc/gdbstub.c b/target/sparc/gdbstub.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/sparc/gdbstub.c
25
+++ b/target/sparc/gdbstub.c
26
@@ -XXX,XX +XXX,XX @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
27
}
28
}
29
if (n < 80) {
30
- /* f32-f62 (double width, even numbers only) */
31
- return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
32
+ /* f32-f62 (16 double width registers, even register numbers only)
33
+ * n == 64: f32 : env->fpr[16]
34
+ * n == 65: f34 : env->fpr[17]
35
+ * etc...
36
+ * n == 79: f62 : env->fpr[31]
37
+ */
38
+ return gdb_get_reg64(mem_buf, env->fpr[(n - 64) + 16].ll);
39
}
40
switch (n) {
41
case 80:
42
@@ -XXX,XX +XXX,XX @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
43
}
44
return 4;
45
} else if (n < 80) {
46
- /* f32-f62 (double width, even numbers only) */
47
- env->fpr[(n - 32) / 2].ll = tmp;
48
+ /* f32-f62 (16 double width registers, even register numbers only)
49
+ * n == 64: f32 : env->fpr[16]
50
+ * n == 65: f34 : env->fpr[17]
51
+ * etc...
52
+ * n == 79: f62 : env->fpr[31]
53
+ */
54
+ env->fpr[(n - 64) + 16].ll = tmp;
55
} else {
56
switch (n) {
57
case 80:
58
--
59
2.43.0
diff view generated by jsdifflib
New patch
1
From: Artyom Tarasenko <atar4qemu@gmail.com>
1
2
3
Fake access to
4
PCR Performance Control Register
5
and
6
PIC Performance Instrumentation Counter.
7
8
Ignore writes in privileged mode, and return 0 on reads.
9
10
This allows booting Tribblix, MilaX and v9os under Niagara target.
11
12
Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-ID: <20250209211248.50383-1-atar4qemu@gmail.com>
16
---
17
target/sparc/translate.c | 19 +++++++++++++++++++
18
target/sparc/insns.decode | 7 ++++++-
19
2 files changed, 25 insertions(+), 1 deletion(-)
20
21
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/sparc/translate.c
24
+++ b/target/sparc/translate.c
25
@@ -XXX,XX +XXX,XX @@ static TCGv do_rd_leon3_config(DisasContext *dc, TCGv dst)
26
27
TRANS(RDASR17, ASR17, do_rd_special, true, a->rd, do_rd_leon3_config)
28
29
+static TCGv do_rdpic(DisasContext *dc, TCGv dst)
30
+{
31
+ return tcg_constant_tl(0);
32
+}
33
+
34
+TRANS(RDPIC, HYPV, do_rd_special, supervisor(dc), a->rd, do_rdpic)
35
+
36
+
37
static TCGv do_rdccr(DisasContext *dc, TCGv dst)
38
{
39
gen_helper_rdccr(dst, tcg_env);
40
@@ -XXX,XX +XXX,XX @@ static void do_wrfprs(DisasContext *dc, TCGv src)
41
42
TRANS(WRFPRS, 64, do_wr_special, a, true, do_wrfprs)
43
44
+static bool do_priv_nop(DisasContext *dc, bool priv)
45
+{
46
+ if (!priv) {
47
+ return raise_priv(dc);
48
+ }
49
+ return advance_pc(dc);
50
+}
51
+
52
+TRANS(WRPCR, HYPV, do_priv_nop, supervisor(dc))
53
+TRANS(WRPIC, HYPV, do_priv_nop, supervisor(dc))
54
+
55
static void do_wrgsr(DisasContext *dc, TCGv src)
56
{
57
gen_trap_ifnofpu(dc);
58
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/sparc/insns.decode
61
+++ b/target/sparc/insns.decode
62
@@ -XXX,XX +XXX,XX @@ CALL 01 i:s30
63
RDTICK 10 rd:5 101000 00100 0 0000000000000
64
RDPC 10 rd:5 101000 00101 0 0000000000000
65
RDFPRS 10 rd:5 101000 00110 0 0000000000000
66
- RDASR17 10 rd:5 101000 10001 0 0000000000000
67
+ {
68
+ RDASR17 10 rd:5 101000 10001 0 0000000000000
69
+ RDPIC 10 rd:5 101000 10001 0 0000000000000
70
+ }
71
RDGSR 10 rd:5 101000 10011 0 0000000000000
72
RDSOFTINT 10 rd:5 101000 10110 0 0000000000000
73
RDTICK_CMPR 10 rd:5 101000 10111 0 0000000000000
74
@@ -XXX,XX +XXX,XX @@ CALL 01 i:s30
75
WRCCR 10 00010 110000 ..... . ............. @n_r_ri
76
WRASI 10 00011 110000 ..... . ............. @n_r_ri
77
WRFPRS 10 00110 110000 ..... . ............. @n_r_ri
78
+ WRPCR 10 10000 110000 01000 0 0000000000000
79
+ WRPIC 10 10001 110000 01000 0 0000000000000
80
{
81
WRGSR 10 10011 110000 ..... . ............. @n_r_ri
82
WRPOWERDOWN 10 10011 110000 ..... . ............. @n_r_ri
83
--
84
2.43.0
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Eliminate code repetition by using the appropriate helpers.
2
2
3
The class cast checkers are quite expensive and always on (unlike the
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
dynamic case who's checks are gated by CONFIG_QOM_CAST_DEBUG). To
5
avoid the overhead of repeatedly checking something which should never
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>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
---
5
---
15
include/hw/core/cpu.h | 9 +++++++++
6
tcg/i386/tcg-target.c.inc | 65 +++++----------------------------------
16
cpu.c | 9 ++++-----
7
1 file changed, 8 insertions(+), 57 deletions(-)
17
2 files changed, 13 insertions(+), 5 deletions(-)
18
8
19
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
9
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
20
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/core/cpu.h
11
--- a/tcg/i386/tcg-target.c.inc
22
+++ b/include/hw/core/cpu.h
12
+++ b/tcg/i386/tcg-target.c.inc
23
@@ -XXX,XX +XXX,XX @@ typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
13
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
24
*/
14
tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
25
#define CPU(obj) ((CPUState *)(obj))
15
label_this, small);
26
16
break;
27
+/*
17
+
28
+ * The class checkers bring in CPU_GET_CLASS() which is potentially
18
case TCG_COND_NE:
29
+ * expensive given the eventual call to
19
case TCG_COND_TSTNE:
30
+ * object_class_dynamic_cast_assert(). Because of this the CPUState
20
tcg_out_brcond(s, 0, cond, args[0], args[2], const_args[2],
31
+ * has a cached value for the class in cs->cc which is set up in
21
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
32
+ * cpu_exec_realizefn() for use in hot code paths.
22
tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
33
+ */
23
label_this, small);
34
typedef struct CPUClass CPUClass;
24
break;
35
DECLARE_CLASS_CHECKERS(CPUClass, CPU,
25
- case TCG_COND_LT:
36
TYPE_CPU)
26
- tcg_out_brcond(s, 0, TCG_COND_LT, args[1], args[3], const_args[3],
37
@@ -XXX,XX +XXX,XX @@ struct qemu_work_item;
27
- label_this, small);
38
struct CPUState {
28
- tcg_out_jxx(s, JCC_JNE, label_next, 1);
39
/*< private >*/
29
- tcg_out_brcond(s, 0, TCG_COND_LTU, args[0], args[2], const_args[2],
40
DeviceState parent_obj;
30
- label_this, small);
41
+ /* cache to avoid expensive CPU_GET_CLASS */
31
- break;
42
+ CPUClass *cc;
32
- case TCG_COND_LE:
43
/*< public >*/
33
- tcg_out_brcond(s, 0, TCG_COND_LT, args[1], args[3], const_args[3],
44
34
- label_this, small);
45
int nr_cores;
35
- tcg_out_jxx(s, JCC_JNE, label_next, 1);
46
diff --git a/cpu.c b/cpu.c
36
- tcg_out_brcond(s, 0, TCG_COND_LEU, args[0], args[2], const_args[2],
47
index XXXXXXX..XXXXXXX 100644
37
- label_this, small);
48
--- a/cpu.c
38
- break;
49
+++ b/cpu.c
39
- case TCG_COND_GT:
50
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_cpu_common = {
40
- tcg_out_brcond(s, 0, TCG_COND_GT, args[1], args[3], const_args[3],
51
41
- label_this, small);
52
void cpu_exec_realizefn(CPUState *cpu, Error **errp)
42
- tcg_out_jxx(s, JCC_JNE, label_next, 1);
53
{
43
- tcg_out_brcond(s, 0, TCG_COND_GTU, args[0], args[2], const_args[2],
54
-#ifndef CONFIG_USER_ONLY
44
- label_this, small);
55
- CPUClass *cc = CPU_GET_CLASS(cpu);
45
- break;
56
-#endif
46
- case TCG_COND_GE:
57
+ /* cache the cpu class for the hotpath */
47
- tcg_out_brcond(s, 0, TCG_COND_GT, args[1], args[3], const_args[3],
58
+ cpu->cc = CPU_GET_CLASS(cpu);
48
- label_this, small);
59
49
- tcg_out_jxx(s, JCC_JNE, label_next, 1);
60
cpu_list_add(cpu);
50
- tcg_out_brcond(s, 0, TCG_COND_GEU, args[0], args[2], const_args[2],
61
if (!accel_cpu_realizefn(cpu, errp)) {
51
- label_this, small);
62
@@ -XXX,XX +XXX,XX @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
52
- break;
63
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
53
- case TCG_COND_LTU:
64
vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
54
- tcg_out_brcond(s, 0, TCG_COND_LTU, args[1], args[3], const_args[3],
55
- label_this, small);
56
- tcg_out_jxx(s, JCC_JNE, label_next, 1);
57
- tcg_out_brcond(s, 0, TCG_COND_LTU, args[0], args[2], const_args[2],
58
- label_this, small);
59
- break;
60
- case TCG_COND_LEU:
61
- tcg_out_brcond(s, 0, TCG_COND_LTU, args[1], args[3], const_args[3],
62
- label_this, small);
63
- tcg_out_jxx(s, JCC_JNE, label_next, 1);
64
- tcg_out_brcond(s, 0, TCG_COND_LEU, args[0], args[2], const_args[2],
65
- label_this, small);
66
- break;
67
- case TCG_COND_GTU:
68
- tcg_out_brcond(s, 0, TCG_COND_GTU, args[1], args[3], const_args[3],
69
- label_this, small);
70
- tcg_out_jxx(s, JCC_JNE, label_next, 1);
71
- tcg_out_brcond(s, 0, TCG_COND_GTU, args[0], args[2], const_args[2],
72
- label_this, small);
73
- break;
74
- case TCG_COND_GEU:
75
- tcg_out_brcond(s, 0, TCG_COND_GTU, args[1], args[3], const_args[3],
76
- label_this, small);
77
- tcg_out_jxx(s, JCC_JNE, label_next, 1);
78
- tcg_out_brcond(s, 0, TCG_COND_GEU, args[0], args[2], const_args[2],
79
- label_this, small);
80
- break;
81
+
82
default:
83
- g_assert_not_reached();
84
+ tcg_out_brcond(s, 0, tcg_high_cond(cond), args[1],
85
+ args[3], const_args[3], label_this, small);
86
+ tcg_out_jxx(s, JCC_JNE, label_next, 1);
87
+ tcg_out_brcond(s, 0, tcg_unsigned_cond(cond), args[0],
88
+ args[2], const_args[2], label_this, small);
89
+ break;
65
}
90
}
66
- if (cc->sysemu_ops->legacy_vmsd != NULL) {
91
tcg_out_label(s, label_next);
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
}
92
}
73
--
93
--
74
2.34.1
94
2.43.0
75
95
76
96
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
These defines never should have been added as they were
2
never used. Only 32-bit hosts may have these opcodes and
3
they have them unconditionally.
2
4
3
This is a heavily used function so lets avoid the cost of
5
Fixes: 6cb14e4de29 ("tcg/loongarch64: Add the tcg-target.h file")
4
CPU_GET_CLASS. On the romulus-bmc run it has a modest effect:
6
Fixes: fb1f70f3685 ("tcg/riscv: Add the tcg-target.h file")
5
7
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
Before: 36.812 s ± 0.506 s
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
---
10
---
16
hw/core/cpu-sysemu.c | 5 ++---
11
tcg/loongarch64/tcg-target-has.h | 2 --
17
1 file changed, 2 insertions(+), 3 deletions(-)
12
tcg/riscv/tcg-target-has.h | 2 --
13
2 files changed, 4 deletions(-)
18
14
19
diff --git a/hw/core/cpu-sysemu.c b/hw/core/cpu-sysemu.c
15
diff --git a/tcg/loongarch64/tcg-target-has.h b/tcg/loongarch64/tcg-target-has.h
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/core/cpu-sysemu.c
17
--- a/tcg/loongarch64/tcg-target-has.h
22
+++ b/hw/core/cpu-sysemu.c
18
+++ b/tcg/loongarch64/tcg-target-has.h
23
@@ -XXX,XX +XXX,XX @@ hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr)
19
@@ -XXX,XX +XXX,XX @@
24
20
#define TCG_TARGET_HAS_clz_i32 1
25
int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs)
21
#define TCG_TARGET_HAS_ctz_i32 1
26
{
22
#define TCG_TARGET_HAS_ctpop_i32 0
27
- CPUClass *cc = CPU_GET_CLASS(cpu);
23
-#define TCG_TARGET_HAS_brcond2 0
28
int ret = 0;
24
-#define TCG_TARGET_HAS_setcond2 0
29
25
#define TCG_TARGET_HAS_qemu_st8_i32 0
30
- if (cc->sysemu_ops->asidx_from_attrs) {
26
31
- ret = cc->sysemu_ops->asidx_from_attrs(cpu, attrs);
27
/* 64-bit operations */
32
+ if (cpu->cc->sysemu_ops->asidx_from_attrs) {
28
diff --git a/tcg/riscv/tcg-target-has.h b/tcg/riscv/tcg-target-has.h
33
+ ret = cpu->cc->sysemu_ops->asidx_from_attrs(cpu, attrs);
29
index XXXXXXX..XXXXXXX 100644
34
assert(ret < cpu->num_ases && ret >= 0);
30
--- a/tcg/riscv/tcg-target-has.h
35
}
31
+++ b/tcg/riscv/tcg-target-has.h
36
return ret;
32
@@ -XXX,XX +XXX,XX @@
33
#define TCG_TARGET_HAS_clz_i32 (cpuinfo & CPUINFO_ZBB)
34
#define TCG_TARGET_HAS_ctz_i32 (cpuinfo & CPUINFO_ZBB)
35
#define TCG_TARGET_HAS_ctpop_i32 (cpuinfo & CPUINFO_ZBB)
36
-#define TCG_TARGET_HAS_brcond2 1
37
-#define TCG_TARGET_HAS_setcond2 1
38
#define TCG_TARGET_HAS_qemu_st8_i32 0
39
40
#define TCG_TARGET_HAS_negsetcond_i64 1
37
--
41
--
38
2.34.1
42
2.43.0
39
43
40
44
diff view generated by jsdifflib