1
The following changes since commit ff56877e911782dedc9a424233fd3f62369c258c:
1
Merge the first set of reviewed patches from my queue.
2
2
3
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20181015-pull-request' into staging (2018-10-15 15:03:45 +0100)
3
r~
4
5
The following changes since commit 6dd06214892d71cbbdd25daed7693e58afcb1093:
6
7
Merge tag 'pull-hex-20230421' of https://github.com/quic/qemu into staging (2023-04-22 08:31:38 +0100)
4
8
5
are available in the Git repository at:
9
are available in the Git repository at:
6
10
7
https://github.com/rth7680/qemu.git tags/pull-tcg-20181016
11
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20230423
8
12
9
for you to fetch changes up to e3e9d1ea20c75718ce7c528c588a0a497f12f750:
13
for you to fetch changes up to 3ea9be33400f14305565a9a094cb6031c07183d5:
10
14
11
cputlb: read CPUTLBEntry.addr_write atomically (2018-10-16 10:04:27 -0700)
15
tcg/riscv: Conditionalize tcg_out_exts_i32_i64 (2023-04-23 08:46:45 +0100)
12
16
13
----------------------------------------------------------------
17
----------------------------------------------------------------
14
Queued tcg patches
18
tcg cleanups:
19
- Remove tcg_abort()
20
- Split out extensions as known backend interfaces
21
- Put the separate extensions together as tcg_out_movext
22
- Introduce tcg_out_xchg as a backend interface
23
- Clear TCGLabelQemuLdst on allocation
24
- Avoid redundant extensions for riscv
15
25
16
----------------------------------------------------------------
26
----------------------------------------------------------------
17
Emilio G. Cota (10):
27
Richard Henderson (15):
18
tcg: access cpu->icount_decr.u16.high with atomics
28
tcg: Replace if + tcg_abort with tcg_debug_assert
19
tcg: fix use of uninitialized variable under CONFIG_PROFILER
29
tcg: Replace tcg_abort with g_assert_not_reached
20
tcg: plug holes in struct TCGProfile
30
tcg: Split out tcg_out_ext8s
21
tcg: distribute tcg_time into TCG contexts
31
tcg: Split out tcg_out_ext8u
22
target/alpha: remove tlb_flush from alpha_cpu_initfn
32
tcg: Split out tcg_out_ext16s
23
target/unicore32: remove tlb_flush from uc32_init_fn
33
tcg: Split out tcg_out_ext16u
24
exec: introduce tlb_init
34
tcg: Split out tcg_out_ext32s
25
cputlb: fix assert_cpu_is_self macro
35
tcg: Split out tcg_out_ext32u
26
cputlb: serialize tlb updates with env->tlb_lock
36
tcg: Split out tcg_out_exts_i32_i64
27
cputlb: read CPUTLBEntry.addr_write atomically
37
tcg: Split out tcg_out_extu_i32_i64
38
tcg: Split out tcg_out_extrl_i64_i32
39
tcg: Introduce tcg_out_movext
40
tcg: Introduce tcg_out_xchg
41
tcg: Clear TCGLabelQemuLdst on allocation
42
tcg/riscv: Conditionalize tcg_out_exts_i32_i64
28
43
29
Richard Henderson (11):
44
include/tcg/tcg.h | 6 --
30
tcg: Implement CPU_LOG_TB_NOCHAIN during expansion
45
target/i386/tcg/translate.c | 20 +++---
31
tcg: Add tlb_index and tlb_entry helpers
46
target/s390x/tcg/translate.c | 4 +-
32
tcg: Split CONFIG_ATOMIC128
47
tcg/optimize.c | 10 ++-
33
target/i386: Convert to HAVE_CMPXCHG128
48
tcg/tcg.c | 135 +++++++++++++++++++++++++++++++++++----
34
target/arm: Convert to HAVE_CMPXCHG128
49
tcg/aarch64/tcg-target.c.inc | 106 +++++++++++++++++++-----------
35
target/arm: Check HAVE_CMPXCHG128 at translate time
50
tcg/arm/tcg-target.c.inc | 93 +++++++++++++++++----------
36
target/ppc: Convert to HAVE_CMPXCHG128 and HAVE_ATOMIC128
51
tcg/i386/tcg-target.c.inc | 129 ++++++++++++++++++-------------------
37
target/s390x: Convert to HAVE_CMPXCHG128 and HAVE_ATOMIC128
52
tcg/loongarch64/tcg-target.c.inc | 123 +++++++++++++----------------------
38
target/s390x: Split do_cdsg, do_lpq, do_stpq
53
tcg/mips/tcg-target.c.inc | 94 +++++++++++++++++++--------
39
target/s390x: Skip wout, cout helpers if op helper does not return
54
tcg/ppc/tcg-target.c.inc | 119 ++++++++++++++++++----------------
40
target/s390x: Check HAVE_ATOMIC128 and HAVE_CMPXCHG128 at translate
55
tcg/riscv/tcg-target.c.inc | 83 +++++++++++-------------
41
56
tcg/s390x/tcg-target.c.inc | 128 +++++++++++++++++--------------------
42
accel/tcg/atomic_template.h | 20 +++-
57
tcg/sparc64/tcg-target.c.inc | 117 +++++++++++++++++++++------------
43
accel/tcg/softmmu_template.h | 64 +++++-----
58
tcg/tcg-ldst.c.inc | 1 +
44
include/exec/cpu-defs.h | 3 +
59
tcg/tci/tcg-target.c.inc | 116 ++++++++++++++++++++++++++++++---
45
include/exec/cpu_ldst.h | 30 ++++-
60
16 files changed, 786 insertions(+), 498 deletions(-)
46
include/exec/cpu_ldst_template.h | 25 ++--
47
include/exec/exec-all.h | 8 ++
48
include/qemu/atomic128.h | 155 ++++++++++++++++++++++++
49
include/qemu/timer.h | 1 -
50
target/ppc/helper.h | 2 +-
51
tcg/tcg.h | 20 ++--
52
accel/tcg/cpu-exec.c | 2 +-
53
accel/tcg/cputlb.c | 235 +++++++++++++++++++-----------------
54
accel/tcg/tcg-all.c | 2 +-
55
accel/tcg/translate-all.c | 2 +-
56
accel/tcg/user-exec.c | 5 +-
57
cpus.c | 3 +-
58
exec.c | 1 +
59
monitor.c | 13 +-
60
qom/cpu.c | 2 +-
61
target/alpha/cpu.c | 1 -
62
target/arm/helper-a64.c | 251 +++++++++++++++++++--------------------
63
target/arm/translate-a64.c | 38 +++---
64
target/i386/mem_helper.c | 9 +-
65
target/ppc/mem_helper.c | 33 ++++-
66
target/ppc/translate.c | 115 +++++++++---------
67
target/s390x/mem_helper.c | 202 +++++++++++++++----------------
68
target/s390x/translate.c | 45 +++++--
69
target/unicore32/cpu.c | 2 -
70
tcg/tcg-op.c | 9 +-
71
tcg/tcg.c | 25 +++-
72
configure | 19 +++
73
31 files changed, 830 insertions(+), 512 deletions(-)
74
create mode 100644 include/qemu/atomic128.h
75
diff view generated by jsdifflib
1
Reviewed-by: David Hildenbrand <david@redhat.com>
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
3
---
4
target/s390x/mem_helper.c | 92 +++++++++++++++++----------------------
4
tcg/tcg.c | 4 +---
5
1 file changed, 41 insertions(+), 51 deletions(-)
5
tcg/i386/tcg-target.c.inc | 8 +++-----
6
2 files changed, 4 insertions(+), 8 deletions(-)
6
7
7
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
8
diff --git a/tcg/tcg.c b/tcg/tcg.c
8
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
9
--- a/target/s390x/mem_helper.c
10
--- a/tcg/tcg.c
10
+++ b/target/s390x/mem_helper.c
11
+++ b/tcg/tcg.c
11
@@ -XXX,XX +XXX,XX @@
12
@@ -XXX,XX +XXX,XX @@ static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
12
#include "exec/exec-all.h"
13
#include "exec/cpu_ldst.h"
14
#include "qemu/int128.h"
15
+#include "qemu/atomic128.h"
16
17
#if !defined(CONFIG_USER_ONLY)
18
#include "hw/s390x/storage-keys.h"
19
@@ -XXX,XX +XXX,XX @@ static void do_cdsg(CPUS390XState *env, uint64_t addr,
20
bool fail;
21
22
if (parallel) {
23
-#ifndef CONFIG_ATOMIC128
24
+#if !HAVE_CMPXCHG128
25
cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
26
#else
27
int mem_idx = cpu_mmu_index(env, false);
28
@@ -XXX,XX +XXX,XX @@ void HELPER(cdsg_parallel)(CPUS390XState *env, uint64_t addr,
29
static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
30
uint64_t a2, bool parallel)
31
{
13
{
32
-#if !defined(CONFIG_USER_ONLY) || defined(CONFIG_ATOMIC128)
14
TCGTemp *ts;
33
uint32_t mem_idx = cpu_mmu_index(env, false);
15
34
-#endif
16
- if (TCG_TARGET_REG_BITS == 32 && type != TCG_TYPE_I32) {
35
uintptr_t ra = GETPC();
17
- tcg_abort();
36
uint32_t fc = extract32(env->regs[0], 0, 8);
18
- }
37
uint32_t sc = extract32(env->regs[0], 8, 8);
19
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
38
@@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
20
39
probe_write(env, a2, 0, mem_idx, ra);
21
ts = tcg_global_alloc(s);
40
#endif
22
ts->base_type = type;
41
23
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
42
- /* Note that the compare-and-swap is atomic, and the store is atomic, but
24
index XXXXXXX..XXXXXXX 100644
43
- the complete operation is not. Therefore we do not need to assert serial
25
--- a/tcg/i386/tcg-target.c.inc
44
- context in order to implement this. That said, restart early if we can't
26
+++ b/tcg/i386/tcg-target.c.inc
45
- support either operation that is supposed to be atomic. */
27
@@ -XXX,XX +XXX,XX @@ static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
46
+ /*
47
+ * Note that the compare-and-swap is atomic, and the store is atomic,
48
+ * but the complete operation is not. Therefore we do not need to
49
+ * assert serial context in order to implement this. That said,
50
+ * restart early if we can't support either operation that is supposed
51
+ * to be atomic.
52
+ */
53
if (parallel) {
54
- int mask = 0;
55
-#if !defined(CONFIG_ATOMIC64)
56
- mask = -8;
57
-#elif !defined(CONFIG_ATOMIC128)
58
- mask = -16;
59
+ uint32_t max = 2;
60
+#ifdef CONFIG_ATOMIC64
61
+ max = 3;
62
#endif
63
- if (((4 << fc) | (1 << sc)) & mask) {
64
+ if ((HAVE_CMPXCHG128 ? 0 : fc + 2 > max) ||
65
+ (HAVE_ATOMIC128 ? 0 : sc > max)) {
66
cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
67
}
68
}
69
@@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
70
Int128 cv = int128_make128(env->regs[r3 + 1], env->regs[r3]);
71
Int128 ov;
72
73
- if (parallel) {
74
-#ifdef CONFIG_ATOMIC128
75
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
76
- ov = helper_atomic_cmpxchgo_be_mmu(env, a1, cv, nv, oi, ra);
77
- cc = !int128_eq(ov, cv);
78
-#else
79
- /* Note that we asserted !parallel above. */
80
- g_assert_not_reached();
81
-#endif
82
- } else {
83
+ if (!parallel) {
84
uint64_t oh = cpu_ldq_data_ra(env, a1 + 0, ra);
85
uint64_t ol = cpu_ldq_data_ra(env, a1 + 8, ra);
86
87
@@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
88
89
cpu_stq_data_ra(env, a1 + 0, int128_gethi(nv), ra);
90
cpu_stq_data_ra(env, a1 + 8, int128_getlo(nv), ra);
91
+ } else if (HAVE_CMPXCHG128) {
92
+ TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
93
+ ov = helper_atomic_cmpxchgo_be_mmu(env, a1, cv, nv, oi, ra);
94
+ cc = !int128_eq(ov, cv);
95
+ } else {
96
+ /* Note that we asserted !parallel above. */
97
+ g_assert_not_reached();
98
}
99
100
env->regs[r3 + 0] = int128_gethi(ov);
101
@@ -XXX,XX +XXX,XX @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
102
cpu_stq_data_ra(env, a2, svh, ra);
103
break;
104
case 4:
105
- if (parallel) {
106
-#ifdef CONFIG_ATOMIC128
107
+ if (!parallel) {
108
+ cpu_stq_data_ra(env, a2 + 0, svh, ra);
109
+ cpu_stq_data_ra(env, a2 + 8, svl, ra);
110
+ } else if (HAVE_ATOMIC128) {
111
TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
112
Int128 sv = int128_make128(svl, svh);
113
helper_atomic_sto_be_mmu(env, a2, sv, oi, ra);
114
-#else
115
+ } else {
116
/* Note that we asserted !parallel above. */
117
g_assert_not_reached();
118
-#endif
119
- } else {
120
- cpu_stq_data_ra(env, a2 + 0, svh, ra);
121
- cpu_stq_data_ra(env, a2 + 8, svl, ra);
122
}
123
break;
124
default:
125
@@ -XXX,XX +XXX,XX @@ static uint64_t do_lpq(CPUS390XState *env, uint64_t addr, bool parallel)
126
uintptr_t ra = GETPC();
127
uint64_t hi, lo;
128
129
- if (parallel) {
130
-#ifndef CONFIG_ATOMIC128
131
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
132
-#else
133
+ if (!parallel) {
134
+ check_alignment(env, addr, 16, ra);
135
+ hi = cpu_ldq_data_ra(env, addr + 0, ra);
136
+ lo = cpu_ldq_data_ra(env, addr + 8, ra);
137
+ } else if (HAVE_ATOMIC128) {
138
int mem_idx = cpu_mmu_index(env, false);
139
TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
140
Int128 v = helper_atomic_ldo_be_mmu(env, addr, oi, ra);
141
hi = int128_gethi(v);
142
lo = int128_getlo(v);
143
-#endif
144
} else {
145
- check_alignment(env, addr, 16, ra);
146
-
147
- hi = cpu_ldq_data_ra(env, addr + 0, ra);
148
- lo = cpu_ldq_data_ra(env, addr + 8, ra);
149
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
150
}
151
152
env->retxl = lo;
153
@@ -XXX,XX +XXX,XX @@ static void do_stpq(CPUS390XState *env, uint64_t addr,
154
{
155
uintptr_t ra = GETPC();
156
157
- if (parallel) {
158
-#ifndef CONFIG_ATOMIC128
159
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
160
-#else
161
- int mem_idx = cpu_mmu_index(env, false);
162
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
163
-
164
- Int128 v = int128_make128(low, high);
165
- helper_atomic_sto_be_mmu(env, addr, v, oi, ra);
166
-#endif
167
- } else {
168
+ if (!parallel) {
169
check_alignment(env, addr, 16, ra);
170
-
171
cpu_stq_data_ra(env, addr + 0, high, ra);
172
cpu_stq_data_ra(env, addr + 8, low, ra);
173
+ } else if (HAVE_ATOMIC128) {
174
+ int mem_idx = cpu_mmu_index(env, false);
175
+ TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
176
+ Int128 v = int128_make128(low, high);
177
+ helper_atomic_sto_be_mmu(env, addr, v, oi, ra);
178
+ } else {
179
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
180
}
28
}
181
}
29
}
182
30
31
-/* Use SMALL != 0 to force a short forward branch. */
32
-static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, int small)
33
+/* Set SMALL to force a short forward branch. */
34
+static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, bool small)
35
{
36
int32_t val, val1;
37
38
@@ -XXX,XX +XXX,XX @@ static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, int small)
39
}
40
tcg_out8(s, val1);
41
} else {
42
- if (small) {
43
- tcg_abort();
44
- }
45
+ tcg_debug_assert(!small);
46
if (opc == -1) {
47
tcg_out8(s, OPC_JMP_long);
48
tcg_out32(s, val - 5);
183
--
49
--
184
2.17.2
50
2.34.1
185
51
186
52
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
3
When we implemented per-vCPU TCG contexts, we forgot to also
4
distribute the tcg_time counter, which has remained as a global
5
accessed without any serialization, leading to potentially missed
6
counts.
7
8
Fix it by distributing the field over the TCG contexts, embedding
9
it into TCGProfile with a field called "cpu_exec_time", which is more
10
descriptive than "tcg_time". Add a function to query this value
11
directly, and for completeness, fill in the field in
12
tcg_profile_snapshot, even though its callers do not use it.
13
14
Signed-off-by: Emilio G. Cota <cota@braap.org>
15
Message-Id: <20181010144853.13005-5-cota@braap.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
---
3
---
18
include/qemu/timer.h | 1 -
4
include/tcg/tcg.h | 6 ------
19
tcg/tcg.h | 2 ++
5
target/i386/tcg/translate.c | 20 ++++++++++----------
20
cpus.c | 3 ++-
6
target/s390x/tcg/translate.c | 4 ++--
21
monitor.c | 13 ++++++++++---
7
tcg/optimize.c | 10 ++++------
22
tcg/tcg.c | 23 +++++++++++++++++++++++
8
tcg/tcg.c | 8 ++++----
23
5 files changed, 37 insertions(+), 5 deletions(-)
9
tcg/aarch64/tcg-target.c.inc | 4 ++--
10
tcg/arm/tcg-target.c.inc | 2 +-
11
tcg/i386/tcg-target.c.inc | 14 +++++++-------
12
tcg/mips/tcg-target.c.inc | 14 +++++++-------
13
tcg/ppc/tcg-target.c.inc | 8 ++++----
14
tcg/s390x/tcg-target.c.inc | 8 ++++----
15
tcg/sparc64/tcg-target.c.inc | 2 +-
16
tcg/tci/tcg-target.c.inc | 2 +-
17
13 files changed, 47 insertions(+), 55 deletions(-)
24
18
25
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
19
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
26
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
27
--- a/include/qemu/timer.h
21
--- a/include/tcg/tcg.h
28
+++ b/include/qemu/timer.h
22
+++ b/include/tcg/tcg.h
29
@@ -XXX,XX +XXX,XX @@ static inline int64_t profile_getclock(void)
23
@@ -XXX,XX +XXX,XX @@ typedef struct TCGTargetOpDef {
30
return get_clock();
24
const char *args_ct_str[TCG_MAX_OP_ARGS];
31
}
25
} TCGTargetOpDef;
32
26
33
-extern int64_t tcg_time;
27
-#define tcg_abort() \
34
extern int64_t dev_time;
28
-do {\
29
- fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
30
- abort();\
31
-} while (0)
32
-
33
bool tcg_op_supported(TCGOpcode op);
34
35
void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
36
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/i386/tcg/translate.c
39
+++ b/target/i386/tcg/translate.c
40
@@ -XXX,XX +XXX,XX @@ static TCGv gen_op_deposit_reg_v(DisasContext *s, MemOp ot, int reg, TCGv dest,
41
break;
35
#endif
42
#endif
36
43
default:
37
diff --git a/tcg/tcg.h b/tcg/tcg.h
44
- tcg_abort();
38
index XXXXXXX..XXXXXXX 100644
45
+ g_assert_not_reached();
39
--- a/tcg/tcg.h
46
}
40
+++ b/tcg/tcg.h
47
return cpu_regs[reg];
41
@@ -XXX,XX +XXX,XX @@ typedef struct TCGOp {
48
}
42
QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8));
49
@@ -XXX,XX +XXX,XX @@ static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0,
43
50
}
44
typedef struct TCGProfile {
51
break;
45
+ int64_t cpu_exec_time;
52
default:
46
int64_t tb_count1;
53
- tcg_abort();
47
int64_t tb_count;
54
+ g_assert_not_reached();
48
int64_t op_count; /* total insn count */
55
}
49
@@ -XXX,XX +XXX,XX @@ int tcg_check_temp_count(void);
56
50
#define tcg_check_temp_count() 0
57
if (ovr_seg >= 0) {
58
@@ -XXX,XX +XXX,XX @@ static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n)
59
gen_helper_inl(v, cpu_env, n);
60
break;
61
default:
62
- tcg_abort();
63
+ g_assert_not_reached();
64
}
65
}
66
67
@@ -XXX,XX +XXX,XX @@ static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n)
68
gen_helper_outl(cpu_env, v, n);
69
break;
70
default:
71
- tcg_abort();
72
+ g_assert_not_reached();
73
}
74
}
75
76
@@ -XXX,XX +XXX,XX @@ static void gen_rotc_rm_T1(DisasContext *s, MemOp ot, int op1,
77
break;
51
#endif
78
#endif
52
79
default:
53
+int64_t tcg_cpu_exec_time(void);
80
- tcg_abort();
54
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
81
+ g_assert_not_reached();
55
void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf);
82
}
56
83
} else {
57
diff --git a/cpus.c b/cpus.c
84
switch (ot) {
58
index XXXXXXX..XXXXXXX 100644
85
@@ -XXX,XX +XXX,XX @@ static void gen_rotc_rm_T1(DisasContext *s, MemOp ot, int op1,
59
--- a/cpus.c
86
break;
60
+++ b/cpus.c
61
@@ -XXX,XX +XXX,XX @@ static int tcg_cpu_exec(CPUState *cpu)
62
ret = cpu_exec(cpu);
63
cpu_exec_end(cpu);
64
#ifdef CONFIG_PROFILER
65
- tcg_time += profile_getclock() - ti;
66
+ atomic_set(&tcg_ctx->prof.cpu_exec_time,
67
+ tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti);
68
#endif
87
#endif
88
default:
89
- tcg_abort();
90
+ g_assert_not_reached();
91
}
92
}
93
/* store */
94
@@ -XXX,XX +XXX,XX @@ static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
95
break;
96
97
default:
98
- tcg_abort();
99
+ g_assert_not_reached();
100
}
101
102
done:
103
@@ -XXX,XX +XXX,XX @@ static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot)
104
ret = x86_ldl_code(env, s);
105
break;
106
default:
107
- tcg_abort();
108
+ g_assert_not_reached();
109
}
69
return ret;
110
return ret;
70
}
111
}
71
diff --git a/monitor.c b/monitor.c
112
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
72
index XXXXXXX..XXXXXXX 100644
113
gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
73
--- a/monitor.c
114
break;
74
+++ b/monitor.c
115
default:
75
@@ -XXX,XX +XXX,XX @@
116
- tcg_abort();
76
#include "sysemu/cpus.h"
117
+ g_assert_not_reached();
77
#include "sysemu/iothread.h"
118
}
78
#include "qemu/cutils.h"
119
break;
79
+#include "tcg/tcg.h"
120
case 0x99: /* CDQ/CWD */
80
121
@@ -XXX,XX +XXX,XX @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
81
#if defined(TARGET_S390X)
122
gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
82
#include "hw/s390x/storage-keys.h"
123
break;
83
@@ -XXX,XX +XXX,XX @@ static void hmp_info_numa(Monitor *mon, const QDict *qdict)
124
default:
84
125
- tcg_abort();
85
#ifdef CONFIG_PROFILER
126
+ g_assert_not_reached();
86
127
}
87
-int64_t tcg_time;
128
break;
88
int64_t dev_time;
129
case 0x1af: /* imul Gv, Ev */
89
130
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
90
static void hmp_info_profile(Monitor *mon, const QDict *qdict)
131
index XXXXXXX..XXXXXXX 100644
91
{
132
--- a/target/s390x/tcg/translate.c
92
+ static int64_t last_cpu_exec_time;
133
+++ b/target/s390x/tcg/translate.c
93
+ int64_t cpu_exec_time;
134
@@ -XXX,XX +XXX,XX @@ static int get_mem_index(DisasContext *s)
94
+ int64_t delta;
135
case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
95
+
136
return MMU_HOME_IDX;
96
+ cpu_exec_time = tcg_cpu_exec_time();
137
default:
97
+ delta = cpu_exec_time - last_cpu_exec_time;
138
- tcg_abort();
98
+
139
+ g_assert_not_reached();
99
monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n",
140
break;
100
dev_time, dev_time / (double)NANOSECONDS_PER_SECOND);
141
}
101
monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n",
142
#endif
102
- tcg_time, tcg_time / (double)NANOSECONDS_PER_SECOND);
143
@@ -XXX,XX +XXX,XX @@ static void gen_op_calc_cc(DisasContext *s)
103
- tcg_time = 0;
144
gen_helper_calc_cc(cc_op, cpu_env, cc_op, cc_src, cc_dst, cc_vr);
104
+ delta, delta / (double)NANOSECONDS_PER_SECOND);
145
break;
105
+ last_cpu_exec_time = cpu_exec_time;
146
default:
106
dev_time = 0;
147
- tcg_abort();
107
}
148
+ g_assert_not_reached();
108
#else
149
}
150
151
/* We now have cc in cc_op as constant */
152
diff --git a/tcg/optimize.c b/tcg/optimize.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/tcg/optimize.c
155
+++ b/tcg/optimize.c
156
@@ -XXX,XX +XXX,XX @@ static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y)
157
return (uint64_t)x % ((uint64_t)y ? : 1);
158
159
default:
160
- fprintf(stderr,
161
- "Unrecognized operation %d in do_constant_folding.\n", op);
162
- tcg_abort();
163
+ g_assert_not_reached();
164
}
165
}
166
167
@@ -XXX,XX +XXX,XX @@ static bool do_constant_folding_cond_32(uint32_t x, uint32_t y, TCGCond c)
168
case TCG_COND_GTU:
169
return x > y;
170
default:
171
- tcg_abort();
172
+ g_assert_not_reached();
173
}
174
}
175
176
@@ -XXX,XX +XXX,XX @@ static bool do_constant_folding_cond_64(uint64_t x, uint64_t y, TCGCond c)
177
case TCG_COND_GTU:
178
return x > y;
179
default:
180
- tcg_abort();
181
+ g_assert_not_reached();
182
}
183
}
184
185
@@ -XXX,XX +XXX,XX @@ static bool do_constant_folding_cond_eq(TCGCond c)
186
case TCG_COND_EQ:
187
return 1;
188
default:
189
- tcg_abort();
190
+ g_assert_not_reached();
191
}
192
}
193
109
diff --git a/tcg/tcg.c b/tcg/tcg.c
194
diff --git a/tcg/tcg.c b/tcg/tcg.c
110
index XXXXXXX..XXXXXXX 100644
195
index XXXXXXX..XXXXXXX 100644
111
--- a/tcg/tcg.c
196
--- a/tcg/tcg.c
112
+++ b/tcg/tcg.c
197
+++ b/tcg/tcg.c
113
@@ -XXX,XX +XXX,XX @@
198
@@ -XXX,XX +XXX,XX @@ static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs,
114
/* Define to jump the ELF file used to communicate with GDB. */
199
115
#undef DEBUG_JIT
200
case TEMP_VAL_DEAD:
116
201
default:
117
+#include "qemu/error-report.h"
202
- tcg_abort();
118
#include "qemu/cutils.h"
203
+ g_assert_not_reached();
119
#include "qemu/host-utils.h"
204
}
120
#include "qemu/timer.h"
205
ts->mem_coherent = 1;
121
@@ -XXX,XX +XXX,XX @@ void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table)
206
}
122
const TCGProfile *orig = &s->prof;
207
@@ -XXX,XX +XXX,XX @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet required_regs,
123
208
}
124
if (counters) {
209
}
125
+ PROF_ADD(prof, orig, cpu_exec_time);
210
126
PROF_ADD(prof, orig, tb_count1);
211
- tcg_abort();
127
PROF_ADD(prof, orig, tb_count);
212
+ g_assert_not_reached();
128
PROF_ADD(prof, orig, op_count);
213
}
129
@@ -XXX,XX +XXX,XX @@ void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
214
130
prof.table_op_count[i]);
215
static TCGReg tcg_reg_alloc_pair(TCGContext *s, TCGRegSet required_regs,
131
}
216
@@ -XXX,XX +XXX,XX @@ static TCGReg tcg_reg_alloc_pair(TCGContext *s, TCGRegSet required_regs,
132
}
217
}
133
+
218
}
134
+int64_t tcg_cpu_exec_time(void)
219
}
135
+{
220
- tcg_abort();
136
+ unsigned int n_ctxs = atomic_read(&n_tcg_ctxs);
221
+ g_assert_not_reached();
137
+ unsigned int i;
222
}
138
+ int64_t ret = 0;
223
139
+
224
/* Make sure the temporary is in a register. If needed, allocate the register
140
+ for (i = 0; i < n_ctxs; i++) {
225
@@ -XXX,XX +XXX,XX @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
141
+ const TCGContext *s = atomic_read(&tcg_ctxs[i]);
226
break;
142
+ const TCGProfile *prof = &s->prof;
227
case TEMP_VAL_DEAD:
143
+
228
default:
144
+ ret += atomic_read(&prof->cpu_exec_time);
229
- tcg_abort();
145
+ }
230
+ g_assert_not_reached();
146
+ return ret;
231
}
147
+}
232
set_temp_val_reg(s, ts, reg);
148
#else
233
}
149
void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
234
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
150
{
235
index XXXXXXX..XXXXXXX 100644
151
cpu_fprintf(f, "[TCG profiler not compiled]\n");
236
--- a/tcg/aarch64/tcg-target.c.inc
152
}
237
+++ b/tcg/aarch64/tcg-target.c.inc
153
+
238
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp memop, TCGType ext,
154
+int64_t tcg_cpu_exec_time(void)
239
tcg_out_ldst_r(s, I3312_LDRX, data_r, addr_r, otype, off_r);
155
+{
240
break;
156
+ error_report("%s: TCG profiler not compiled", __func__);
241
default:
157
+ exit(EXIT_FAILURE);
242
- tcg_abort();
158
+}
243
+ g_assert_not_reached();
159
#endif
244
}
160
245
}
246
247
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp memop,
248
tcg_out_ldst_r(s, I3312_STRX, data_r, addr_r, otype, off_r);
249
break;
250
default:
251
- tcg_abort();
252
+ g_assert_not_reached();
253
}
254
}
255
256
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
257
index XXXXXXX..XXXXXXX 100644
258
--- a/tcg/arm/tcg-target.c.inc
259
+++ b/tcg/arm/tcg-target.c.inc
260
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
261
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
262
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
263
default:
264
- tcg_abort();
265
+ g_assert_not_reached();
266
}
267
}
268
269
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
270
index XXXXXXX..XXXXXXX 100644
271
--- a/tcg/i386/tcg-target.c.inc
272
+++ b/tcg/i386/tcg-target.c.inc
273
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
274
tcg_patch8(code_ptr, value);
275
break;
276
default:
277
- tcg_abort();
278
+ g_assert_not_reached();
279
}
280
return true;
281
}
282
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
283
tcg_out_opc(s, OPC_PUSH_Iv, 0, 0, 0);
284
tcg_out32(s, val);
285
} else {
286
- tcg_abort();
287
+ g_assert_not_reached();
288
}
289
}
290
291
@@ -XXX,XX +XXX,XX @@ static void tgen_arithi(TCGContext *s, int c, int r0,
292
return;
293
}
294
295
- tcg_abort();
296
+ g_assert_not_reached();
297
}
298
299
static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
300
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
301
label_this, small);
302
break;
303
default:
304
- tcg_abort();
305
+ g_assert_not_reached();
306
}
307
tcg_out_label(s, label_next);
308
}
309
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
310
}
311
break;
312
default:
313
- tcg_abort();
314
+ g_assert_not_reached();
315
}
316
317
/* Jump to the code corresponding to next IR of qemu_st */
318
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
319
/* load bits 0..15 */
320
tcg_out_modrm(s, OPC_MOVL_EvGv | P_DATA16, a2, a0);
321
} else {
322
- tcg_abort();
323
+ g_assert_not_reached();
324
}
325
break;
326
327
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
328
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
329
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
330
default:
331
- tcg_abort();
332
+ g_assert_not_reached();
333
}
334
335
#undef OP_32_64
336
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
337
index XXXXXXX..XXXXXXX 100644
338
--- a/tcg/mips/tcg-target.c.inc
339
+++ b/tcg/mips/tcg-target.c.inc
340
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
341
break;
342
343
default:
344
- tcg_abort();
345
+ g_assert_not_reached();
346
break;
347
}
348
}
349
@@ -XXX,XX +XXX,XX @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
350
break;
351
352
default:
353
- tcg_abort();
354
+ g_assert_not_reached();
355
break;
356
}
357
358
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
359
}
360
break;
361
default:
362
- tcg_abort();
363
+ g_assert_not_reached();
364
}
365
i = tcg_out_call_iarg_imm(s, i, oi);
366
367
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi,
368
}
369
break;
370
default:
371
- tcg_abort();
372
+ g_assert_not_reached();
373
}
374
}
375
376
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg lo, TCGReg hi,
377
break;
378
379
default:
380
- tcg_abort();
381
+ g_assert_not_reached();
382
}
383
}
384
385
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_unalign(TCGContext *s, TCGReg lo, TCGReg hi,
386
break;
387
388
default:
389
- tcg_abort();
390
+ g_assert_not_reached();
391
}
392
}
393
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
394
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
395
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
396
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
397
default:
398
- tcg_abort();
399
+ g_assert_not_reached();
400
}
401
}
402
403
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
404
index XXXXXXX..XXXXXXX 100644
405
--- a/tcg/ppc/tcg-target.c.inc
406
+++ b/tcg/ppc/tcg-target.c.inc
407
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
408
break;
409
410
default:
411
- tcg_abort();
412
+ g_assert_not_reached();
413
}
414
op |= BF(cr) | ((type == TCG_TYPE_I64) << 21);
415
416
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
417
break;
418
419
default:
420
- tcg_abort();
421
+ g_assert_not_reached();
422
}
423
}
424
425
@@ -XXX,XX +XXX,XX @@ static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
426
break;
427
428
default:
429
- tcg_abort();
430
+ g_assert_not_reached();
431
}
432
}
433
434
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
435
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
436
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
437
default:
438
- tcg_abort();
439
+ g_assert_not_reached();
440
}
441
}
442
443
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
444
index XXXXXXX..XXXXXXX 100644
445
--- a/tcg/s390x/tcg-target.c.inc
446
+++ b/tcg/s390x/tcg-target.c.inc
447
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
448
break;
449
450
default:
451
- tcg_abort();
452
+ g_assert_not_reached();
453
}
454
}
455
456
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg data,
457
break;
458
459
default:
460
- tcg_abort();
461
+ g_assert_not_reached();
462
}
463
}
464
465
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
466
tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
467
break;
468
default:
469
- tcg_abort();
470
+ g_assert_not_reached();
471
}
472
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi);
473
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr);
474
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
475
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
476
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
477
default:
478
- tcg_abort();
479
+ g_assert_not_reached();
480
}
481
}
482
483
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
484
index XXXXXXX..XXXXXXX 100644
485
--- a/tcg/sparc64/tcg-target.c.inc
486
+++ b/tcg/sparc64/tcg-target.c.inc
487
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
488
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
489
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
490
default:
491
- tcg_abort();
492
+ g_assert_not_reached();
493
}
494
}
495
496
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
497
index XXXXXXX..XXXXXXX 100644
498
--- a/tcg/tci/tcg-target.c.inc
499
+++ b/tcg/tci/tcg-target.c.inc
500
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
501
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
502
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
503
default:
504
- tcg_abort();
505
+ g_assert_not_reached();
506
}
507
}
161
508
162
--
509
--
163
2.17.2
510
2.34.1
164
511
165
512
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
We will need a backend interface for performing 8-bit sign-extend.
2
Use it in tcg_reg_alloc_op in the meantime.
2
3
3
Updates can come from other threads, so readers that do not
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
take tlb_lock must use atomic_read to avoid undefined
5
behaviour (UB).
6
7
This completes the conversion to tlb_lock. This conversion results
8
on average in no performance loss, as the following experiments
9
(run on an Intel i7-6700K CPU @ 4.00GHz) show.
10
11
1. aarch64 bootup+shutdown test:
12
13
- Before:
14
Performance counter stats for 'taskset -c 0 ../img/aarch64/die.sh' (10 runs):
15
16
7487.087786 task-clock (msec) # 0.998 CPUs utilized ( +- 0.12% )
17
31,574,905,303 cycles # 4.217 GHz ( +- 0.12% )
18
57,097,908,812 instructions # 1.81 insns per cycle ( +- 0.08% )
19
10,255,415,367 branches # 1369.747 M/sec ( +- 0.08% )
20
173,278,962 branch-misses # 1.69% of all branches ( +- 0.18% )
21
22
7.504481349 seconds time elapsed ( +- 0.14% )
23
24
- After:
25
Performance counter stats for 'taskset -c 0 ../img/aarch64/die.sh' (10 runs):
26
27
7462.441328 task-clock (msec) # 0.998 CPUs utilized ( +- 0.07% )
28
31,478,476,520 cycles # 4.218 GHz ( +- 0.07% )
29
57,017,330,084 instructions # 1.81 insns per cycle ( +- 0.05% )
30
10,251,929,667 branches # 1373.804 M/sec ( +- 0.05% )
31
173,023,787 branch-misses # 1.69% of all branches ( +- 0.11% )
32
33
7.474970463 seconds time elapsed ( +- 0.07% )
34
35
2. SPEC06int:
36
SPEC06int (test set)
37
[Y axis: Speedup over master]
38
1.15 +-+----+------+------+------+------+------+-------+------+------+------+------+------+------+----+-+
39
| |
40
1.1 +-+.................................+++.............................+ tlb-lock-v2 (m+++x) +-+
41
| +++ | +++ tlb-lock-v3 (spinl|ck) |
42
| +++ | | +++ +++ | | |
43
1.05 +-+....+++...........####.........|####.+++.|......|.....###....+++...........+++....###.........+-+
44
| ### ++#| # |# |# ***### +++### +++#+# | +++ | #|# ### |
45
1 +-+++***+#++++####+++#++#++++++++++#++#+*+*++#++++#+#+****+#++++###++++###++++###++++#+#++++#+#+++-+
46
| *+* # #++# *** # #### *** # * *++# ****+# *| * # ****|# |# # #|# #+# # # |
47
0.95 +-+..*.*.#....#..#.*|*..#...#..#.*|*..#.*.*..#.*|.*.#.*++*.#.*++*+#.****.#....#+#....#.#..++#.#..+-+
48
| * * # # # *|* # # # *|* # * * # *++* # * * # * * # * |* # ++# # # # *** # |
49
| * * # ++# # *+* # # # *|* # * * # * * # * * # * * # *++* # **** # ++# # * * # |
50
0.9 +-+..*.*.#...|#..#.*.*..#.++#..#.*|*..#.*.*..#.*..*.#.*..*.#.*..*.#.*..*.#.*.|*.#...|#.#..*.*.#..+-+
51
| * * # *** # * * # |# # *+* # * * # * * # * * # * * # * * # *++* # |# # * * # |
52
0.85 +-+..*.*.#..*|*..#.*.*..#.***..#.*.*..#.*.*..#.*..*.#.*..*.#.*..*.#.*..*.#.*..*.#.****.#..*.*.#..+-+
53
| * * # *+* # * * # *|* # * * # * * # * * # * * # * * # * * # * * # * |* # * * # |
54
| * * # * * # * * # *+* # * * # * * # * * # * * # * * # * * # * * # * |* # * * # |
55
0.8 +-+..*.*.#..*.*..#.*.*..#.*.*..#.*.*..#.*.*..#.*..*.#.*..*.#.*..*.#.*..*.#.*..*.#.*++*.#..*.*.#..+-+
56
| * * # * * # * * # * * # * * # * * # * * # * * # * * # * * # * * # * * # * * # |
57
0.75 +-+--***##--***###-***###-***###-***###-***###-****##-****##-****##-****##-****##-****##--***##--+-+
58
400.perlben401.bzip2403.gcc429.m445.gob456.hmme45462.libqua464.h26471.omnet473483.xalancbmkgeomean
59
60
png: https://imgur.com/a/BHzpPTW
61
62
Notes:
63
- tlb-lock-v2 corresponds to an implementation with a mutex.
64
- tlb-lock-v3 corresponds to the current implementation, i.e.
65
a spinlock and a single lock acquisition in tlb_set_page_with_attrs.
66
67
Signed-off-by: Emilio G. Cota <cota@braap.org>
68
Message-Id: <20181016153840.25877-1-cota@braap.org>
69
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
70
---
6
---
71
accel/tcg/softmmu_template.h | 12 ++++++------
7
tcg/tcg.c | 21 ++++++++++++++++-----
72
include/exec/cpu_ldst.h | 11 ++++++++++-
8
tcg/aarch64/tcg-target.c.inc | 11 +++++++----
73
include/exec/cpu_ldst_template.h | 2 +-
9
tcg/arm/tcg-target.c.inc | 10 ++++------
74
accel/tcg/cputlb.c | 19 +++++++++++++------
10
tcg/i386/tcg-target.c.inc | 10 +++++-----
75
4 files changed, 30 insertions(+), 14 deletions(-)
11
tcg/loongarch64/tcg-target.c.inc | 11 ++++-------
12
tcg/mips/tcg-target.c.inc | 12 ++++++++----
13
tcg/ppc/tcg-target.c.inc | 10 ++++------
14
tcg/riscv/tcg-target.c.inc | 9 +++------
15
tcg/s390x/tcg-target.c.inc | 10 +++-------
16
tcg/sparc64/tcg-target.c.inc | 7 +++++++
17
tcg/tci/tcg-target.c.inc | 21 ++++++++++++++++++++-
18
11 files changed, 81 insertions(+), 51 deletions(-)
76
19
77
diff --git a/accel/tcg/softmmu_template.h b/accel/tcg/softmmu_template.h
20
diff --git a/tcg/tcg.c b/tcg/tcg.c
78
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
79
--- a/accel/tcg/softmmu_template.h
22
--- a/tcg/tcg.c
80
+++ b/accel/tcg/softmmu_template.h
23
+++ b/tcg/tcg.c
81
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
82
uintptr_t mmu_idx = get_mmuidx(oi);
25
static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
83
uintptr_t index = tlb_index(env, mmu_idx, addr);
26
static void tcg_out_movi(TCGContext *s, TCGType type,
84
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
27
TCGReg ret, tcg_target_long arg);
85
- target_ulong tlb_addr = entry->addr_write;
28
+static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
86
+ target_ulong tlb_addr = tlb_addr_write(entry);
29
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
87
unsigned a_bits = get_alignment_bits(get_memop(oi));
30
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
88
uintptr_t haddr;
31
static void tcg_out_goto_tb(TCGContext *s, int which);
89
32
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
90
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
33
}
91
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
34
92
mmu_idx, retaddr);
35
/* emit instruction */
93
}
36
- if (def->flags & TCG_OPF_VECTOR) {
94
- tlb_addr = entry->addr_write & ~TLB_INVALID_MASK;
37
- tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
95
+ tlb_addr = tlb_addr_write(entry) & ~TLB_INVALID_MASK;
38
- new_args, const_args);
96
}
39
- } else {
97
40
- tcg_out_op(s, op->opc, new_args, const_args);
98
/* Handle an IO access. */
41
+ switch (op->opc) {
99
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
42
+ case INDEX_op_ext8s_i32:
100
cannot evict the first. */
43
+ tcg_out_ext8s(s, TCG_TYPE_I32, new_args[0], new_args[1]);
101
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
44
+ break;
102
entry2 = tlb_entry(env, mmu_idx, page2);
45
+ case INDEX_op_ext8s_i64:
103
- if (!tlb_hit_page(entry2->addr_write, page2)
46
+ tcg_out_ext8s(s, TCG_TYPE_I64, new_args[0], new_args[1]);
104
+ if (!tlb_hit_page(tlb_addr_write(entry2), page2)
47
+ break;
105
&& !VICTIM_TLB_HIT(addr_write, page2)) {
48
+ default:
106
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
49
+ if (def->flags & TCG_OPF_VECTOR) {
107
mmu_idx, retaddr);
50
+ tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
108
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
51
+ new_args, const_args);
109
uintptr_t mmu_idx = get_mmuidx(oi);
52
+ } else {
110
uintptr_t index = tlb_index(env, mmu_idx, addr);
53
+ tcg_out_op(s, op->opc, new_args, const_args);
111
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
54
+ }
112
- target_ulong tlb_addr = entry->addr_write;
55
+ break;
113
+ target_ulong tlb_addr = tlb_addr_write(entry);
56
}
114
unsigned a_bits = get_alignment_bits(get_memop(oi));
57
115
uintptr_t haddr;
58
/* move the outputs in the correct register if needed */
116
59
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
117
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
60
index XXXXXXX..XXXXXXX 100644
118
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
61
--- a/tcg/aarch64/tcg-target.c.inc
119
mmu_idx, retaddr);
62
+++ b/tcg/aarch64/tcg-target.c.inc
120
}
63
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_sxt(TCGContext *s, TCGType ext, MemOp s_bits,
121
- tlb_addr = entry->addr_write & ~TLB_INVALID_MASK;
64
tcg_out_sbfm(s, ext, rd, rn, 0, bits);
122
+ tlb_addr = tlb_addr_write(entry) & ~TLB_INVALID_MASK;
65
}
123
}
66
124
67
+static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn)
125
/* Handle an IO access. */
126
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
127
cannot evict the first. */
128
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
129
entry2 = tlb_entry(env, mmu_idx, page2);
130
- if (!tlb_hit_page(entry2->addr_write, page2)
131
+ if (!tlb_hit_page(tlb_addr_write(entry2), page2)
132
&& !VICTIM_TLB_HIT(addr_write, page2)) {
133
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
134
mmu_idx, retaddr);
135
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
136
index XXXXXXX..XXXXXXX 100644
137
--- a/include/exec/cpu_ldst.h
138
+++ b/include/exec/cpu_ldst.h
139
@@ -XXX,XX +XXX,XX @@ extern __thread uintptr_t helper_retaddr;
140
/* The memory helpers for tcg-generated code need tcg_target_long etc. */
141
#include "tcg.h"
142
143
+static inline target_ulong tlb_addr_write(const CPUTLBEntry *entry)
144
+{
68
+{
145
+#if TCG_OVERSIZED_GUEST
69
+ tcg_out_sxt(s, type, MO_8, rd, rn);
146
+ return entry->addr_write;
147
+#else
148
+ return atomic_read(&entry->addr_write);
149
+#endif
150
+}
70
+}
151
+
71
+
152
/* Find the TLB index corresponding to the mmu_idx + address pair. */
72
static inline void tcg_out_uxt(TCGContext *s, MemOp s_bits,
153
static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
73
TCGReg rd, TCGReg rn)
154
target_ulong addr)
74
{
155
@@ -XXX,XX +XXX,XX @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
75
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
156
tlb_addr = tlbentry->addr_read;
76
}
157
break;
77
break;
158
case 1:
78
159
- tlb_addr = tlbentry->addr_write;
79
- case INDEX_op_ext8s_i64:
160
+ tlb_addr = tlb_addr_write(tlbentry);
80
- case INDEX_op_ext8s_i32:
161
break;
81
- tcg_out_sxt(s, ext, MO_8, a0, a1);
162
case 2:
82
- break;
163
tlb_addr = tlbentry->addr_code;
83
case INDEX_op_ext16s_i64:
164
diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
84
case INDEX_op_ext16s_i32:
165
index XXXXXXX..XXXXXXX 100644
85
tcg_out_sxt(s, ext, MO_16, a0, a1);
166
--- a/include/exec/cpu_ldst_template.h
86
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
167
+++ b/include/exec/cpu_ldst_template.h
87
case INDEX_op_call: /* Always emitted via tcg_out_call. */
168
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
88
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
169
addr = ptr;
89
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
170
mmu_idx = CPU_MMU_INDEX;
90
+ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
171
entry = tlb_entry(env, mmu_idx, addr);
91
+ case INDEX_op_ext8s_i64:
172
- if (unlikely(entry->addr_write !=
92
default:
173
+ if (unlikely(tlb_addr_write(entry) !=
93
g_assert_not_reached();
174
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
94
}
175
oi = make_memop_idx(SHIFT, mmu_idx);
95
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
176
glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi,
96
index XXXXXXX..XXXXXXX 100644
177
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
97
--- a/tcg/arm/tcg-target.c.inc
178
index XXXXXXX..XXXXXXX 100644
98
+++ b/tcg/arm/tcg-target.c.inc
179
--- a/accel/tcg/cputlb.c
99
@@ -XXX,XX +XXX,XX @@ static void tcg_out_udiv(TCGContext *s, ARMCond cond,
180
+++ b/accel/tcg/cputlb.c
100
tcg_out32(s, 0x0730f010 | (cond << 28) | (rd << 16) | rn | (rm << 8));
181
@@ -XXX,XX +XXX,XX @@ static inline bool tlb_hit_page_anyprot(CPUTLBEntry *tlb_entry,
101
}
182
target_ulong page)
102
183
{
103
-static void tcg_out_ext8s(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn)
184
return tlb_hit_page(tlb_entry->addr_read, page) ||
104
+static void tcg_out_ext8s(TCGContext *s, TCGType t, TCGReg rd, TCGReg rn)
185
- tlb_hit_page(tlb_entry->addr_write, page) ||
105
{
186
+ tlb_hit_page(tlb_addr_write(tlb_entry), page) ||
106
/* sxtb */
187
tlb_hit_page(tlb_entry->addr_code, page);
107
- tcg_out32(s, 0x06af0070 | (cond << 28) | (rd << 12) | rn);
188
}
108
+ tcg_out32(s, 0x06af0070 | (COND_AL << 28) | (rd << 12) | rn);
189
109
}
190
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
110
191
tlb_fill(cpu, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
111
static void __attribute__((unused))
192
112
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
193
entry = tlb_entry(env, mmu_idx, addr);
113
datahi = lb->datahi_reg;
194
- tlb_addr = entry->addr_write;
114
switch (opc & MO_SSIZE) {
195
+ tlb_addr = tlb_addr_write(entry);
115
case MO_SB:
196
if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
116
- tcg_out_ext8s(s, COND_AL, datalo, TCG_REG_R0);
197
/* RAM access */
117
+ tcg_out_ext8s(s, TCG_TYPE_I32, datalo, TCG_REG_R0);
198
uintptr_t haddr = addr + entry->addend;
118
break;
199
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
119
case MO_SW:
200
assert_cpu_is_self(ENV_GET_CPU(env));
120
tcg_out_ext16s(s, COND_AL, datalo, TCG_REG_R0);
201
for (vidx = 0; vidx < CPU_VTLB_SIZE; ++vidx) {
121
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
202
CPUTLBEntry *vtlb = &env->tlb_v_table[mmu_idx][vidx];
122
tcg_out_bswap32(s, COND_AL, args[0], args[1]);
203
- target_ulong cmp = *(target_ulong *)((uintptr_t)vtlb + elt_ofs);
123
break;
204
+ target_ulong cmp;
124
125
- case INDEX_op_ext8s_i32:
126
- tcg_out_ext8s(s, COND_AL, args[0], args[1]);
127
- break;
128
case INDEX_op_ext16s_i32:
129
tcg_out_ext16s(s, COND_AL, args[0], args[1]);
130
break;
131
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
132
case INDEX_op_call: /* Always emitted via tcg_out_call. */
133
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
134
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
135
+ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
136
default:
137
g_assert_not_reached();
138
}
139
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
140
index XXXXXXX..XXXXXXX 100644
141
--- a/tcg/i386/tcg-target.c.inc
142
+++ b/tcg/i386/tcg-target.c.inc
143
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
144
tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src);
145
}
146
147
-static void tcg_out_ext8s(TCGContext *s, int dest, int src, int rexw)
148
+static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
149
{
150
+ int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW;
151
/* movsbl */
152
tcg_debug_assert(src < 4 || TCG_TARGET_REG_BITS == 64);
153
tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src);
154
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
155
data_reg = l->datalo_reg;
156
switch (opc & MO_SSIZE) {
157
case MO_SB:
158
- tcg_out_ext8s(s, data_reg, TCG_REG_EAX, rexw);
159
+ tcg_out_ext8s(s, l->type, data_reg, TCG_REG_EAX);
160
break;
161
case MO_SW:
162
tcg_out_ext16s(s, data_reg, TCG_REG_EAX, rexw);
163
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
164
tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0);
165
break;
166
167
- OP_32_64(ext8s):
168
- tcg_out_ext8s(s, a0, a1, rexw);
169
- break;
170
OP_32_64(ext16s):
171
tcg_out_ext16s(s, a0, a1, rexw);
172
break;
173
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
174
case INDEX_op_call: /* Always emitted via tcg_out_call. */
175
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
176
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
177
+ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
178
+ case INDEX_op_ext8s_i64:
179
default:
180
g_assert_not_reached();
181
}
182
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
183
index XXXXXXX..XXXXXXX 100644
184
--- a/tcg/loongarch64/tcg-target.c.inc
185
+++ b/tcg/loongarch64/tcg-target.c.inc
186
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
187
tcg_out_opc_bstrpick_d(s, ret, arg, 0, 31);
188
}
189
190
-static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
191
+static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
192
{
193
tcg_out_opc_sext_b(s, ret, arg);
194
}
195
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
196
197
switch (opc & MO_SSIZE) {
198
case MO_SB:
199
- tcg_out_ext8s(s, l->datalo_reg, TCG_REG_A0);
200
+ tcg_out_ext8s(s, type, l->datalo_reg, TCG_REG_A0);
201
break;
202
case MO_SW:
203
tcg_out_ext16s(s, l->datalo_reg, TCG_REG_A0);
204
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
205
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
206
break;
207
208
- case INDEX_op_ext8s_i32:
209
- case INDEX_op_ext8s_i64:
210
- tcg_out_ext8s(s, a0, a1);
211
- break;
212
-
213
case INDEX_op_ext8u_i32:
214
case INDEX_op_ext8u_i64:
215
tcg_out_ext8u(s, a0, a1);
216
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
217
case INDEX_op_call: /* Always emitted via tcg_out_call. */
218
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
219
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
220
+ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
221
+ case INDEX_op_ext8s_i64:
222
default:
223
g_assert_not_reached();
224
}
225
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
226
index XXXXXXX..XXXXXXX 100644
227
--- a/tcg/mips/tcg-target.c.inc
228
+++ b/tcg/mips/tcg-target.c.inc
229
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type,
230
}
231
}
232
233
+static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
234
+{
235
+ tcg_debug_assert(TCG_TARGET_HAS_ext8s_i32);
236
+ tcg_out_opc_reg(s, OPC_SEB, rd, TCG_REG_ZERO, rs);
237
+}
205
+
238
+
206
+ /* elt_ofs might correspond to .addr_write, so use atomic_read */
239
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
207
+#if TCG_OVERSIZED_GUEST
240
tcg_target_long imm)
208
+ cmp = *(target_ulong *)((uintptr_t)vtlb + elt_ofs);
241
{
209
+#else
242
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
210
+ cmp = atomic_read((target_ulong *)((uintptr_t)vtlb + elt_ofs));
243
case INDEX_op_not_i64:
244
i1 = OPC_NOR;
245
goto do_unary;
246
- case INDEX_op_ext8s_i32:
247
- case INDEX_op_ext8s_i64:
248
- i1 = OPC_SEB;
249
- goto do_unary;
250
case INDEX_op_ext16s_i32:
251
case INDEX_op_ext16s_i64:
252
i1 = OPC_SEH;
253
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
254
case INDEX_op_call: /* Always emitted via tcg_out_call. */
255
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
256
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
257
+ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
258
+ case INDEX_op_ext8s_i64:
259
default:
260
g_assert_not_reached();
261
}
262
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
263
index XXXXXXX..XXXXXXX 100644
264
--- a/tcg/ppc/tcg-target.c.inc
265
+++ b/tcg/ppc/tcg-target.c.inc
266
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
267
tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
268
}
269
270
-static inline void tcg_out_ext8s(TCGContext *s, TCGReg dst, TCGReg src)
271
+static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
272
{
273
tcg_out32(s, EXTSB | RA(dst) | RS(src));
274
}
275
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
276
case INDEX_op_ld8s_i32:
277
case INDEX_op_ld8s_i64:
278
tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
279
- tcg_out_ext8s(s, args[0], args[0]);
280
+ tcg_out_ext8s(s, TCG_TYPE_REG, args[0], args[0]);
281
break;
282
case INDEX_op_ld16u_i32:
283
case INDEX_op_ld16u_i64:
284
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
285
tcg_out_qemu_st(s, args, true);
286
break;
287
288
- case INDEX_op_ext8s_i32:
289
- case INDEX_op_ext8s_i64:
290
- tcg_out_ext8s(s, args[0], args[1]);
291
- break;
292
case INDEX_op_ext16s_i32:
293
case INDEX_op_ext16s_i64:
294
tcg_out_ext16s(s, args[0], args[1]);
295
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
296
case INDEX_op_call: /* Always emitted via tcg_out_call. */
297
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
298
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
299
+ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
300
+ case INDEX_op_ext8s_i64:
301
default:
302
g_assert_not_reached();
303
}
304
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
305
index XXXXXXX..XXXXXXX 100644
306
--- a/tcg/riscv/tcg-target.c.inc
307
+++ b/tcg/riscv/tcg-target.c.inc
308
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
309
tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32);
310
}
311
312
-static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
313
+static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
314
{
315
tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 24);
316
tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24);
317
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
318
tcg_out_ext32u(s, a0, a1);
319
break;
320
321
- case INDEX_op_ext8s_i32:
322
- case INDEX_op_ext8s_i64:
323
- tcg_out_ext8s(s, a0, a1);
324
- break;
325
-
326
case INDEX_op_ext16s_i32:
327
case INDEX_op_ext16s_i64:
328
tcg_out_ext16s(s, a0, a1);
329
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
330
case INDEX_op_call: /* Always emitted via tcg_out_call. */
331
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
332
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
333
+ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
334
+ case INDEX_op_ext8s_i64:
335
default:
336
g_assert_not_reached();
337
}
338
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
339
index XXXXXXX..XXXXXXX 100644
340
--- a/tcg/s390x/tcg-target.c.inc
341
+++ b/tcg/s390x/tcg-target.c.inc
342
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src,
343
tcg_out16(s, (ofs << 8) | (RIEf_RISBG & 0xff));
344
}
345
346
-static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
347
+static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
348
{
349
tcg_out_insn(s, RRE, LGBR, dest, src);
350
}
351
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
352
}
353
break;
354
355
- case INDEX_op_ext8s_i32:
356
- tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
357
- break;
358
case INDEX_op_ext16s_i32:
359
tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
360
break;
361
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
362
}
363
break;
364
365
- case INDEX_op_ext8s_i64:
366
- tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
367
- break;
368
case INDEX_op_ext16s_i64:
369
tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
370
break;
371
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
372
case INDEX_op_call: /* Always emitted via tcg_out_call. */
373
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
374
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
375
+ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
376
+ case INDEX_op_ext8s_i64:
377
default:
378
g_assert_not_reached();
379
}
380
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
381
index XXXXXXX..XXXXXXX 100644
382
--- a/tcg/sparc64/tcg-target.c.inc
383
+++ b/tcg/sparc64/tcg-target.c.inc
384
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type,
385
tcg_out_movi_int(s, type, ret, arg, false, TCG_REG_T2);
386
}
387
388
+static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
389
+{
390
+ g_assert_not_reached();
391
+}
392
+
393
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
394
tcg_target_long imm)
395
{
396
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
397
case INDEX_op_call: /* Always emitted via tcg_out_call. */
398
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
399
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
400
+ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
401
+ case INDEX_op_ext8s_i64:
402
default:
403
g_assert_not_reached();
404
}
405
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
406
index XXXXXXX..XXXXXXX 100644
407
--- a/tcg/tci/tcg-target.c.inc
408
+++ b/tcg/tci/tcg-target.c.inc
409
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type,
410
}
411
}
412
413
+static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
414
+{
415
+ switch (type) {
416
+ case TCG_TYPE_I32:
417
+ tcg_debug_assert(TCG_TARGET_HAS_ext8s_i32);
418
+ tcg_out_op_rr(s, INDEX_op_ext8s_i32, rd, rs);
419
+ break;
420
+#if TCG_TARGET_REG_BITS == 64
421
+ case TCG_TYPE_I64:
422
+ tcg_debug_assert(TCG_TARGET_HAS_ext8s_i64);
423
+ tcg_out_op_rr(s, INDEX_op_ext8s_i64, rd, rs);
424
+ break;
211
+#endif
425
+#endif
212
426
+ default:
213
if (cmp == page) {
427
+ g_assert_not_reached();
214
/* Found entry in victim tlb, swap tlb and iotlb. */
428
+ }
215
@@ -XXX,XX +XXX,XX @@ void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
429
+}
216
uintptr_t index = tlb_index(env, mmu_idx, addr);
430
+
217
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
431
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
218
432
tcg_target_long imm)
219
- if (!tlb_hit(entry->addr_write, addr)) {
433
{
220
+ if (!tlb_hit(tlb_addr_write(entry), addr)) {
434
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
221
/* TLB entry is for a different page */
435
222
if (!VICTIM_TLB_HIT(addr_write, addr)) {
436
CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
223
tlb_fill(ENV_GET_CPU(env), addr, size, MMU_DATA_STORE,
437
CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */
224
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
438
- CASE_32_64(ext8s) /* Optional (TCG_TARGET_HAS_ext8s_*). */
225
size_t mmu_idx = get_mmuidx(oi);
439
CASE_32_64(ext8u) /* Optional (TCG_TARGET_HAS_ext8u_*). */
226
uintptr_t index = tlb_index(env, mmu_idx, addr);
440
CASE_32_64(ext16s) /* Optional (TCG_TARGET_HAS_ext16s_*). */
227
CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
441
CASE_32_64(ext16u) /* Optional (TCG_TARGET_HAS_ext16u_*). */
228
- target_ulong tlb_addr = tlbe->addr_write;
442
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
229
+ target_ulong tlb_addr = tlb_addr_write(tlbe);
443
case INDEX_op_call: /* Always emitted via tcg_out_call. */
230
TCGMemOp mop = get_memop(oi);
444
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
231
int a_bits = get_alignment_bits(mop);
445
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
232
int s_bits = mop & MO_SIZE;
446
+ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
233
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
447
+ case INDEX_op_ext8s_i64:
234
tlb_fill(ENV_GET_CPU(env), addr, 1 << s_bits, MMU_DATA_STORE,
448
default:
235
mmu_idx, retaddr);
449
g_assert_not_reached();
236
}
450
}
237
- tlb_addr = tlbe->addr_write & ~TLB_INVALID_MASK;
238
+ tlb_addr = tlb_addr_write(tlbe) & ~TLB_INVALID_MASK;
239
}
240
241
/* Notice an IO access or a needs-MMU-lookup access */
242
--
451
--
243
2.17.2
452
2.34.1
244
453
245
454
diff view generated by jsdifflib
1
Isolate the computation of an index from an address into a
1
We will need a backend interface for performing 8-bit zero-extend.
2
helper before we change that function.
2
Use it in tcg_reg_alloc_op in the meantime.
3
3
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.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
[ cota: convert tlb_vaddr_to_host; use atomic_read on addr_write ]
7
Signed-off-by: Emilio G. Cota <cota@braap.org>
8
Message-Id: <20181009175129.17888-2-cota@braap.org>
9
---
6
---
10
accel/tcg/softmmu_template.h | 64 +++++++++++++++++---------------
7
tcg/tcg.c | 5 +++++
11
include/exec/cpu_ldst.h | 19 ++++++++--
8
tcg/aarch64/tcg-target.c.inc | 11 +++++++----
12
include/exec/cpu_ldst_template.h | 25 +++++++------
9
tcg/arm/tcg-target.c.inc | 12 +++++++++---
13
accel/tcg/cputlb.c | 60 ++++++++++++++----------------
10
tcg/i386/tcg-target.c.inc | 7 +++----
14
4 files changed, 90 insertions(+), 78 deletions(-)
11
tcg/loongarch64/tcg-target.c.inc | 7 ++-----
12
tcg/mips/tcg-target.c.inc | 9 ++++++++-
13
tcg/ppc/tcg-target.c.inc | 7 +++++++
14
tcg/riscv/tcg-target.c.inc | 7 ++-----
15
tcg/s390x/tcg-target.c.inc | 14 +++++---------
16
tcg/sparc64/tcg-target.c.inc | 9 ++++++++-
17
tcg/tci/tcg-target.c.inc | 14 +++++++++++++-
18
11 files changed, 69 insertions(+), 33 deletions(-)
15
19
16
diff --git a/accel/tcg/softmmu_template.h b/accel/tcg/softmmu_template.h
20
diff --git a/tcg/tcg.c b/tcg/tcg.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/accel/tcg/softmmu_template.h
22
--- a/tcg/tcg.c
19
+++ b/accel/tcg/softmmu_template.h
23
+++ b/tcg/tcg.c
20
@@ -XXX,XX +XXX,XX @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
24
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
21
WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
25
static void tcg_out_movi(TCGContext *s, TCGType type,
22
TCGMemOpIdx oi, uintptr_t retaddr)
26
TCGReg ret, tcg_target_long arg);
23
{
27
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
24
- unsigned mmu_idx = get_mmuidx(oi);
28
+static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg);
25
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
29
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
26
- target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
30
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
27
+ uintptr_t mmu_idx = get_mmuidx(oi);
31
static void tcg_out_goto_tb(TCGContext *s, int which);
28
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
32
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
29
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
33
case INDEX_op_ext8s_i64:
30
+ target_ulong tlb_addr = entry->ADDR_READ;
34
tcg_out_ext8s(s, TCG_TYPE_I64, new_args[0], new_args[1]);
31
unsigned a_bits = get_alignment_bits(get_memop(oi));
35
break;
32
uintptr_t haddr;
36
+ case INDEX_op_ext8u_i32:
33
DATA_TYPE res;
37
+ case INDEX_op_ext8u_i64:
34
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
38
+ tcg_out_ext8u(s, new_args[0], new_args[1]);
35
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE,
39
+ break;
36
mmu_idx, retaddr);
40
default:
37
}
41
if (def->flags & TCG_OPF_VECTOR) {
38
- tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
42
tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
39
+ tlb_addr = entry->ADDR_READ;
43
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
40
}
44
index XXXXXXX..XXXXXXX 100644
41
45
--- a/tcg/aarch64/tcg-target.c.inc
42
/* Handle an IO access. */
46
+++ b/tcg/aarch64/tcg-target.c.inc
43
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
47
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_uxt(TCGContext *s, MemOp s_bits,
44
return res;
48
tcg_out_ubfm(s, 0, rd, rn, 0, bits);
45
}
49
}
46
50
47
- haddr = addr + env->tlb_table[mmu_idx][index].addend;
51
+static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rn)
48
+ haddr = addr + entry->addend;
52
+{
49
#if DATA_SIZE == 1
53
+ tcg_out_uxt(s, MO_8, rd, rn);
50
res = glue(glue(ld, LSUFFIX), _p)((uint8_t *)haddr);
54
+}
51
#else
55
+
52
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
56
static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd,
53
WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
57
TCGReg rn, int64_t aimm)
54
TCGMemOpIdx oi, uintptr_t retaddr)
58
{
55
{
59
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
56
- unsigned mmu_idx = get_mmuidx(oi);
60
case INDEX_op_ext32s_i64:
57
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
61
tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1);
58
- target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
62
break;
59
+ uintptr_t mmu_idx = get_mmuidx(oi);
63
- case INDEX_op_ext8u_i64:
60
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
64
- case INDEX_op_ext8u_i32:
61
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
65
- tcg_out_uxt(s, MO_8, a0, a1);
62
+ target_ulong tlb_addr = entry->ADDR_READ;
66
- break;
63
unsigned a_bits = get_alignment_bits(get_memop(oi));
67
case INDEX_op_ext16u_i64:
64
uintptr_t haddr;
68
case INDEX_op_ext16u_i32:
65
DATA_TYPE res;
69
tcg_out_uxt(s, MO_16, a0, a1);
66
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
70
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
67
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE,
71
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
68
mmu_idx, retaddr);
72
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
69
}
73
case INDEX_op_ext8s_i64:
70
- tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
74
+ case INDEX_op_ext8u_i32:
71
+ tlb_addr = entry->ADDR_READ;
75
+ case INDEX_op_ext8u_i64:
72
}
76
default:
73
77
g_assert_not_reached();
74
/* Handle an IO access. */
78
}
75
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
79
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
76
return res;
80
index XXXXXXX..XXXXXXX 100644
77
}
81
--- a/tcg/arm/tcg-target.c.inc
78
82
+++ b/tcg/arm/tcg-target.c.inc
79
- haddr = addr + env->tlb_table[mmu_idx][index].addend;
83
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType t, TCGReg rd, TCGReg rn)
80
+ haddr = addr + entry->addend;
84
tcg_out32(s, 0x06af0070 | (COND_AL << 28) | (rd << 12) | rn);
81
res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr);
85
}
82
return res;
86
83
}
87
+static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rn)
84
@@ -XXX,XX +XXX,XX @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
88
+{
85
void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
89
+ tcg_out_dat_imm(s, COND_AL, ARITH_AND, rd, rn, 0xff);
86
TCGMemOpIdx oi, uintptr_t retaddr)
90
+}
87
{
91
+
88
- unsigned mmu_idx = get_mmuidx(oi);
92
static void __attribute__((unused))
89
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
93
-tcg_out_ext8u(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn)
90
- target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
94
+tcg_out_ext8u_cond(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn)
91
+ uintptr_t mmu_idx = get_mmuidx(oi);
95
{
92
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
96
tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff);
93
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
97
}
94
+ target_ulong tlb_addr = entry->addr_write;
98
@@ -XXX,XX +XXX,XX @@ static TCGReg NAME(TCGContext *s, TCGReg argreg, ARGTYPE arg) \
95
unsigned a_bits = get_alignment_bits(get_memop(oi));
99
96
uintptr_t haddr;
100
DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t, tcg_out_movi32,
97
101
(tcg_out_movi32(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
98
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
102
-DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg, tcg_out_ext8u,
99
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
103
- (tcg_out_ext8u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
100
mmu_idx, retaddr);
104
+DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg, tcg_out_ext8u_cond,
101
}
105
+ (tcg_out_ext8u_cond(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
102
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write & ~TLB_INVALID_MASK;
106
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg, tcg_out_ext16u,
103
+ tlb_addr = entry->addr_write & ~TLB_INVALID_MASK;
107
(tcg_out_ext16u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
104
}
108
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg32, TCGReg, tcg_out_mov_reg, )
105
109
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
106
/* Handle an IO access. */
110
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
107
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
111
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
108
if (DATA_SIZE > 1
112
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
109
&& unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
113
+ case INDEX_op_ext8u_i32:
110
>= TARGET_PAGE_SIZE)) {
114
default:
111
- int i, index2;
115
g_assert_not_reached();
112
- target_ulong page2, tlb_addr2;
116
}
113
+ int i;
117
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
114
+ target_ulong page2;
118
index XXXXXXX..XXXXXXX 100644
115
+ CPUTLBEntry *entry2;
119
--- a/tcg/i386/tcg-target.c.inc
116
do_unaligned_access:
120
+++ b/tcg/i386/tcg-target.c.inc
117
/* Ensure the second page is in the TLB. Note that the first page
121
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_rolw_8(TCGContext *s, int reg)
118
is already guaranteed to be filled, and that the second page
122
tcg_out_shifti(s, SHIFT_ROL + P_DATA16, reg, 8);
119
cannot evict the first. */
123
}
120
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
124
121
- index2 = (page2 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
125
-static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
122
- tlb_addr2 = env->tlb_table[mmu_idx][index2].addr_write;
126
+static void tcg_out_ext8u(TCGContext *s, TCGReg dest, TCGReg src)
123
- if (!tlb_hit_page(tlb_addr2, page2)
127
{
124
+ entry2 = tlb_entry(env, mmu_idx, page2);
128
/* movzbl */
125
+ if (!tlb_hit_page(entry2->addr_write, page2)
129
tcg_debug_assert(src < 4 || TCG_TARGET_REG_BITS == 64);
126
&& !VICTIM_TLB_HIT(addr_write, page2)) {
130
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
127
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
131
OP_32_64(ext16s):
128
mmu_idx, retaddr);
132
tcg_out_ext16s(s, a0, a1, rexw);
129
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
133
break;
134
- OP_32_64(ext8u):
135
- tcg_out_ext8u(s, a0, a1);
136
- break;
137
OP_32_64(ext16u):
138
tcg_out_ext16u(s, a0, a1);
139
break;
140
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
141
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
142
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
143
case INDEX_op_ext8s_i64:
144
+ case INDEX_op_ext8u_i32:
145
+ case INDEX_op_ext8u_i64:
146
default:
147
g_assert_not_reached();
148
}
149
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
150
index XXXXXXX..XXXXXXX 100644
151
--- a/tcg/loongarch64/tcg-target.c.inc
152
+++ b/tcg/loongarch64/tcg-target.c.inc
153
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
154
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
155
break;
156
157
- case INDEX_op_ext8u_i32:
158
- case INDEX_op_ext8u_i64:
159
- tcg_out_ext8u(s, a0, a1);
160
- break;
161
-
162
case INDEX_op_ext16s_i32:
163
case INDEX_op_ext16s_i64:
164
tcg_out_ext16s(s, a0, a1);
165
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
166
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
167
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
168
case INDEX_op_ext8s_i64:
169
+ case INDEX_op_ext8u_i32:
170
+ case INDEX_op_ext8u_i64:
171
default:
172
g_assert_not_reached();
173
}
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 void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
179
tcg_out_opc_reg(s, OPC_SEB, rd, TCG_REG_ZERO, rs);
180
}
181
182
+static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
183
+{
184
+ tcg_out_opc_imm(s, OPC_ANDI, rd, rs, 0xff);
185
+}
186
+
187
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
188
tcg_target_long imm)
189
{
190
@@ -XXX,XX +XXX,XX @@ static int tcg_out_call_iarg_reg8(TCGContext *s, int i, TCGReg arg)
191
if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) {
192
tmp = tcg_target_call_iarg_regs[i];
193
}
194
- tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xff);
195
+ tcg_out_ext8u(s, tmp, arg);
196
return tcg_out_call_iarg_reg(s, i, tmp);
197
}
198
199
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
200
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
201
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
202
case INDEX_op_ext8s_i64:
203
+ case INDEX_op_ext8u_i32:
204
+ case INDEX_op_ext8u_i64:
205
default:
206
g_assert_not_reached();
207
}
208
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
209
index XXXXXXX..XXXXXXX 100644
210
--- a/tcg/ppc/tcg-target.c.inc
211
+++ b/tcg/ppc/tcg-target.c.inc
212
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
213
tcg_out32(s, EXTSB | RA(dst) | RS(src));
214
}
215
216
+static void tcg_out_ext8u(TCGContext *s, TCGReg dst, TCGReg src)
217
+{
218
+ tcg_out32(s, ANDI | SAI(src, dst, 0xff));
219
+}
220
+
221
static inline void tcg_out_ext16s(TCGContext *s, TCGReg dst, TCGReg src)
222
{
223
tcg_out32(s, EXTSH | RA(dst) | RS(src));
224
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
225
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
226
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
227
case INDEX_op_ext8s_i64:
228
+ case INDEX_op_ext8u_i32:
229
+ case INDEX_op_ext8u_i64:
230
default:
231
g_assert_not_reached();
232
}
233
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
234
index XXXXXXX..XXXXXXX 100644
235
--- a/tcg/riscv/tcg-target.c.inc
236
+++ b/tcg/riscv/tcg-target.c.inc
237
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
238
tcg_out_qemu_st(s, args, true);
239
break;
240
241
- case INDEX_op_ext8u_i32:
242
- case INDEX_op_ext8u_i64:
243
- tcg_out_ext8u(s, a0, a1);
244
- break;
245
-
246
case INDEX_op_ext16u_i32:
247
case INDEX_op_ext16u_i64:
248
tcg_out_ext16u(s, a0, a1);
249
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
250
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
251
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
252
case INDEX_op_ext8s_i64:
253
+ case INDEX_op_ext8u_i32:
254
+ case INDEX_op_ext8u_i64:
255
default:
256
g_assert_not_reached();
257
}
258
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
259
index XXXXXXX..XXXXXXX 100644
260
--- a/tcg/s390x/tcg-target.c.inc
261
+++ b/tcg/s390x/tcg-target.c.inc
262
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
263
tcg_out_insn(s, RRE, LGBR, dest, src);
264
}
265
266
-static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
267
+static void tcg_out_ext8u(TCGContext *s, TCGReg dest, TCGReg src)
268
{
269
tcg_out_insn(s, RRE, LLGCR, dest, src);
270
}
271
@@ -XXX,XX +XXX,XX @@ static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
130
return;
272
return;
131
}
273
}
132
274
if ((val & valid) == 0xff) {
133
- haddr = addr + env->tlb_table[mmu_idx][index].addend;
275
- tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
134
+ haddr = addr + entry->addend;
276
+ tcg_out_ext8u(s, dest, dest);
135
#if DATA_SIZE == 1
136
glue(glue(st, SUFFIX), _p)((uint8_t *)haddr, val);
137
#else
138
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
139
void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
140
TCGMemOpIdx oi, uintptr_t retaddr)
141
{
142
- unsigned mmu_idx = get_mmuidx(oi);
143
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
144
- target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
145
+ uintptr_t mmu_idx = get_mmuidx(oi);
146
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
147
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
148
+ target_ulong tlb_addr = entry->addr_write;
149
unsigned a_bits = get_alignment_bits(get_memop(oi));
150
uintptr_t haddr;
151
152
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
153
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
154
mmu_idx, retaddr);
155
}
156
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write & ~TLB_INVALID_MASK;
157
+ tlb_addr = entry->addr_write & ~TLB_INVALID_MASK;
158
}
159
160
/* Handle an IO access. */
161
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
162
if (DATA_SIZE > 1
163
&& unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
164
>= TARGET_PAGE_SIZE)) {
165
- int i, index2;
166
- target_ulong page2, tlb_addr2;
167
+ int i;
168
+ target_ulong page2;
169
+ CPUTLBEntry *entry2;
170
do_unaligned_access:
171
/* Ensure the second page is in the TLB. Note that the first page
172
is already guaranteed to be filled, and that the second page
173
cannot evict the first. */
174
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
175
- index2 = (page2 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
176
- tlb_addr2 = env->tlb_table[mmu_idx][index2].addr_write;
177
- if (!tlb_hit_page(tlb_addr2, page2)
178
+ entry2 = tlb_entry(env, mmu_idx, page2);
179
+ if (!tlb_hit_page(entry2->addr_write, page2)
180
&& !VICTIM_TLB_HIT(addr_write, page2)) {
181
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
182
mmu_idx, retaddr);
183
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
184
return;
277
return;
185
}
278
}
186
279
if ((val & valid) == 0xffff) {
187
- haddr = addr + env->tlb_table[mmu_idx][index].addend;
280
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
188
+ haddr = addr + entry->addend;
281
}
189
glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val);
282
switch (opc & MO_SIZE) {
190
}
283
case MO_UB:
191
#endif /* DATA_SIZE > 1 */
284
- tgen_ext8u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
192
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
285
+ tcg_out_ext8u(s, TCG_REG_R4, data_reg);
193
index XXXXXXX..XXXXXXX 100644
286
break;
194
--- a/include/exec/cpu_ldst.h
287
case MO_UW:
195
+++ b/include/exec/cpu_ldst.h
288
tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
196
@@ -XXX,XX +XXX,XX @@ extern __thread uintptr_t helper_retaddr;
289
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
197
/* The memory helpers for tcg-generated code need tcg_target_long etc. */
290
case INDEX_op_ext16s_i32:
198
#include "tcg.h"
291
tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
199
292
break;
200
+/* Find the TLB index corresponding to the mmu_idx + address pair. */
293
- case INDEX_op_ext8u_i32:
201
+static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
294
- tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
202
+ target_ulong addr)
295
- break;
203
+{
296
case INDEX_op_ext16u_i32:
204
+ return (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
297
tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
205
+}
298
break;
206
+
299
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
207
+/* Find the TLB entry corresponding to the mmu_idx + address pair. */
300
case INDEX_op_ext32s_i64:
208
+static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
301
tgen_ext32s(s, args[0], args[1]);
209
+ target_ulong addr)
302
break;
210
+{
303
- case INDEX_op_ext8u_i64:
211
+ return &env->tlb_table[mmu_idx][tlb_index(env, mmu_idx, addr)];
304
- tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
212
+}
305
- break;
213
+
306
case INDEX_op_ext16u_i64:
214
#ifdef MMU_MODE0_SUFFIX
307
tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
215
#define CPU_MMU_INDEX 0
308
break;
216
#define MEMSUFFIX MMU_MODE0_SUFFIX
309
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
217
@@ -XXX,XX +XXX,XX @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
310
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
218
#if defined(CONFIG_USER_ONLY)
311
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
219
return g2h(addr);
312
case INDEX_op_ext8s_i64:
220
#else
313
+ case INDEX_op_ext8u_i32:
221
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
314
+ case INDEX_op_ext8u_i64:
222
- CPUTLBEntry *tlbentry = &env->tlb_table[mmu_idx][index];
315
default:
223
+ CPUTLBEntry *tlbentry = tlb_entry(env, mmu_idx, addr);
316
g_assert_not_reached();
224
abi_ptr tlb_addr;
317
}
225
uintptr_t haddr;
318
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
226
319
index XXXXXXX..XXXXXXX 100644
227
@@ -XXX,XX +XXX,XX @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
320
--- a/tcg/sparc64/tcg-target.c.inc
228
return NULL;
321
+++ b/tcg/sparc64/tcg-target.c.inc
229
}
322
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
230
323
g_assert_not_reached();
231
- haddr = addr + env->tlb_table[mmu_idx][index].addend;
324
}
232
+ haddr = addr + tlbentry->addend;
325
233
return (void *)haddr;
326
+static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
234
#endif /* defined(CONFIG_USER_ONLY) */
327
+{
235
}
328
+ tcg_out_arithi(s, rd, rs, 0xff, ARITH_AND);
236
diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
329
+}
237
index XXXXXXX..XXXXXXX 100644
330
+
238
--- a/include/exec/cpu_ldst_template.h
331
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
239
+++ b/include/exec/cpu_ldst_template.h
332
tcg_target_long imm)
240
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
333
{
241
target_ulong ptr,
334
@@ -XXX,XX +XXX,XX @@ static void emit_extend(TCGContext *s, TCGReg r, int op)
242
uintptr_t retaddr)
335
*/
243
{
336
switch (op & MO_SIZE) {
244
- int page_index;
337
case MO_8:
245
+ CPUTLBEntry *entry;
338
- tcg_out_arithi(s, r, r, 0xff, ARITH_AND);
246
RES_TYPE res;
339
+ tcg_out_ext8u(s, r, r);
247
target_ulong addr;
340
break;
248
int mmu_idx;
341
case MO_16:
249
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
342
tcg_out_arithi(s, r, r, 16, SHIFT_SLL);
250
#endif
343
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
251
344
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
252
addr = ptr;
345
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
253
- page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
346
case INDEX_op_ext8s_i64:
254
mmu_idx = CPU_MMU_INDEX;
347
+ case INDEX_op_ext8u_i32:
255
- if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
348
+ case INDEX_op_ext8u_i64:
256
+ entry = tlb_entry(env, mmu_idx, addr);
349
default:
257
+ if (unlikely(entry->ADDR_READ !=
350
g_assert_not_reached();
258
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
351
}
259
oi = make_memop_idx(SHIFT, mmu_idx);
352
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
260
res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
353
index XXXXXXX..XXXXXXX 100644
261
oi, retaddr);
354
--- a/tcg/tci/tcg-target.c.inc
262
} else {
355
+++ b/tcg/tci/tcg-target.c.inc
263
- uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
356
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
264
+ uintptr_t hostaddr = addr + entry->addend;
357
}
265
res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
358
}
266
}
359
267
return res;
360
+static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
268
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
361
+{
269
target_ulong ptr,
362
+ if (TCG_TARGET_REG_BITS == 64) {
270
uintptr_t retaddr)
363
+ tcg_debug_assert(TCG_TARGET_HAS_ext8u_i64);
271
{
364
+ tcg_out_op_rr(s, INDEX_op_ext8u_i64, rd, rs);
272
- int res, page_index;
365
+ } else {
273
+ CPUTLBEntry *entry;
366
+ tcg_debug_assert(TCG_TARGET_HAS_ext8u_i32);
274
+ int res;
367
+ tcg_out_op_rr(s, INDEX_op_ext8u_i32, rd, rs);
275
target_ulong addr;
368
+ }
276
int mmu_idx;
369
+}
277
TCGMemOpIdx oi;
370
+
278
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
371
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
279
#endif
372
tcg_target_long imm)
280
373
{
281
addr = ptr;
374
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
282
- page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
375
283
mmu_idx = CPU_MMU_INDEX;
376
CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
284
- if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
377
CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */
285
+ entry = tlb_entry(env, mmu_idx, addr);
378
- CASE_32_64(ext8u) /* Optional (TCG_TARGET_HAS_ext8u_*). */
286
+ if (unlikely(entry->ADDR_READ !=
379
CASE_32_64(ext16s) /* Optional (TCG_TARGET_HAS_ext16s_*). */
287
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
380
CASE_32_64(ext16u) /* Optional (TCG_TARGET_HAS_ext16u_*). */
288
oi = make_memop_idx(SHIFT, mmu_idx);
381
CASE_64(ext32s) /* Optional (TCG_TARGET_HAS_ext32s_i64). */
289
res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
382
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
290
MMUSUFFIX)(env, addr, oi, retaddr);
383
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
291
} else {
384
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
292
- uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
385
case INDEX_op_ext8s_i64:
293
+ uintptr_t hostaddr = addr + entry->addend;
386
+ case INDEX_op_ext8u_i32:
294
res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
387
+ case INDEX_op_ext8u_i64:
295
}
388
default:
296
return res;
389
g_assert_not_reached();
297
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
390
}
298
target_ulong ptr,
299
RES_TYPE v, uintptr_t retaddr)
300
{
301
- int page_index;
302
+ CPUTLBEntry *entry;
303
target_ulong addr;
304
int mmu_idx;
305
TCGMemOpIdx oi;
306
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
307
#endif
308
309
addr = ptr;
310
- page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
311
mmu_idx = CPU_MMU_INDEX;
312
- if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
313
+ entry = tlb_entry(env, mmu_idx, addr);
314
+ if (unlikely(entry->addr_write !=
315
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
316
oi = make_memop_idx(SHIFT, mmu_idx);
317
glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi,
318
retaddr);
319
} else {
320
- uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
321
+ uintptr_t hostaddr = addr + entry->addend;
322
glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
323
}
324
}
325
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
326
index XXXXXXX..XXXXXXX 100644
327
--- a/accel/tcg/cputlb.c
328
+++ b/accel/tcg/cputlb.c
329
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_async_work(CPUState *cpu, run_on_cpu_data data)
330
{
331
CPUArchState *env = cpu->env_ptr;
332
target_ulong addr = (target_ulong) data.target_ptr;
333
- int i;
334
int mmu_idx;
335
336
assert_cpu_is_self(cpu);
337
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_async_work(CPUState *cpu, run_on_cpu_data data)
338
}
339
340
addr &= TARGET_PAGE_MASK;
341
- i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
342
qemu_spin_lock(&env->tlb_lock);
343
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
344
- tlb_flush_entry_locked(&env->tlb_table[mmu_idx][i], addr);
345
+ tlb_flush_entry_locked(tlb_entry(env, mmu_idx, addr), addr);
346
tlb_flush_vtlb_page_locked(env, mmu_idx, addr);
347
}
348
qemu_spin_unlock(&env->tlb_lock);
349
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_by_mmuidx_async_work(CPUState *cpu,
350
target_ulong addr_and_mmuidx = (target_ulong) data.target_ptr;
351
target_ulong addr = addr_and_mmuidx & TARGET_PAGE_MASK;
352
unsigned long mmu_idx_bitmap = addr_and_mmuidx & ALL_MMUIDX_BITS;
353
- int page = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
354
int mmu_idx;
355
356
assert_cpu_is_self(cpu);
357
358
- tlb_debug("page:%d addr:"TARGET_FMT_lx" mmu_idx:0x%lx\n",
359
- page, addr, mmu_idx_bitmap);
360
+ tlb_debug("flush page addr:"TARGET_FMT_lx" mmu_idx:0x%lx\n",
361
+ addr, mmu_idx_bitmap);
362
363
qemu_spin_lock(&env->tlb_lock);
364
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
365
if (test_bit(mmu_idx, &mmu_idx_bitmap)) {
366
- tlb_flush_entry_locked(&env->tlb_table[mmu_idx][page], addr);
367
+ tlb_flush_entry_locked(tlb_entry(env, mmu_idx, addr), addr);
368
tlb_flush_vtlb_page_locked(env, mmu_idx, addr);
369
}
370
}
371
@@ -XXX,XX +XXX,XX @@ static inline void tlb_set_dirty1_locked(CPUTLBEntry *tlb_entry,
372
void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
373
{
374
CPUArchState *env = cpu->env_ptr;
375
- int i;
376
int mmu_idx;
377
378
assert_cpu_is_self(cpu);
379
380
vaddr &= TARGET_PAGE_MASK;
381
- i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
382
qemu_spin_lock(&env->tlb_lock);
383
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
384
- tlb_set_dirty1_locked(&env->tlb_table[mmu_idx][i], vaddr);
385
+ tlb_set_dirty1_locked(tlb_entry(env, mmu_idx, vaddr), vaddr);
386
}
387
388
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
389
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
390
iotlb = memory_region_section_get_iotlb(cpu, section, vaddr_page,
391
paddr_page, xlat, prot, &address);
392
393
- index = (vaddr_page >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
394
- te = &env->tlb_table[mmu_idx][index];
395
+ index = tlb_index(env, mmu_idx, vaddr_page);
396
+ te = tlb_entry(env, mmu_idx, vaddr_page);
397
398
/*
399
* Hold the TLB lock for the rest of the function. We could acquire/release
400
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
401
* repeat the MMU check here. This tlb_fill() call might
402
* longjump out if this access should cause a guest exception.
403
*/
404
- int index;
405
+ CPUTLBEntry *entry;
406
target_ulong tlb_addr;
407
408
tlb_fill(cpu, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
409
410
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
411
- tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
412
+ entry = tlb_entry(env, mmu_idx, addr);
413
+ tlb_addr = entry->addr_read;
414
if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
415
/* RAM access */
416
- uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;
417
+ uintptr_t haddr = addr + entry->addend;
418
419
return ldn_p((void *)haddr, size);
420
}
421
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
422
* repeat the MMU check here. This tlb_fill() call might
423
* longjump out if this access should cause a guest exception.
424
*/
425
- int index;
426
+ CPUTLBEntry *entry;
427
target_ulong tlb_addr;
428
429
tlb_fill(cpu, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
430
431
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
432
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
433
+ entry = tlb_entry(env, mmu_idx, addr);
434
+ tlb_addr = entry->addr_write;
435
if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
436
/* RAM access */
437
- uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;
438
+ uintptr_t haddr = addr + entry->addend;
439
440
stn_p((void *)haddr, size, val);
441
return;
442
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
443
*/
444
tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
445
{
446
- int mmu_idx, index;
447
+ uintptr_t mmu_idx = cpu_mmu_index(env, true);
448
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
449
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
450
void *p;
451
452
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
453
- mmu_idx = cpu_mmu_index(env, true);
454
- if (unlikely(!tlb_hit(env->tlb_table[mmu_idx][index].addr_code, addr))) {
455
+ if (unlikely(!tlb_hit(entry->addr_code, addr))) {
456
if (!VICTIM_TLB_HIT(addr_code, addr)) {
457
tlb_fill(ENV_GET_CPU(env), addr, 0, MMU_INST_FETCH, mmu_idx, 0);
458
}
459
- assert(tlb_hit(env->tlb_table[mmu_idx][index].addr_code, addr));
460
+ assert(tlb_hit(entry->addr_code, addr));
461
}
462
463
- if (unlikely(env->tlb_table[mmu_idx][index].addr_code &
464
- (TLB_RECHECK | TLB_MMIO))) {
465
+ if (unlikely(entry->addr_code & (TLB_RECHECK | TLB_MMIO))) {
466
/*
467
* Return -1 if we can't translate and execute from an entire
468
* page of RAM here, which will cause us to execute by loading
469
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
470
return -1;
471
}
472
473
- p = (void *)((uintptr_t)addr + env->tlb_table[mmu_idx][index].addend);
474
+ p = (void *)((uintptr_t)addr + entry->addend);
475
return qemu_ram_addr_from_host_nofail(p);
476
}
477
478
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
479
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
480
uintptr_t retaddr)
481
{
482
- int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
483
- target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
484
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
485
+ CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
486
487
- if (!tlb_hit(tlb_addr, addr)) {
488
+ if (!tlb_hit(entry->addr_write, addr)) {
489
/* TLB entry is for a different page */
490
if (!VICTIM_TLB_HIT(addr_write, addr)) {
491
tlb_fill(ENV_GET_CPU(env), addr, size, MMU_DATA_STORE,
492
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
493
NotDirtyInfo *ndi)
494
{
495
size_t mmu_idx = get_mmuidx(oi);
496
- size_t index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
497
- CPUTLBEntry *tlbe = &env->tlb_table[mmu_idx][index];
498
+ uintptr_t index = tlb_index(env, mmu_idx, addr);
499
+ CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
500
target_ulong tlb_addr = tlbe->addr_write;
501
TCGMemOp mop = get_memop(oi);
502
int a_bits = get_alignment_bits(mop);
503
--
391
--
504
2.17.2
392
2.34.1
505
393
506
394
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
We will need a backend interface for performing 16-bit sign-extend.
2
Use it in tcg_reg_alloc_op in the meantime.
2
3
3
Paves the way for the addition of a per-TLB lock.
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Emilio G. Cota <cota@braap.org>
8
Message-Id: <20181009174557.16125-4-cota@braap.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/exec-all.h | 8 ++++++++
7
tcg/tcg.c | 7 +++++++
12
accel/tcg/cputlb.c | 4 ++++
8
tcg/aarch64/tcg-target.c.inc | 13 ++++++++-----
13
exec.c | 1 +
9
tcg/arm/tcg-target.c.inc | 10 ++++------
14
3 files changed, 13 insertions(+)
10
tcg/i386/tcg-target.c.inc | 16 ++++++++--------
11
tcg/loongarch64/tcg-target.c.inc | 13 +++++--------
12
tcg/mips/tcg-target.c.inc | 11 ++++++++---
13
tcg/ppc/tcg-target.c.inc | 12 +++++-------
14
tcg/riscv/tcg-target.c.inc | 9 +++------
15
tcg/s390x/tcg-target.c.inc | 12 ++++--------
16
tcg/sparc64/tcg-target.c.inc | 7 +++++++
17
tcg/tci/tcg-target.c.inc | 21 ++++++++++++++++++++-
18
11 files changed, 79 insertions(+), 52 deletions(-)
15
19
16
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
20
diff --git a/tcg/tcg.c b/tcg/tcg.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/include/exec/exec-all.h
22
--- a/tcg/tcg.c
19
+++ b/include/exec/exec-all.h
23
+++ b/tcg/tcg.c
20
@@ -XXX,XX +XXX,XX @@ void cpu_address_space_init(CPUState *cpu, int asidx,
24
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
21
25
static void tcg_out_movi(TCGContext *s, TCGType type,
22
#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
26
TCGReg ret, tcg_target_long arg);
23
/* cputlb.c */
27
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
24
+/**
28
+static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
25
+ * tlb_init - initialize a CPU's TLB
29
static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg);
26
+ * @cpu: CPU whose TLB should be initialized
30
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
27
+ */
31
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
28
+void tlb_init(CPUState *cpu);
32
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
29
/**
33
case INDEX_op_ext8u_i64:
30
* tlb_flush_page:
34
tcg_out_ext8u(s, new_args[0], new_args[1]);
31
* @cpu: CPU whose TLB should be flushed
35
break;
32
@@ -XXX,XX +XXX,XX @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
36
+ case INDEX_op_ext16s_i32:
33
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
37
+ tcg_out_ext16s(s, TCG_TYPE_I32, new_args[0], new_args[1]);
34
uintptr_t retaddr);
38
+ break;
35
#else
39
+ case INDEX_op_ext16s_i64:
36
+static inline void tlb_init(CPUState *cpu)
40
+ tcg_out_ext16s(s, TCG_TYPE_I64, new_args[0], new_args[1]);
41
+ break;
42
default:
43
if (def->flags & TCG_OPF_VECTOR) {
44
tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
45
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
46
index XXXXXXX..XXXXXXX 100644
47
--- a/tcg/aarch64/tcg-target.c.inc
48
+++ b/tcg/aarch64/tcg-target.c.inc
49
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn)
50
tcg_out_sxt(s, type, MO_8, rd, rn);
51
}
52
53
+static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn)
37
+{
54
+{
38
+}
55
+ tcg_out_sxt(s, type, MO_16, rd, rn);
39
static inline void tlb_flush_page(CPUState *cpu, target_ulong addr)
40
{
41
}
42
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/accel/tcg/cputlb.c
45
+++ b/accel/tcg/cputlb.c
46
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(sizeof(target_ulong) > sizeof(run_on_cpu_data));
47
QEMU_BUILD_BUG_ON(NB_MMU_MODES > 16);
48
#define ALL_MMUIDX_BITS ((1 << NB_MMU_MODES) - 1)
49
50
+void tlb_init(CPUState *cpu)
51
+{
52
+}
56
+}
53
+
57
+
54
/* flush_all_helper: run fn across all cpus
58
static inline void tcg_out_uxt(TCGContext *s, MemOp s_bits,
55
*
59
TCGReg rd, TCGReg rn)
56
* If the wait flag is set then the src cpu's helper will be queued as
60
{
57
diff --git a/exec.c b/exec.c
61
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
58
index XXXXXXX..XXXXXXX 100644
62
tcg_out_rev(s, TCG_TYPE_I32, MO_16, a0, a1);
59
--- a/exec.c
63
if (a2 & TCG_BSWAP_OS) {
60
+++ b/exec.c
64
/* Output must be sign-extended. */
61
@@ -XXX,XX +XXX,XX @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
65
- tcg_out_sxt(s, ext, MO_16, a0, a0);
62
tcg_target_initialized = true;
66
+ tcg_out_ext16s(s, ext, a0, a0);
63
cc->tcg_initialize();
67
} else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
64
}
68
/* Output must be zero-extended, but input isn't. */
65
+ tlb_init(cpu);
69
tcg_out_uxt(s, MO_16, a0, a0);
66
70
}
67
#ifndef CONFIG_USER_ONLY
71
break;
68
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
72
73
- case INDEX_op_ext16s_i64:
74
- case INDEX_op_ext16s_i32:
75
- tcg_out_sxt(s, ext, MO_16, a0, a1);
76
- break;
77
case INDEX_op_ext_i32_i64:
78
case INDEX_op_ext32s_i64:
79
tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1);
80
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
81
case INDEX_op_ext8s_i64:
82
case INDEX_op_ext8u_i32:
83
case INDEX_op_ext8u_i64:
84
+ case INDEX_op_ext16s_i64:
85
+ case INDEX_op_ext16s_i32:
86
default:
87
g_assert_not_reached();
88
}
89
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
90
index XXXXXXX..XXXXXXX 100644
91
--- a/tcg/arm/tcg-target.c.inc
92
+++ b/tcg/arm/tcg-target.c.inc
93
@@ -XXX,XX +XXX,XX @@ tcg_out_ext8u_cond(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn)
94
tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff);
95
}
96
97
-static void tcg_out_ext16s(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn)
98
+static void tcg_out_ext16s(TCGContext *s, TCGType t, TCGReg rd, TCGReg rn)
99
{
100
/* sxth */
101
- tcg_out32(s, 0x06bf0070 | (cond << 28) | (rd << 12) | rn);
102
+ tcg_out32(s, 0x06bf0070 | (COND_AL << 28) | (rd << 12) | rn);
103
}
104
105
static void tcg_out_ext16u(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn)
106
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
107
tcg_out_ext8s(s, TCG_TYPE_I32, datalo, TCG_REG_R0);
108
break;
109
case MO_SW:
110
- tcg_out_ext16s(s, COND_AL, datalo, TCG_REG_R0);
111
+ tcg_out_ext16s(s, TCG_TYPE_I32, datalo, TCG_REG_R0);
112
break;
113
default:
114
tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0);
115
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
116
tcg_out_bswap32(s, COND_AL, args[0], args[1]);
117
break;
118
119
- case INDEX_op_ext16s_i32:
120
- tcg_out_ext16s(s, COND_AL, args[0], args[1]);
121
- break;
122
case INDEX_op_ext16u_i32:
123
tcg_out_ext16u(s, COND_AL, args[0], args[1]);
124
break;
125
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
126
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
127
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
128
case INDEX_op_ext8u_i32:
129
+ case INDEX_op_ext16s_i32:
130
default:
131
g_assert_not_reached();
132
}
133
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
134
index XXXXXXX..XXXXXXX 100644
135
--- a/tcg/i386/tcg-target.c.inc
136
+++ b/tcg/i386/tcg-target.c.inc
137
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
138
tcg_out_modrm(s, OPC_MOVZWL, dest, src);
139
}
140
141
-static inline void tcg_out_ext16s(TCGContext *s, int dest, int src, int rexw)
142
+static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
143
{
144
+ int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW;
145
/* movsw[lq] */
146
tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src);
147
}
148
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
149
MemOp opc = get_memop(oi);
150
TCGReg data_reg;
151
tcg_insn_unit **label_ptr = &l->label_ptr[0];
152
- int rexw = (l->type == TCG_TYPE_I64 ? P_REXW : 0);
153
154
/* resolve label address */
155
tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4);
156
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
157
tcg_out_ext8s(s, l->type, data_reg, TCG_REG_EAX);
158
break;
159
case MO_SW:
160
- tcg_out_ext16s(s, data_reg, TCG_REG_EAX, rexw);
161
+ tcg_out_ext16s(s, l->type, data_reg, TCG_REG_EAX);
162
break;
163
#if TCG_TARGET_REG_BITS == 64
164
case MO_SL:
165
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
166
TCGReg base, int index, intptr_t ofs,
167
int seg, bool is64, MemOp memop)
168
{
169
+ TCGType type = is64 ? TCG_TYPE_I64 : TCG_TYPE_I32;
170
bool use_movbe = false;
171
int rexw = is64 * P_REXW;
172
int movop = OPC_MOVL_GvEv;
173
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
174
if (use_movbe) {
175
tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
176
datalo, base, index, 0, ofs);
177
- tcg_out_ext16s(s, datalo, datalo, rexw);
178
+ tcg_out_ext16s(s, type, datalo, datalo);
179
} else {
180
tcg_out_modrm_sib_offset(s, OPC_MOVSWL + rexw + seg,
181
datalo, base, index, 0, ofs);
182
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
183
tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0);
184
break;
185
186
- OP_32_64(ext16s):
187
- tcg_out_ext16s(s, a0, a1, rexw);
188
- break;
189
OP_32_64(ext16u):
190
tcg_out_ext16u(s, a0, a1);
191
break;
192
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
193
if (a1 < 4 && a0 < 8) {
194
tcg_out_modrm(s, OPC_MOVSBL, a0, a1 + 4);
195
} else {
196
- tcg_out_ext16s(s, a0, a1, 0);
197
+ tcg_out_ext16s(s, TCG_TYPE_I32, a0, a1);
198
tcg_out_shifti(s, SHIFT_SAR, a0, 8);
199
}
200
break;
201
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
202
case INDEX_op_ext8s_i64:
203
case INDEX_op_ext8u_i32:
204
case INDEX_op_ext8u_i64:
205
+ case INDEX_op_ext16s_i32:
206
+ case INDEX_op_ext16s_i64:
207
default:
208
g_assert_not_reached();
209
}
210
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
211
index XXXXXXX..XXXXXXX 100644
212
--- a/tcg/loongarch64/tcg-target.c.inc
213
+++ b/tcg/loongarch64/tcg-target.c.inc
214
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
215
tcg_out_opc_sext_b(s, ret, arg);
216
}
217
218
-static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
219
+static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
220
{
221
tcg_out_opc_sext_h(s, ret, arg);
222
}
223
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
224
tcg_out_ext8s(s, type, l->datalo_reg, TCG_REG_A0);
225
break;
226
case MO_SW:
227
- tcg_out_ext16s(s, l->datalo_reg, TCG_REG_A0);
228
+ tcg_out_ext16s(s, type, l->datalo_reg, TCG_REG_A0);
229
break;
230
case MO_SL:
231
tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0);
232
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
233
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
234
break;
235
236
- case INDEX_op_ext16s_i32:
237
- case INDEX_op_ext16s_i64:
238
- tcg_out_ext16s(s, a0, a1);
239
- break;
240
-
241
case INDEX_op_ext16u_i32:
242
case INDEX_op_ext16u_i64:
243
tcg_out_ext16u(s, a0, a1);
244
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
245
case INDEX_op_bswap16_i64:
246
tcg_out_opc_revb_2h(s, a0, a1);
247
if (a2 & TCG_BSWAP_OS) {
248
- tcg_out_ext16s(s, a0, a0);
249
+ tcg_out_ext16s(s, TCG_TYPE_REG, a0, a0);
250
} else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
251
tcg_out_ext16u(s, a0, a0);
252
}
253
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
254
case INDEX_op_ext8s_i64:
255
case INDEX_op_ext8u_i32:
256
case INDEX_op_ext8u_i64:
257
+ case INDEX_op_ext16s_i32:
258
+ case INDEX_op_ext16s_i64:
259
default:
260
g_assert_not_reached();
261
}
262
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
263
index XXXXXXX..XXXXXXX 100644
264
--- a/tcg/mips/tcg-target.c.inc
265
+++ b/tcg/mips/tcg-target.c.inc
266
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
267
tcg_out_opc_imm(s, OPC_ANDI, rd, rs, 0xff);
268
}
269
270
+static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
271
+{
272
+ tcg_debug_assert(TCG_TARGET_HAS_ext16s_i32);
273
+ tcg_out_opc_reg(s, OPC_SEH, rd, TCG_REG_ZERO, rs);
274
+}
275
+
276
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
277
tcg_target_long imm)
278
{
279
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
280
case INDEX_op_not_i64:
281
i1 = OPC_NOR;
282
goto do_unary;
283
- case INDEX_op_ext16s_i32:
284
- case INDEX_op_ext16s_i64:
285
- i1 = OPC_SEH;
286
do_unary:
287
tcg_out_opc_reg(s, i1, a0, TCG_REG_ZERO, a1);
288
break;
289
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
290
case INDEX_op_ext8s_i64:
291
case INDEX_op_ext8u_i32:
292
case INDEX_op_ext8u_i64:
293
+ case INDEX_op_ext16s_i32:
294
+ case INDEX_op_ext16s_i64:
295
default:
296
g_assert_not_reached();
297
}
298
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
299
index XXXXXXX..XXXXXXX 100644
300
--- a/tcg/ppc/tcg-target.c.inc
301
+++ b/tcg/ppc/tcg-target.c.inc
302
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8u(TCGContext *s, TCGReg dst, TCGReg src)
303
tcg_out32(s, ANDI | SAI(src, dst, 0xff));
304
}
305
306
-static inline void tcg_out_ext16s(TCGContext *s, TCGReg dst, TCGReg src)
307
+static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
308
{
309
tcg_out32(s, EXTSH | RA(dst) | RS(src));
310
}
311
@@ -XXX,XX +XXX,XX @@ static void tcg_out_bswap16(TCGContext *s, TCGReg dst, TCGReg src, int flags)
312
if (have_isa_3_10) {
313
tcg_out32(s, BRH | RA(dst) | RS(src));
314
if (flags & TCG_BSWAP_OS) {
315
- tcg_out_ext16s(s, dst, dst);
316
+ tcg_out_ext16s(s, TCG_TYPE_REG, dst, dst);
317
} else if ((flags & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
318
tcg_out_ext16u(s, dst, dst);
319
}
320
@@ -XXX,XX +XXX,XX @@ static void tcg_out_bswap16(TCGContext *s, TCGReg dst, TCGReg src, int flags)
321
tcg_out_rlw(s, RLWIMI, tmp, src, 8, 16, 23);
322
323
if (flags & TCG_BSWAP_OS) {
324
- tcg_out_ext16s(s, dst, tmp);
325
+ tcg_out_ext16s(s, TCG_TYPE_REG, dst, tmp);
326
} else {
327
tcg_out_mov(s, TCG_TYPE_REG, dst, tmp);
328
}
329
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
330
tcg_out_qemu_st(s, args, true);
331
break;
332
333
- case INDEX_op_ext16s_i32:
334
- case INDEX_op_ext16s_i64:
335
- tcg_out_ext16s(s, args[0], args[1]);
336
- break;
337
case INDEX_op_ext_i32_i64:
338
case INDEX_op_ext32s_i64:
339
tcg_out_ext32s(s, args[0], args[1]);
340
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
341
case INDEX_op_ext8s_i64:
342
case INDEX_op_ext8u_i32:
343
case INDEX_op_ext8u_i64:
344
+ case INDEX_op_ext16s_i32:
345
+ case INDEX_op_ext16s_i64:
346
default:
347
g_assert_not_reached();
348
}
349
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
350
index XXXXXXX..XXXXXXX 100644
351
--- a/tcg/riscv/tcg-target.c.inc
352
+++ b/tcg/riscv/tcg-target.c.inc
353
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
354
tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24);
355
}
356
357
-static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
358
+static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
359
{
360
tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16);
361
tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 16);
362
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
363
tcg_out_ext32u(s, a0, a1);
364
break;
365
366
- case INDEX_op_ext16s_i32:
367
- case INDEX_op_ext16s_i64:
368
- tcg_out_ext16s(s, a0, a1);
369
- break;
370
-
371
case INDEX_op_ext32s_i64:
372
case INDEX_op_extrl_i64_i32:
373
case INDEX_op_ext_i32_i64:
374
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
375
case INDEX_op_ext8s_i64:
376
case INDEX_op_ext8u_i32:
377
case INDEX_op_ext8u_i64:
378
+ case INDEX_op_ext16s_i32:
379
+ case INDEX_op_ext16s_i64:
380
default:
381
g_assert_not_reached();
382
}
383
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
384
index XXXXXXX..XXXXXXX 100644
385
--- a/tcg/s390x/tcg-target.c.inc
386
+++ b/tcg/s390x/tcg-target.c.inc
387
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8u(TCGContext *s, TCGReg dest, TCGReg src)
388
tcg_out_insn(s, RRE, LLGCR, dest, src);
389
}
390
391
-static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
392
+static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
393
{
394
tcg_out_insn(s, RRE, LGHR, dest, src);
395
}
396
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
397
case MO_SW | MO_BSWAP:
398
/* swapped sign-extended halfword load */
399
tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
400
- tgen_ext16s(s, TCG_TYPE_I64, data, data);
401
+ tcg_out_ext16s(s, TCG_TYPE_REG, data, data);
402
break;
403
case MO_SW:
404
tcg_out_insn(s, RXY, LGH, data, base, index, disp);
405
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
406
}
407
break;
408
409
- case INDEX_op_ext16s_i32:
410
- tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
411
- break;
412
case INDEX_op_ext16u_i32:
413
tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
414
break;
415
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
416
}
417
break;
418
419
- case INDEX_op_ext16s_i64:
420
- tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
421
- break;
422
case INDEX_op_ext_i32_i64:
423
case INDEX_op_ext32s_i64:
424
tgen_ext32s(s, args[0], args[1]);
425
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
426
case INDEX_op_ext8s_i64:
427
case INDEX_op_ext8u_i32:
428
case INDEX_op_ext8u_i64:
429
+ case INDEX_op_ext16s_i32:
430
+ case INDEX_op_ext16s_i64:
431
default:
432
g_assert_not_reached();
433
}
434
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
435
index XXXXXXX..XXXXXXX 100644
436
--- a/tcg/sparc64/tcg-target.c.inc
437
+++ b/tcg/sparc64/tcg-target.c.inc
438
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
439
g_assert_not_reached();
440
}
441
442
+static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
443
+{
444
+ g_assert_not_reached();
445
+}
446
+
447
static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
448
{
449
tcg_out_arithi(s, rd, rs, 0xff, ARITH_AND);
450
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
451
case INDEX_op_ext8s_i64:
452
case INDEX_op_ext8u_i32:
453
case INDEX_op_ext8u_i64:
454
+ case INDEX_op_ext16s_i32:
455
+ case INDEX_op_ext16s_i64:
456
default:
457
g_assert_not_reached();
458
}
459
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
460
index XXXXXXX..XXXXXXX 100644
461
--- a/tcg/tci/tcg-target.c.inc
462
+++ b/tcg/tci/tcg-target.c.inc
463
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
464
}
465
}
466
467
+static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
468
+{
469
+ switch (type) {
470
+ case TCG_TYPE_I32:
471
+ tcg_debug_assert(TCG_TARGET_HAS_ext16s_i32);
472
+ tcg_out_op_rr(s, INDEX_op_ext16s_i32, rd, rs);
473
+ break;
474
+#if TCG_TARGET_REG_BITS == 64
475
+ case TCG_TYPE_I64:
476
+ tcg_debug_assert(TCG_TARGET_HAS_ext16s_i64);
477
+ tcg_out_op_rr(s, INDEX_op_ext16s_i64, rd, rs);
478
+ break;
479
+#endif
480
+ default:
481
+ g_assert_not_reached();
482
+ }
483
+}
484
+
485
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
486
tcg_target_long imm)
487
{
488
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
489
490
CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
491
CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */
492
- CASE_32_64(ext16s) /* Optional (TCG_TARGET_HAS_ext16s_*). */
493
CASE_32_64(ext16u) /* Optional (TCG_TARGET_HAS_ext16u_*). */
494
CASE_64(ext32s) /* Optional (TCG_TARGET_HAS_ext32s_i64). */
495
CASE_64(ext32u) /* Optional (TCG_TARGET_HAS_ext32u_i64). */
496
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
497
case INDEX_op_ext8s_i64:
498
case INDEX_op_ext8u_i32:
499
case INDEX_op_ext8u_i64:
500
+ case INDEX_op_ext16s_i32:
501
+ case INDEX_op_ext16s_i64:
502
default:
503
g_assert_not_reached();
504
}
69
--
505
--
70
2.17.2
506
2.34.1
71
507
72
508
diff view generated by jsdifflib
1
GCC7+ will no longer advertise support for 16-byte __atomic operations
1
We will need a backend interface for performing 16-bit zero-extend.
2
if only cmpxchg is supported, as for x86_64. Fortunately, x86_64 still
2
Use it in tcg_reg_alloc_op in the meantime.
3
has support for __sync_compare_and_swap_16 and we can make use of that.
4
AArch64 does not have, nor ever has had such support, so open-code it.
5
3
6
Reviewed-by: Emilio G. Cota <cota@braap.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
6
---
9
accel/tcg/atomic_template.h | 20 ++++-
7
tcg/tcg.c | 5 +++++
10
include/qemu/atomic128.h | 155 ++++++++++++++++++++++++++++++++++++
8
tcg/aarch64/tcg-target.c.inc | 13 ++++++++-----
11
tcg/tcg.h | 16 ++--
9
tcg/arm/tcg-target.c.inc | 17 ++++++++++-------
12
accel/tcg/cputlb.c | 3 +-
10
tcg/i386/tcg-target.c.inc | 8 +++-----
13
accel/tcg/user-exec.c | 5 +-
11
tcg/loongarch64/tcg-target.c.inc | 7 ++-----
14
configure | 19 +++++
12
tcg/mips/tcg-target.c.inc | 5 +++++
15
6 files changed, 204 insertions(+), 14 deletions(-)
13
tcg/ppc/tcg-target.c.inc | 4 +++-
16
create mode 100644 include/qemu/atomic128.h
14
tcg/riscv/tcg-target.c.inc | 7 ++-----
15
tcg/s390x/tcg-target.c.inc | 17 ++++++-----------
16
tcg/sparc64/tcg-target.c.inc | 11 +++++++++--
17
tcg/tci/tcg-target.c.inc | 14 +++++++++++++-
18
11 files changed, 66 insertions(+), 42 deletions(-)
17
19
18
diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
20
diff --git a/tcg/tcg.c b/tcg/tcg.c
19
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
20
--- a/accel/tcg/atomic_template.h
22
--- a/tcg/tcg.c
21
+++ b/accel/tcg/atomic_template.h
23
+++ b/tcg/tcg.c
22
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type,
23
DATA_TYPE ret;
25
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
24
26
static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
25
ATOMIC_TRACE_RMW;
27
static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg);
26
+#if DATA_SIZE == 16
28
+static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg);
27
+ ret = atomic16_cmpxchg(haddr, cmpv, newv);
29
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
28
+#else
30
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
29
ret = atomic_cmpxchg__nocheck(haddr, cmpv, newv);
31
static void tcg_out_goto_tb(TCGContext *s, int which);
30
+#endif
32
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
31
ATOMIC_MMU_CLEANUP;
33
case INDEX_op_ext16s_i64:
32
return ret;
34
tcg_out_ext16s(s, TCG_TYPE_I64, new_args[0], new_args[1]);
33
}
35
break;
34
36
+ case INDEX_op_ext16u_i32:
35
#if DATA_SIZE >= 16
37
+ case INDEX_op_ext16u_i64:
36
+#if HAVE_ATOMIC128
38
+ tcg_out_ext16u(s, new_args[0], new_args[1]);
37
ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
39
+ break;
38
{
40
default:
39
ATOMIC_MMU_DECLS;
41
if (def->flags & TCG_OPF_VECTOR) {
40
DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
42
tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
41
43
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
42
ATOMIC_TRACE_LD;
44
index XXXXXXX..XXXXXXX 100644
43
- __atomic_load(haddr, &val, __ATOMIC_RELAXED);
45
--- a/tcg/aarch64/tcg-target.c.inc
44
+ val = atomic16_read(haddr);
46
+++ b/tcg/aarch64/tcg-target.c.inc
45
ATOMIC_MMU_CLEANUP;
47
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rn)
46
return val;
48
tcg_out_uxt(s, MO_8, rd, rn);
47
}
49
}
48
@@ -XXX,XX +XXX,XX @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
50
49
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
51
+static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rn)
50
51
ATOMIC_TRACE_ST;
52
- __atomic_store(haddr, &val, __ATOMIC_RELAXED);
53
+ atomic16_set(haddr, val);
54
ATOMIC_MMU_CLEANUP;
55
}
56
+#endif
57
#else
58
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
59
ABI_TYPE val EXTRA_ARGS)
60
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
61
DATA_TYPE ret;
62
63
ATOMIC_TRACE_RMW;
64
+#if DATA_SIZE == 16
65
+ ret = atomic16_cmpxchg(haddr, BSWAP(cmpv), BSWAP(newv));
66
+#else
67
ret = atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv));
68
+#endif
69
ATOMIC_MMU_CLEANUP;
70
return BSWAP(ret);
71
}
72
73
#if DATA_SIZE >= 16
74
+#if HAVE_ATOMIC128
75
ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
76
{
77
ATOMIC_MMU_DECLS;
78
DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
79
80
ATOMIC_TRACE_LD;
81
- __atomic_load(haddr, &val, __ATOMIC_RELAXED);
82
+ val = atomic16_read(haddr);
83
ATOMIC_MMU_CLEANUP;
84
return BSWAP(val);
85
}
86
@@ -XXX,XX +XXX,XX @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
87
88
ATOMIC_TRACE_ST;
89
val = BSWAP(val);
90
- __atomic_store(haddr, &val, __ATOMIC_RELAXED);
91
+ atomic16_set(haddr, val);
92
ATOMIC_MMU_CLEANUP;
93
}
94
+#endif
95
#else
96
ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
97
ABI_TYPE val EXTRA_ARGS)
98
diff --git a/include/qemu/atomic128.h b/include/qemu/atomic128.h
99
new file mode 100644
100
index XXXXXXX..XXXXXXX
101
--- /dev/null
102
+++ b/include/qemu/atomic128.h
103
@@ -XXX,XX +XXX,XX @@
104
+/*
105
+ * Simple interface for 128-bit atomic operations.
106
+ *
107
+ * Copyright (C) 2018 Linaro, Ltd.
108
+ *
109
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
110
+ * See the COPYING file in the top-level directory.
111
+ *
112
+ * See docs/devel/atomics.txt for discussion about the guarantees each
113
+ * atomic primitive is meant to provide.
114
+ */
115
+
116
+#ifndef QEMU_ATOMIC128_H
117
+#define QEMU_ATOMIC128_H
118
+
119
+/*
120
+ * GCC is a house divided about supporting large atomic operations.
121
+ *
122
+ * For hosts that only have large compare-and-swap, a legalistic reading
123
+ * of the C++ standard means that one cannot implement __atomic_read on
124
+ * read-only memory, and thus all atomic operations must synchronize
125
+ * through libatomic.
126
+ *
127
+ * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878
128
+ *
129
+ * This interpretation is not especially helpful for QEMU.
130
+ * For softmmu, all RAM is always read/write from the hypervisor.
131
+ * For user-only, if the guest doesn't implement such an __atomic_read
132
+ * then the host need not worry about it either.
133
+ *
134
+ * Moreover, using libatomic is not an option, because its interface is
135
+ * built for std::atomic<T>, and requires that *all* accesses to such an
136
+ * object go through the library. In our case we do not have an object
137
+ * in the C/C++ sense, but a view of memory as seen by the guest.
138
+ * The guest may issue a large atomic operation and then access those
139
+ * pieces using word-sized accesses. From the hypervisor, we have no
140
+ * way to connect those two actions.
141
+ *
142
+ * Therefore, special case each platform.
143
+ */
144
+
145
+#if defined(CONFIG_ATOMIC128)
146
+static inline Int128 atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
147
+{
52
+{
148
+ return atomic_cmpxchg__nocheck(ptr, cmp, new);
53
+ tcg_out_uxt(s, MO_16, rd, rn);
149
+}
150
+# define HAVE_CMPXCHG128 1
151
+#elif defined(CONFIG_CMPXCHG128)
152
+static inline Int128 atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
153
+{
154
+ return __sync_val_compare_and_swap_16(ptr, cmp, new);
155
+}
156
+# define HAVE_CMPXCHG128 1
157
+#elif defined(__aarch64__)
158
+/* Through gcc 8, aarch64 has no support for 128-bit at all. */
159
+static inline Int128 atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
160
+{
161
+ uint64_t cmpl = int128_getlo(cmp), cmph = int128_gethi(cmp);
162
+ uint64_t newl = int128_getlo(new), newh = int128_gethi(new);
163
+ uint64_t oldl, oldh;
164
+ uint32_t tmp;
165
+
166
+ asm("0: ldaxp %[oldl], %[oldh], %[mem]\n\t"
167
+ "cmp %[oldl], %[cmpl]\n\t"
168
+ "ccmp %[oldh], %[cmph], #0, eq\n\t"
169
+ "b.ne 1f\n\t"
170
+ "stlxp %w[tmp], %[newl], %[newh], %[mem]\n\t"
171
+ "cbnz %w[tmp], 0b\n"
172
+ "1:"
173
+ : [mem] "+m"(*ptr), [tmp] "=&r"(tmp),
174
+ [oldl] "=&r"(oldl), [oldh] "=r"(oldh)
175
+ : [cmpl] "r"(cmpl), [cmph] "r"(cmph),
176
+ [newl] "r"(newl), [newh] "r"(newh)
177
+ : "memory", "cc");
178
+
179
+ return int128_make128(oldl, oldh);
180
+}
181
+# define HAVE_CMPXCHG128 1
182
+#else
183
+/* Fallback definition that must be optimized away, or error. */
184
+Int128 __attribute__((error("unsupported atomic")))
185
+ atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new);
186
+# define HAVE_CMPXCHG128 0
187
+#endif /* Some definition for HAVE_CMPXCHG128 */
188
+
189
+
190
+#if defined(CONFIG_ATOMIC128)
191
+static inline Int128 atomic16_read(Int128 *ptr)
192
+{
193
+ return atomic_read__nocheck(ptr);
194
+}
54
+}
195
+
55
+
196
+static inline void atomic16_set(Int128 *ptr, Int128 val)
56
static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd,
57
TCGReg rn, int64_t aimm)
58
{
59
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
60
tcg_out_ext16s(s, ext, a0, a0);
61
} else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
62
/* Output must be zero-extended, but input isn't. */
63
- tcg_out_uxt(s, MO_16, a0, a0);
64
+ tcg_out_ext16u(s, a0, a0);
65
}
66
break;
67
68
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
69
case INDEX_op_ext32s_i64:
70
tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1);
71
break;
72
- case INDEX_op_ext16u_i64:
73
- case INDEX_op_ext16u_i32:
74
- tcg_out_uxt(s, MO_16, a0, a1);
75
- break;
76
case INDEX_op_extu_i32_i64:
77
case INDEX_op_ext32u_i64:
78
tcg_out_movr(s, TCG_TYPE_I32, a0, a1);
79
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
80
case INDEX_op_ext8u_i64:
81
case INDEX_op_ext16s_i64:
82
case INDEX_op_ext16s_i32:
83
+ case INDEX_op_ext16u_i64:
84
+ case INDEX_op_ext16u_i32:
85
default:
86
g_assert_not_reached();
87
}
88
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
89
index XXXXXXX..XXXXXXX 100644
90
--- a/tcg/arm/tcg-target.c.inc
91
+++ b/tcg/arm/tcg-target.c.inc
92
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16s(TCGContext *s, TCGType t, TCGReg rd, TCGReg rn)
93
tcg_out32(s, 0x06bf0070 | (COND_AL << 28) | (rd << 12) | rn);
94
}
95
96
-static void tcg_out_ext16u(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn)
97
+static void tcg_out_ext16u_cond(TCGContext *s, ARMCond cond,
98
+ TCGReg rd, TCGReg rn)
99
{
100
/* uxth */
101
tcg_out32(s, 0x06ff0070 | (cond << 28) | (rd << 12) | rn);
102
}
103
104
+static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rn)
197
+{
105
+{
198
+ atomic_set__nocheck(ptr, val);
106
+ tcg_out_ext16u_cond(s, COND_AL, rd, rn);
199
+}
107
+}
200
+
108
+
201
+# define HAVE_ATOMIC128 1
109
static void tcg_out_bswap16(TCGContext *s, ARMCond cond,
202
+#elif !defined(CONFIG_USER_ONLY) && defined(__aarch64__)
110
TCGReg rd, TCGReg rn, int flags)
203
+/* We can do better than cmpxchg for AArch64. */
111
{
204
+static inline Int128 atomic16_read(Int128 *ptr)
112
@@ -XXX,XX +XXX,XX @@ DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t, tcg_out_movi32,
113
(tcg_out_movi32(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
114
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg, tcg_out_ext8u_cond,
115
(tcg_out_ext8u_cond(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
116
-DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg, tcg_out_ext16u,
117
- (tcg_out_ext16u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
118
+DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg, tcg_out_ext16u_cond,
119
+ (tcg_out_ext16u_cond(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
120
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg32, TCGReg, tcg_out_mov_reg, )
121
122
static TCGReg tcg_out_arg_reg64(TCGContext *s, TCGReg argreg,
123
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
124
tcg_out_bswap32(s, COND_AL, args[0], args[1]);
125
break;
126
127
- case INDEX_op_ext16u_i32:
128
- tcg_out_ext16u(s, COND_AL, args[0], args[1]);
129
- break;
130
-
131
case INDEX_op_deposit_i32:
132
tcg_out_deposit(s, COND_AL, args[0], args[2],
133
args[3], args[4], const_args[2]);
134
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
135
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
136
case INDEX_op_ext8u_i32:
137
case INDEX_op_ext16s_i32:
138
+ case INDEX_op_ext16u_i32:
139
default:
140
g_assert_not_reached();
141
}
142
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/tcg/i386/tcg-target.c.inc
145
+++ b/tcg/i386/tcg-target.c.inc
146
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
147
tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src);
148
}
149
150
-static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
151
+static void tcg_out_ext16u(TCGContext *s, TCGReg dest, TCGReg src)
152
{
153
/* movzwl */
154
tcg_out_modrm(s, OPC_MOVZWL, dest, src);
155
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
156
tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0);
157
break;
158
159
- OP_32_64(ext16u):
160
- tcg_out_ext16u(s, a0, a1);
161
- break;
162
-
163
case INDEX_op_qemu_ld_i32:
164
tcg_out_qemu_ld(s, args, 0);
165
break;
166
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
167
case INDEX_op_ext8u_i64:
168
case INDEX_op_ext16s_i32:
169
case INDEX_op_ext16s_i64:
170
+ case INDEX_op_ext16u_i32:
171
+ case INDEX_op_ext16u_i64:
172
default:
173
g_assert_not_reached();
174
}
175
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
176
index XXXXXXX..XXXXXXX 100644
177
--- a/tcg/loongarch64/tcg-target.c.inc
178
+++ b/tcg/loongarch64/tcg-target.c.inc
179
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
180
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
181
break;
182
183
- case INDEX_op_ext16u_i32:
184
- case INDEX_op_ext16u_i64:
185
- tcg_out_ext16u(s, a0, a1);
186
- break;
187
-
188
case INDEX_op_ext32u_i64:
189
case INDEX_op_extu_i32_i64:
190
tcg_out_ext32u(s, a0, a1);
191
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
192
case INDEX_op_ext8u_i64:
193
case INDEX_op_ext16s_i32:
194
case INDEX_op_ext16s_i64:
195
+ case INDEX_op_ext16u_i32:
196
+ case INDEX_op_ext16u_i64:
197
default:
198
g_assert_not_reached();
199
}
200
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
201
index XXXXXXX..XXXXXXX 100644
202
--- a/tcg/mips/tcg-target.c.inc
203
+++ b/tcg/mips/tcg-target.c.inc
204
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
205
tcg_out_opc_reg(s, OPC_SEH, rd, TCG_REG_ZERO, rs);
206
}
207
208
+static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs)
205
+{
209
+{
206
+ uint64_t l, h;
210
+ tcg_out_opc_imm(s, OPC_ANDI, rd, rs, 0xffff);
207
+ uint32_t tmp;
208
+
209
+ /* The load must be paired with the store to guarantee not tearing. */
210
+ asm("0: ldxp %[l], %[h], %[mem]\n\t"
211
+ "stxp %w[tmp], %[l], %[h], %[mem]\n\t"
212
+ "cbnz %w[tmp], 0b"
213
+ : [mem] "+m"(*ptr), [tmp] "=r"(tmp), [l] "=r"(l), [h] "=r"(h));
214
+
215
+ return int128_make128(l, h);
216
+}
211
+}
217
+
212
+
218
+static inline void atomic16_set(Int128 *ptr, Int128 val)
213
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
214
tcg_target_long imm)
215
{
216
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
217
index XXXXXXX..XXXXXXX 100644
218
--- a/tcg/ppc/tcg-target.c.inc
219
+++ b/tcg/ppc/tcg-target.c.inc
220
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
221
tcg_out32(s, EXTSH | RA(dst) | RS(src));
222
}
223
224
-static inline void tcg_out_ext16u(TCGContext *s, TCGReg dst, TCGReg src)
225
+static void tcg_out_ext16u(TCGContext *s, TCGReg dst, TCGReg src)
226
{
227
tcg_out32(s, ANDI | SAI(src, dst, 0xffff));
228
}
229
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
230
case INDEX_op_ext8u_i64:
231
case INDEX_op_ext16s_i32:
232
case INDEX_op_ext16s_i64:
233
+ case INDEX_op_ext16u_i32:
234
+ case INDEX_op_ext16u_i64:
235
default:
236
g_assert_not_reached();
237
}
238
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
239
index XXXXXXX..XXXXXXX 100644
240
--- a/tcg/riscv/tcg-target.c.inc
241
+++ b/tcg/riscv/tcg-target.c.inc
242
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
243
tcg_out_qemu_st(s, args, true);
244
break;
245
246
- case INDEX_op_ext16u_i32:
247
- case INDEX_op_ext16u_i64:
248
- tcg_out_ext16u(s, a0, a1);
249
- break;
250
-
251
case INDEX_op_ext32u_i64:
252
case INDEX_op_extu_i32_i64:
253
tcg_out_ext32u(s, a0, a1);
254
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
255
case INDEX_op_ext8u_i64:
256
case INDEX_op_ext16s_i32:
257
case INDEX_op_ext16s_i64:
258
+ case INDEX_op_ext16u_i32:
259
+ case INDEX_op_ext16u_i64:
260
default:
261
g_assert_not_reached();
262
}
263
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
264
index XXXXXXX..XXXXXXX 100644
265
--- a/tcg/s390x/tcg-target.c.inc
266
+++ b/tcg/s390x/tcg-target.c.inc
267
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
268
tcg_out_insn(s, RRE, LGHR, dest, src);
269
}
270
271
-static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
272
+static void tcg_out_ext16u(TCGContext *s, TCGReg dest, TCGReg src)
273
{
274
tcg_out_insn(s, RRE, LLGHR, dest, src);
275
}
276
@@ -XXX,XX +XXX,XX @@ static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
277
return;
278
}
279
if ((val & valid) == 0xffff) {
280
- tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
281
+ tcg_out_ext16u(s, dest, dest);
282
return;
283
}
284
285
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
286
case MO_UW | MO_BSWAP:
287
/* swapped unsigned halfword load with upper bits zeroed */
288
tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
289
- tgen_ext16u(s, TCG_TYPE_I64, data, data);
290
+ tcg_out_ext16u(s, data, data);
291
break;
292
case MO_UW:
293
tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
294
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
295
tcg_out_ext8u(s, TCG_REG_R4, data_reg);
296
break;
297
case MO_UW:
298
- tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
299
+ tcg_out_ext16u(s, TCG_REG_R4, data_reg);
300
break;
301
case MO_UL:
302
tgen_ext32u(s, TCG_REG_R4, data_reg);
303
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
304
}
305
break;
306
307
- case INDEX_op_ext16u_i32:
308
- tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
309
- break;
310
-
311
case INDEX_op_bswap16_i32:
312
a0 = args[0], a1 = args[1], a2 = args[2];
313
tcg_out_insn(s, RRE, LRVR, a0, a1);
314
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
315
case INDEX_op_ext32s_i64:
316
tgen_ext32s(s, args[0], args[1]);
317
break;
318
- case INDEX_op_ext16u_i64:
319
- tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
320
- break;
321
case INDEX_op_extu_i32_i64:
322
case INDEX_op_ext32u_i64:
323
tgen_ext32u(s, args[0], args[1]);
324
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
325
case INDEX_op_ext8u_i64:
326
case INDEX_op_ext16s_i32:
327
case INDEX_op_ext16s_i64:
328
+ case INDEX_op_ext16u_i32:
329
+ case INDEX_op_ext16u_i64:
330
default:
331
g_assert_not_reached();
332
}
333
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
334
index XXXXXXX..XXXXXXX 100644
335
--- a/tcg/sparc64/tcg-target.c.inc
336
+++ b/tcg/sparc64/tcg-target.c.inc
337
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
338
tcg_out_arithi(s, rd, rs, 0xff, ARITH_AND);
339
}
340
341
+static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs)
219
+{
342
+{
220
+ uint64_t l = int128_getlo(val), h = int128_gethi(val);
343
+ tcg_out_arithi(s, rd, rs, 16, SHIFT_SLL);
221
+ uint64_t t1, t2;
344
+ tcg_out_arithi(s, rd, rd, 16, SHIFT_SRL);
222
+
223
+ /* Load into temporaries to acquire the exclusive access lock. */
224
+ asm("0: ldxp %[t1], %[t2], %[mem]\n\t"
225
+ "stxp %w[t1], %[l], %[h], %[mem]\n\t"
226
+ "cbnz %w[t1], 0b"
227
+ : [mem] "+m"(*ptr), [t1] "=&r"(t1), [t2] "=&r"(t2)
228
+ : [l] "r"(l), [h] "r"(h));
229
+}
345
+}
230
+
346
+
231
+# define HAVE_ATOMIC128 1
347
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
232
+#elif !defined(CONFIG_USER_ONLY) && HAVE_CMPXCHG128
348
tcg_target_long imm)
233
+static inline Int128 atomic16_read(Int128 *ptr)
349
{
350
@@ -XXX,XX +XXX,XX @@ static void emit_extend(TCGContext *s, TCGReg r, int op)
351
tcg_out_ext8u(s, r, r);
352
break;
353
case MO_16:
354
- tcg_out_arithi(s, r, r, 16, SHIFT_SLL);
355
- tcg_out_arithi(s, r, r, 16, SHIFT_SRL);
356
+ tcg_out_ext16u(s, r, r);
357
break;
358
case MO_32:
359
tcg_out_arith(s, r, r, 0, SHIFT_SRL);
360
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
361
case INDEX_op_ext8u_i64:
362
case INDEX_op_ext16s_i32:
363
case INDEX_op_ext16s_i64:
364
+ case INDEX_op_ext16u_i32:
365
+ case INDEX_op_ext16u_i64:
366
default:
367
g_assert_not_reached();
368
}
369
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
370
index XXXXXXX..XXXXXXX 100644
371
--- a/tcg/tci/tcg-target.c.inc
372
+++ b/tcg/tci/tcg-target.c.inc
373
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
374
}
375
}
376
377
+static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs)
234
+{
378
+{
235
+ /* Maybe replace 0 with 0, returning the old value. */
379
+ if (TCG_TARGET_REG_BITS == 64) {
236
+ return atomic16_cmpxchg(ptr, 0, 0);
380
+ tcg_debug_assert(TCG_TARGET_HAS_ext16u_i64);
381
+ tcg_out_op_rr(s, INDEX_op_ext16u_i64, rd, rs);
382
+ } else {
383
+ tcg_debug_assert(TCG_TARGET_HAS_ext16u_i32);
384
+ tcg_out_op_rr(s, INDEX_op_ext16u_i32, rd, rs);
385
+ }
237
+}
386
+}
238
+
387
+
239
+static inline void atomic16_set(Int128 *ptr, Int128 val)
388
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
240
+{
389
tcg_target_long imm)
241
+ Int128 old = *ptr, cmp;
390
{
242
+ do {
391
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
243
+ cmp = old;
392
244
+ old = atomic16_cmpxchg(ptr, cmp, val);
393
CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
245
+ } while (old != cmp);
394
CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */
246
+}
395
- CASE_32_64(ext16u) /* Optional (TCG_TARGET_HAS_ext16u_*). */
247
+
396
CASE_64(ext32s) /* Optional (TCG_TARGET_HAS_ext32s_i64). */
248
+# define HAVE_ATOMIC128 1
397
CASE_64(ext32u) /* Optional (TCG_TARGET_HAS_ext32u_i64). */
249
+#else
398
CASE_64(ext_i32)
250
+/* Fallback definitions that must be optimized away, or error. */
399
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
251
+Int128 __attribute__((error("unsupported atomic")))
400
case INDEX_op_ext8u_i64:
252
+ atomic16_read(Int128 *ptr);
401
case INDEX_op_ext16s_i32:
253
+void __attribute__((error("unsupported atomic")))
402
case INDEX_op_ext16s_i64:
254
+ atomic16_set(Int128 *ptr, Int128 val);
403
+ case INDEX_op_ext16u_i32:
255
+# define HAVE_ATOMIC128 0
404
+ case INDEX_op_ext16u_i64:
256
+#endif /* Some definition for HAVE_ATOMIC128 */
405
default:
257
+
406
g_assert_not_reached();
258
+#endif /* QEMU_ATOMIC128_H */
407
}
259
diff --git a/tcg/tcg.h b/tcg/tcg.h
260
index XXXXXXX..XXXXXXX 100644
261
--- a/tcg/tcg.h
262
+++ b/tcg/tcg.h
263
@@ -XXX,XX +XXX,XX @@
264
#include "qemu/queue.h"
265
#include "tcg-mo.h"
266
#include "tcg-target.h"
267
+#include "qemu/int128.h"
268
269
/* XXX: make safe guess about sizes */
270
#define MAX_OP_PER_INSTR 266
271
@@ -XXX,XX +XXX,XX @@ GEN_ATOMIC_HELPER_ALL(xchg)
272
#undef GEN_ATOMIC_HELPER
273
#endif /* CONFIG_SOFTMMU */
274
275
-#ifdef CONFIG_ATOMIC128
276
-#include "qemu/int128.h"
277
-
278
-/* These aren't really a "proper" helpers because TCG cannot manage Int128.
279
- However, use the same format as the others, for use by the backends. */
280
+/*
281
+ * These aren't really a "proper" helpers because TCG cannot manage Int128.
282
+ * However, use the same format as the others, for use by the backends.
283
+ *
284
+ * The cmpxchg functions are only defined if HAVE_CMPXCHG128;
285
+ * the ld/st functions are only defined if HAVE_ATOMIC128,
286
+ * as defined by <qemu/atomic128.h>.
287
+ */
288
Int128 helper_atomic_cmpxchgo_le_mmu(CPUArchState *env, target_ulong addr,
289
Int128 cmpv, Int128 newv,
290
TCGMemOpIdx oi, uintptr_t retaddr);
291
@@ -XXX,XX +XXX,XX @@ void helper_atomic_sto_le_mmu(CPUArchState *env, target_ulong addr, Int128 val,
292
void helper_atomic_sto_be_mmu(CPUArchState *env, target_ulong addr, Int128 val,
293
TCGMemOpIdx oi, uintptr_t retaddr);
294
295
-#endif /* CONFIG_ATOMIC128 */
296
-
297
#endif /* TCG_H */
298
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
299
index XXXXXXX..XXXXXXX 100644
300
--- a/accel/tcg/cputlb.c
301
+++ b/accel/tcg/cputlb.c
302
@@ -XXX,XX +XXX,XX @@
303
#include "exec/log.h"
304
#include "exec/helper-proto.h"
305
#include "qemu/atomic.h"
306
+#include "qemu/atomic128.h"
307
308
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
309
/* #define DEBUG_TLB */
310
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
311
#include "atomic_template.h"
312
#endif
313
314
-#ifdef CONFIG_ATOMIC128
315
+#if HAVE_CMPXCHG128 || HAVE_ATOMIC128
316
#define DATA_SIZE 16
317
#include "atomic_template.h"
318
#endif
319
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
320
index XXXXXXX..XXXXXXX 100644
321
--- a/accel/tcg/user-exec.c
322
+++ b/accel/tcg/user-exec.c
323
@@ -XXX,XX +XXX,XX @@
324
#include "exec/cpu_ldst.h"
325
#include "translate-all.h"
326
#include "exec/helper-proto.h"
327
+#include "qemu/atomic128.h"
328
329
#undef EAX
330
#undef ECX
331
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
332
/* The following is only callable from other helpers, and matches up
333
with the softmmu version. */
334
335
-#ifdef CONFIG_ATOMIC128
336
+#if HAVE_ATOMIC128 || HAVE_CMPXCHG128
337
338
#undef EXTRA_ARGS
339
#undef ATOMIC_NAME
340
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
341
342
#define DATA_SIZE 16
343
#include "atomic_template.h"
344
-#endif /* CONFIG_ATOMIC128 */
345
+#endif
346
diff --git a/configure b/configure
347
index XXXXXXX..XXXXXXX 100755
348
--- a/configure
349
+++ b/configure
350
@@ -XXX,XX +XXX,XX @@ EOF
351
fi
352
fi
353
354
+cmpxchg128=no
355
+if test "$int128" = yes -a "$atomic128" = no; then
356
+ cat > $TMPC << EOF
357
+int main(void)
358
+{
359
+ unsigned __int128 x = 0, y = 0;
360
+ __sync_val_compare_and_swap_16(&x, y, x);
361
+ return 0;
362
+}
363
+EOF
364
+ if compile_prog "" "" ; then
365
+ cmpxchg128=yes
366
+ fi
367
+fi
368
+
369
#########################################
370
# See if 64-bit atomic operations are supported.
371
# Note that without __atomic builtins, we can only
372
@@ -XXX,XX +XXX,XX @@ if test "$atomic128" = "yes" ; then
373
echo "CONFIG_ATOMIC128=y" >> $config_host_mak
374
fi
375
376
+if test "$cmpxchg128" = "yes" ; then
377
+ echo "CONFIG_CMPXCHG128=y" >> $config_host_mak
378
+fi
379
+
380
if test "$atomic64" = "yes" ; then
381
echo "CONFIG_ATOMIC64=y" >> $config_host_mak
382
fi
383
--
408
--
384
2.17.2
409
2.34.1
385
410
386
411
diff view generated by jsdifflib
1
Reviewed-by: David Hildenbrand <david@redhat.com>
1
We will need a backend interface for performing 32-bit sign-extend.
2
Use it in tcg_reg_alloc_op in the meantime.
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
6
---
4
target/s390x/mem_helper.c | 40 +++++++++++++++++++--------------------
7
tcg/tcg.c | 4 ++++
5
target/s390x/translate.c | 25 +++++++++++++++++-------
8
tcg/aarch64/tcg-target.c.inc | 9 +++++++--
6
2 files changed, 38 insertions(+), 27 deletions(-)
9
tcg/arm/tcg-target.c.inc | 5 +++++
10
tcg/i386/tcg-target.c.inc | 5 +++--
11
tcg/loongarch64/tcg-target.c.inc | 2 +-
12
tcg/mips/tcg-target.c.inc | 12 +++++++++---
13
tcg/ppc/tcg-target.c.inc | 5 +++--
14
tcg/riscv/tcg-target.c.inc | 2 +-
15
tcg/s390x/tcg-target.c.inc | 10 +++++-----
16
tcg/sparc64/tcg-target.c.inc | 11 ++++++++---
17
tcg/tci/tcg-target.c.inc | 9 ++++++++-
18
11 files changed, 54 insertions(+), 20 deletions(-)
7
19
8
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
20
diff --git a/tcg/tcg.c b/tcg/tcg.c
9
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
10
--- a/target/s390x/mem_helper.c
22
--- a/tcg/tcg.c
11
+++ b/target/s390x/mem_helper.c
23
+++ b/tcg/tcg.c
12
@@ -XXX,XX +XXX,XX @@ void HELPER(cdsg_parallel)(CPUS390XState *env, uint64_t addr,
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
13
Int128 oldv;
25
static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
14
bool fail;
26
static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg);
15
27
static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg);
16
- if (!HAVE_CMPXCHG128) {
28
+static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg);
17
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
29
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
18
- }
30
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
19
+ assert(HAVE_CMPXCHG128);
31
static void tcg_out_goto_tb(TCGContext *s, int which);
20
32
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
21
mem_idx = cpu_mmu_index(env, false);
33
case INDEX_op_ext16u_i64:
22
oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
34
tcg_out_ext16u(s, new_args[0], new_args[1]);
23
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(lpq_parallel)(CPUS390XState *env, uint64_t addr)
35
break;
24
{
36
+ case INDEX_op_ext32s_i64:
25
uintptr_t ra = GETPC();
37
+ tcg_out_ext32s(s, new_args[0], new_args[1]);
26
uint64_t hi, lo;
38
+ break;
27
+ int mem_idx;
39
default:
28
+ TCGMemOpIdx oi;
40
if (def->flags & TCG_OPF_VECTOR) {
29
+ Int128 v;
41
tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
30
42
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
31
- if (HAVE_ATOMIC128) {
43
index XXXXXXX..XXXXXXX 100644
32
- int mem_idx = cpu_mmu_index(env, false);
44
--- a/tcg/aarch64/tcg-target.c.inc
33
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
45
+++ b/tcg/aarch64/tcg-target.c.inc
34
- Int128 v = helper_atomic_ldo_be_mmu(env, addr, oi, ra);
46
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn)
35
- hi = int128_gethi(v);
47
tcg_out_sxt(s, type, MO_16, rd, rn);
36
- lo = int128_getlo(v);
48
}
37
- } else {
49
38
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
50
+static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rn)
39
- }
51
+{
40
+ assert(HAVE_ATOMIC128);
52
+ tcg_out_sxt(s, TCG_TYPE_I64, MO_32, rd, rn);
41
+
53
+}
42
+ mem_idx = cpu_mmu_index(env, false);
54
+
43
+ oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
55
static inline void tcg_out_uxt(TCGContext *s, MemOp s_bits,
44
+ v = helper_atomic_ldo_be_mmu(env, addr, oi, ra);
56
TCGReg rd, TCGReg rn)
45
+ hi = int128_gethi(v);
57
{
46
+ lo = int128_getlo(v);
58
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
47
59
case INDEX_op_bswap32_i64:
48
env->retxl = lo;
60
tcg_out_rev(s, TCG_TYPE_I32, MO_32, a0, a1);
49
return hi;
61
if (a2 & TCG_BSWAP_OS) {
50
@@ -XXX,XX +XXX,XX @@ void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
62
- tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a0);
51
uint64_t low, uint64_t high)
63
+ tcg_out_ext32s(s, a0, a0);
52
{
64
}
53
uintptr_t ra = GETPC();
65
break;
54
+ int mem_idx;
66
case INDEX_op_bswap32_i32:
55
+ TCGMemOpIdx oi;
67
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
56
+ Int128 v;
68
break;
57
69
58
- if (HAVE_ATOMIC128) {
70
case INDEX_op_ext_i32_i64:
59
- int mem_idx = cpu_mmu_index(env, false);
71
- case INDEX_op_ext32s_i64:
60
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
72
tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1);
61
- Int128 v = int128_make128(low, high);
73
break;
62
- helper_atomic_sto_be_mmu(env, addr, v, oi, ra);
74
case INDEX_op_extu_i32_i64:
63
- } else {
75
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
64
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
76
case INDEX_op_ext16s_i32:
65
- }
77
case INDEX_op_ext16u_i64:
66
+ assert(HAVE_ATOMIC128);
78
case INDEX_op_ext16u_i32:
67
+
79
+ case INDEX_op_ext32s_i64:
68
+ mem_idx = cpu_mmu_index(env, false);
80
default:
69
+ oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
81
g_assert_not_reached();
70
+ v = int128_make128(low, high);
82
}
71
+ helper_atomic_sto_be_mmu(env, addr, v, oi, ra);
83
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
72
}
84
index XXXXXXX..XXXXXXX 100644
73
85
--- a/tcg/arm/tcg-target.c.inc
74
/* Execute instruction. This instruction executes an insn modified with
86
+++ b/tcg/arm/tcg-target.c.inc
75
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
87
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rn)
76
index XXXXXXX..XXXXXXX 100644
88
tcg_out_ext16u_cond(s, COND_AL, rd, rn);
77
--- a/target/s390x/translate.c
89
}
78
+++ b/target/s390x/translate.c
90
79
@@ -XXX,XX +XXX,XX @@
91
+static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rn)
80
#include "trace-tcg.h"
92
+{
81
#include "exec/translator.h"
93
+ g_assert_not_reached();
82
#include "exec/log.h"
94
+}
83
+#include "qemu/atomic128.h"
95
+
84
96
static void tcg_out_bswap16(TCGContext *s, ARMCond cond,
85
97
TCGReg rd, TCGReg rn, int flags)
86
/* Information that (most) every instruction needs to manipulate. */
98
{
87
@@ -XXX,XX +XXX,XX @@ static DisasJumpType op_cdsg(DisasContext *s, DisasOps *o)
99
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
88
int r3 = get_field(s->fields, r3);
100
index XXXXXXX..XXXXXXX 100644
89
int d2 = get_field(s->fields, d2);
101
--- a/tcg/i386/tcg-target.c.inc
90
int b2 = get_field(s->fields, b2);
102
+++ b/tcg/i386/tcg-target.c.inc
91
+ DisasJumpType ret = DISAS_NEXT;
103
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_ext32u(TCGContext *s, int dest, int src)
92
TCGv_i64 addr;
104
tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src);
93
TCGv_i32 t_r1, t_r3;
105
}
94
106
95
@@ -XXX,XX +XXX,XX @@ static DisasJumpType op_cdsg(DisasContext *s, DisasOps *o)
107
-static inline void tcg_out_ext32s(TCGContext *s, int dest, int src)
96
addr = get_address(s, 0, b2, d2);
108
+static void tcg_out_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
97
t_r1 = tcg_const_i32(r1);
109
{
98
t_r3 = tcg_const_i32(r3);
110
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
99
- if (tb_cflags(s->base.tb) & CF_PARALLEL) {
111
tcg_out_modrm(s, OPC_MOVSLQ, dest, src);
100
+ if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
112
}
101
+ gen_helper_cdsg(cpu_env, addr, t_r1, t_r3);
113
102
+ } else if (HAVE_CMPXCHG128) {
114
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
103
gen_helper_cdsg_parallel(cpu_env, addr, t_r1, t_r3);
115
tcg_out_ext32u(s, a0, a1);
116
break;
117
case INDEX_op_ext_i32_i64:
118
- case INDEX_op_ext32s_i64:
119
tcg_out_ext32s(s, a0, a1);
120
break;
121
case INDEX_op_extrh_i64_i32:
122
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
123
case INDEX_op_ext16s_i64:
124
case INDEX_op_ext16u_i32:
125
case INDEX_op_ext16u_i64:
126
+ case INDEX_op_ext32s_i64:
127
default:
128
g_assert_not_reached();
129
}
130
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
131
index XXXXXXX..XXXXXXX 100644
132
--- a/tcg/loongarch64/tcg-target.c.inc
133
+++ b/tcg/loongarch64/tcg-target.c.inc
134
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
135
tcg_out_ext32u(s, a0, a1);
136
break;
137
138
- case INDEX_op_ext32s_i64:
139
case INDEX_op_extrl_i64_i32:
140
case INDEX_op_ext_i32_i64:
141
tcg_out_ext32s(s, a0, a1);
142
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
143
case INDEX_op_ext16s_i64:
144
case INDEX_op_ext16u_i32:
145
case INDEX_op_ext16u_i64:
146
+ case INDEX_op_ext32s_i64:
147
default:
148
g_assert_not_reached();
149
}
150
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
151
index XXXXXXX..XXXXXXX 100644
152
--- a/tcg/mips/tcg-target.c.inc
153
+++ b/tcg/mips/tcg-target.c.inc
154
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs)
155
tcg_out_opc_imm(s, OPC_ANDI, rd, rs, 0xffff);
156
}
157
158
+static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs)
159
+{
160
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
161
+ tcg_out_opc_sa(s, OPC_SLL, rd, rs, 0);
162
+}
163
+
164
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
165
tcg_target_long imm)
166
{
167
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
168
/* delay slot */
169
if (TCG_TARGET_REG_BITS == 64 && l->type == TCG_TYPE_I32) {
170
/* we always sign-extend 32-bit loads */
171
- tcg_out_opc_sa(s, OPC_SLL, v0, TCG_REG_V0, 0);
172
+ tcg_out_ext32s(s, v0, TCG_REG_V0);
104
} else {
173
} else {
105
- gen_helper_cdsg(cpu_env, addr, t_r1, t_r3);
174
tcg_out_opc_reg(s, OPC_OR, v0, TCG_REG_V0, TCG_REG_ZERO);
106
+ gen_helper_exit_atomic(cpu_env);
175
}
107
+ ret = DISAS_NORETURN;
176
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
108
}
177
case INDEX_op_extrh_i64_i32:
109
tcg_temp_free_i64(addr);
178
tcg_out_dsra(s, a0, a1, 32);
110
tcg_temp_free_i32(t_r1);
179
break;
111
tcg_temp_free_i32(t_r3);
180
- case INDEX_op_ext32s_i64:
112
181
case INDEX_op_ext_i32_i64:
113
set_cc_static(s);
182
case INDEX_op_extrl_i64_i32:
114
- return DISAS_NEXT;
183
- tcg_out_opc_sa(s, OPC_SLL, a0, a1, 0);
115
+ return ret;
184
+ tcg_out_ext32s(s, a0, a1);
116
}
185
break;
117
186
case INDEX_op_ext32u_i64:
118
static DisasJumpType op_csst(DisasContext *s, DisasOps *o)
187
case INDEX_op_extu_i32_i64:
119
@@ -XXX,XX +XXX,XX @@ static DisasJumpType op_lpd(DisasContext *s, DisasOps *o)
188
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
120
189
case INDEX_op_ext8u_i64:
121
static DisasJumpType op_lpq(DisasContext *s, DisasOps *o)
190
case INDEX_op_ext16s_i32:
122
{
191
case INDEX_op_ext16s_i64:
123
- if (tb_cflags(s->base.tb) & CF_PARALLEL) {
192
+ case INDEX_op_ext32s_i64:
124
+ if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
193
default:
125
+ gen_helper_lpq(o->out, cpu_env, o->in2);
194
g_assert_not_reached();
126
+ } else if (HAVE_ATOMIC128) {
195
}
127
gen_helper_lpq_parallel(o->out, cpu_env, o->in2);
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 void tcg_out_ext16u(TCGContext *s, TCGReg dst, TCGReg src)
201
tcg_out32(s, ANDI | SAI(src, dst, 0xffff));
202
}
203
204
-static inline void tcg_out_ext32s(TCGContext *s, TCGReg dst, TCGReg src)
205
+static void tcg_out_ext32s(TCGContext *s, TCGReg dst, TCGReg src)
206
{
207
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
208
tcg_out32(s, EXTSW | RA(dst) | RS(src));
209
}
210
211
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
212
break;
213
214
case INDEX_op_ext_i32_i64:
215
- case INDEX_op_ext32s_i64:
216
tcg_out_ext32s(s, args[0], args[1]);
217
break;
218
case INDEX_op_extu_i32_i64:
219
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
220
case INDEX_op_ext16s_i64:
221
case INDEX_op_ext16u_i32:
222
case INDEX_op_ext16u_i64:
223
+ case INDEX_op_ext32s_i64:
224
default:
225
g_assert_not_reached();
226
}
227
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
228
index XXXXXXX..XXXXXXX 100644
229
--- a/tcg/riscv/tcg-target.c.inc
230
+++ b/tcg/riscv/tcg-target.c.inc
231
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
232
tcg_out_ext32u(s, a0, a1);
233
break;
234
235
- case INDEX_op_ext32s_i64:
236
case INDEX_op_extrl_i64_i32:
237
case INDEX_op_ext_i32_i64:
238
tcg_out_ext32s(s, a0, a1);
239
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
240
case INDEX_op_ext16s_i64:
241
case INDEX_op_ext16u_i32:
242
case INDEX_op_ext16u_i64:
243
+ case INDEX_op_ext32s_i64:
244
default:
245
g_assert_not_reached();
246
}
247
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
248
index XXXXXXX..XXXXXXX 100644
249
--- a/tcg/s390x/tcg-target.c.inc
250
+++ b/tcg/s390x/tcg-target.c.inc
251
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16u(TCGContext *s, TCGReg dest, TCGReg src)
252
tcg_out_insn(s, RRE, LLGHR, dest, src);
253
}
254
255
-static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
256
+static void tcg_out_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
257
{
258
tcg_out_insn(s, RRE, LGFR, dest, src);
259
}
260
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
261
case MO_SL | MO_BSWAP:
262
/* swapped sign-extended int load */
263
tcg_out_insn(s, RXY, LRV, data, base, index, disp);
264
- tgen_ext32s(s, data, data);
265
+ tcg_out_ext32s(s, data, data);
266
break;
267
case MO_SL:
268
tcg_out_insn(s, RXY, LGF, data, base, index, disp);
269
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
270
a0 = args[0], a1 = args[1], a2 = args[2];
271
tcg_out_insn(s, RRE, LRVR, a0, a1);
272
if (a2 & TCG_BSWAP_OS) {
273
- tgen_ext32s(s, a0, a0);
274
+ tcg_out_ext32s(s, a0, a0);
275
} else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
276
tgen_ext32u(s, a0, a0);
277
}
278
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
279
break;
280
281
case INDEX_op_ext_i32_i64:
282
- case INDEX_op_ext32s_i64:
283
- tgen_ext32s(s, args[0], args[1]);
284
+ tcg_out_ext32s(s, args[0], args[1]);
285
break;
286
case INDEX_op_extu_i32_i64:
287
case INDEX_op_ext32u_i64:
288
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
289
case INDEX_op_ext16s_i64:
290
case INDEX_op_ext16u_i32:
291
case INDEX_op_ext16u_i64:
292
+ case INDEX_op_ext32s_i64:
293
default:
294
g_assert_not_reached();
295
}
296
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
297
index XXXXXXX..XXXXXXX 100644
298
--- a/tcg/sparc64/tcg-target.c.inc
299
+++ b/tcg/sparc64/tcg-target.c.inc
300
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs)
301
tcg_out_arithi(s, rd, rd, 16, SHIFT_SRL);
302
}
303
304
+static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs)
305
+{
306
+ tcg_out_arithi(s, rd, rs, 0, SHIFT_SRA);
307
+}
308
+
309
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
310
tcg_target_long imm)
311
{
312
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
313
314
/* We let the helper sign-extend SB and SW, but leave SL for here. */
315
if (is_64 && (memop & MO_SSIZE) == MO_SL) {
316
- tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA);
317
+ tcg_out_ext32s(s, data, TCG_REG_O0);
128
} else {
318
} else {
129
- gen_helper_lpq(o->out, cpu_env, o->in2);
319
tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0);
130
+ gen_helper_exit_atomic(cpu_env);
320
}
131
+ return DISAS_NORETURN;
321
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
132
}
322
c = ARITH_UDIVX;
133
return_low128(o->out2);
323
goto gen_arith;
134
return DISAS_NEXT;
324
case INDEX_op_ext_i32_i64:
135
@@ -XXX,XX +XXX,XX @@ static DisasJumpType op_stmh(DisasContext *s, DisasOps *o)
325
- case INDEX_op_ext32s_i64:
136
326
- tcg_out_arithi(s, a0, a1, 0, SHIFT_SRA);
137
static DisasJumpType op_stpq(DisasContext *s, DisasOps *o)
327
+ tcg_out_ext32s(s, a0, a1);
138
{
328
break;
139
- if (tb_cflags(s->base.tb) & CF_PARALLEL) {
329
case INDEX_op_extu_i32_i64:
140
+ if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
330
case INDEX_op_ext32u_i64:
141
+ gen_helper_stpq(cpu_env, o->in2, o->out2, o->out);
331
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
142
+ } else if (HAVE_ATOMIC128) {
332
case INDEX_op_ext16s_i64:
143
gen_helper_stpq_parallel(cpu_env, o->in2, o->out2, o->out);
333
case INDEX_op_ext16u_i32:
144
} else {
334
case INDEX_op_ext16u_i64:
145
- gen_helper_stpq(cpu_env, o->in2, o->out2, o->out);
335
+ case INDEX_op_ext32s_i64:
146
+ gen_helper_exit_atomic(cpu_env);
336
default:
147
+ return DISAS_NORETURN;
337
g_assert_not_reached();
148
}
338
}
149
return DISAS_NEXT;
339
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
150
}
340
index XXXXXXX..XXXXXXX 100644
341
--- a/tcg/tci/tcg-target.c.inc
342
+++ b/tcg/tci/tcg-target.c.inc
343
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs)
344
}
345
}
346
347
+static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs)
348
+{
349
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
350
+ tcg_debug_assert(TCG_TARGET_HAS_ext32s_i64);
351
+ tcg_out_op_rr(s, INDEX_op_ext32s_i64, rd, rs);
352
+}
353
+
354
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
355
tcg_target_long imm)
356
{
357
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
358
359
CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
360
CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */
361
- CASE_64(ext32s) /* Optional (TCG_TARGET_HAS_ext32s_i64). */
362
CASE_64(ext32u) /* Optional (TCG_TARGET_HAS_ext32u_i64). */
363
CASE_64(ext_i32)
364
CASE_64(extu_i32)
365
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
366
case INDEX_op_ext16s_i64:
367
case INDEX_op_ext16u_i32:
368
case INDEX_op_ext16u_i64:
369
+ case INDEX_op_ext32s_i64:
370
default:
371
g_assert_not_reached();
372
}
151
--
373
--
152
2.17.2
374
2.34.1
153
375
154
376
diff view generated by jsdifflib
1
Reviewed-by: David Hildenbrand <david@redhat.com>
1
We will need a backend interface for performing 32-bit zero-extend.
2
Use it in tcg_reg_alloc_op in the meantime.
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
6
---
4
target/s390x/mem_helper.c | 128 ++++++++++++++++++--------------------
7
tcg/tcg.c | 4 ++++
5
1 file changed, 61 insertions(+), 67 deletions(-)
8
tcg/aarch64/tcg-target.c.inc | 9 +++++++--
9
tcg/arm/tcg-target.c.inc | 5 +++++
10
tcg/i386/tcg-target.c.inc | 4 ++--
11
tcg/loongarch64/tcg-target.c.inc | 2 +-
12
tcg/mips/tcg-target.c.inc | 3 ++-
13
tcg/ppc/tcg-target.c.inc | 4 +++-
14
tcg/riscv/tcg-target.c.inc | 2 +-
15
tcg/s390x/tcg-target.c.inc | 20 ++++++++++----------
16
tcg/sparc64/tcg-target.c.inc | 17 +++++++++++------
17
tcg/tci/tcg-target.c.inc | 9 ++++++++-
18
11 files changed, 54 insertions(+), 25 deletions(-)
6
19
7
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
20
diff --git a/tcg/tcg.c b/tcg/tcg.c
8
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
9
--- a/target/s390x/mem_helper.c
22
--- a/tcg/tcg.c
10
+++ b/target/s390x/mem_helper.c
23
+++ b/tcg/tcg.c
11
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(trXX)(CPUS390XState *env, uint32_t r1, uint32_t r2,
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
12
return cc;
25
static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg);
13
}
26
static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg);
14
27
static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg);
15
-static void do_cdsg(CPUS390XState *env, uint64_t addr,
28
+static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg);
16
- uint32_t r1, uint32_t r3, bool parallel)
29
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
17
+void HELPER(cdsg)(CPUS390XState *env, uint64_t addr,
30
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
18
+ uint32_t r1, uint32_t r3)
31
static void tcg_out_goto_tb(TCGContext *s, int which);
19
{
32
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
20
uintptr_t ra = GETPC();
33
case INDEX_op_ext32s_i64:
21
Int128 cmpv = int128_make128(env->regs[r1 + 1], env->regs[r1]);
34
tcg_out_ext32s(s, new_args[0], new_args[1]);
22
Int128 newv = int128_make128(env->regs[r3 + 1], env->regs[r3]);
35
break;
23
Int128 oldv;
36
+ case INDEX_op_ext32u_i64:
24
+ uint64_t oldh, oldl;
37
+ tcg_out_ext32u(s, new_args[0], new_args[1]);
25
bool fail;
38
+ break;
26
39
default:
27
- if (parallel) {
40
if (def->flags & TCG_OPF_VECTOR) {
28
-#if !HAVE_CMPXCHG128
41
tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
29
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
42
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
30
-#else
43
index XXXXXXX..XXXXXXX 100644
31
- int mem_idx = cpu_mmu_index(env, false);
44
--- a/tcg/aarch64/tcg-target.c.inc
32
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
45
+++ b/tcg/aarch64/tcg-target.c.inc
33
- oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
46
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rn)
34
- fail = !int128_eq(oldv, cmpv);
47
tcg_out_uxt(s, MO_16, rd, rn);
35
-#endif
48
}
36
- } else {
49
37
- uint64_t oldh, oldl;
50
+static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rn)
38
+ check_alignment(env, addr, 16, ra);
51
+{
39
52
+ tcg_out_movr(s, TCG_TYPE_I32, rd, rn);
40
- check_alignment(env, addr, 16, ra);
41
+ oldh = cpu_ldq_data_ra(env, addr + 0, ra);
42
+ oldl = cpu_ldq_data_ra(env, addr + 8, ra);
43
44
- oldh = cpu_ldq_data_ra(env, addr + 0, ra);
45
- oldl = cpu_ldq_data_ra(env, addr + 8, ra);
46
-
47
- oldv = int128_make128(oldl, oldh);
48
- fail = !int128_eq(oldv, cmpv);
49
- if (fail) {
50
- newv = oldv;
51
- }
52
-
53
- cpu_stq_data_ra(env, addr + 0, int128_gethi(newv), ra);
54
- cpu_stq_data_ra(env, addr + 8, int128_getlo(newv), ra);
55
+ oldv = int128_make128(oldl, oldh);
56
+ fail = !int128_eq(oldv, cmpv);
57
+ if (fail) {
58
+ newv = oldv;
59
}
60
61
+ cpu_stq_data_ra(env, addr + 0, int128_gethi(newv), ra);
62
+ cpu_stq_data_ra(env, addr + 8, int128_getlo(newv), ra);
63
+
64
env->cc_op = fail;
65
env->regs[r1] = int128_gethi(oldv);
66
env->regs[r1 + 1] = int128_getlo(oldv);
67
}
68
69
-void HELPER(cdsg)(CPUS390XState *env, uint64_t addr,
70
- uint32_t r1, uint32_t r3)
71
-{
72
- do_cdsg(env, addr, r1, r3, false);
73
-}
74
-
75
void HELPER(cdsg_parallel)(CPUS390XState *env, uint64_t addr,
76
uint32_t r1, uint32_t r3)
77
{
78
- do_cdsg(env, addr, r1, r3, true);
79
+ uintptr_t ra = GETPC();
80
+ Int128 cmpv = int128_make128(env->regs[r1 + 1], env->regs[r1]);
81
+ Int128 newv = int128_make128(env->regs[r3 + 1], env->regs[r3]);
82
+ int mem_idx;
83
+ TCGMemOpIdx oi;
84
+ Int128 oldv;
85
+ bool fail;
86
+
87
+ if (!HAVE_CMPXCHG128) {
88
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
89
+ }
90
+
91
+ mem_idx = cpu_mmu_index(env, false);
92
+ oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
93
+ oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
94
+ fail = !int128_eq(oldv, cmpv);
95
+
96
+ env->cc_op = fail;
97
+ env->regs[r1] = int128_gethi(oldv);
98
+ env->regs[r1 + 1] = int128_getlo(oldv);
99
}
100
101
static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
103
#endif
104
105
/* load pair from quadword */
106
-static uint64_t do_lpq(CPUS390XState *env, uint64_t addr, bool parallel)
107
+uint64_t HELPER(lpq)(CPUS390XState *env, uint64_t addr)
108
{
109
uintptr_t ra = GETPC();
110
uint64_t hi, lo;
111
112
- if (!parallel) {
113
- check_alignment(env, addr, 16, ra);
114
- hi = cpu_ldq_data_ra(env, addr + 0, ra);
115
- lo = cpu_ldq_data_ra(env, addr + 8, ra);
116
- } else if (HAVE_ATOMIC128) {
117
+ check_alignment(env, addr, 16, ra);
118
+ hi = cpu_ldq_data_ra(env, addr + 0, ra);
119
+ lo = cpu_ldq_data_ra(env, addr + 8, ra);
120
+
121
+ env->retxl = lo;
122
+ return hi;
123
+}
53
+}
124
+
54
+
125
+uint64_t HELPER(lpq_parallel)(CPUS390XState *env, uint64_t addr)
55
static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd,
56
TCGReg rn, int64_t aimm)
57
{
58
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
59
tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1);
60
break;
61
case INDEX_op_extu_i32_i64:
62
- case INDEX_op_ext32u_i64:
63
- tcg_out_movr(s, TCG_TYPE_I32, a0, a1);
64
+ tcg_out_ext32u(s, a0, a1);
65
break;
66
67
case INDEX_op_deposit_i64:
68
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
69
case INDEX_op_ext16u_i64:
70
case INDEX_op_ext16u_i32:
71
case INDEX_op_ext32s_i64:
72
+ case INDEX_op_ext32u_i64:
73
default:
74
g_assert_not_reached();
75
}
76
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
77
index XXXXXXX..XXXXXXX 100644
78
--- a/tcg/arm/tcg-target.c.inc
79
+++ b/tcg/arm/tcg-target.c.inc
80
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rn)
81
g_assert_not_reached();
82
}
83
84
+static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rn)
126
+{
85
+{
127
+ uintptr_t ra = GETPC();
86
+ g_assert_not_reached();
128
+ uint64_t hi, lo;
129
+
130
+ if (HAVE_ATOMIC128) {
131
int mem_idx = cpu_mmu_index(env, false);
132
TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
133
Int128 v = helper_atomic_ldo_be_mmu(env, addr, oi, ra);
134
@@ -XXX,XX +XXX,XX @@ static uint64_t do_lpq(CPUS390XState *env, uint64_t addr, bool parallel)
135
return hi;
136
}
137
138
-uint64_t HELPER(lpq)(CPUS390XState *env, uint64_t addr)
139
-{
140
- return do_lpq(env, addr, false);
141
-}
142
-
143
-uint64_t HELPER(lpq_parallel)(CPUS390XState *env, uint64_t addr)
144
-{
145
- return do_lpq(env, addr, true);
146
-}
147
-
148
/* store pair to quadword */
149
-static void do_stpq(CPUS390XState *env, uint64_t addr,
150
- uint64_t low, uint64_t high, bool parallel)
151
+void HELPER(stpq)(CPUS390XState *env, uint64_t addr,
152
+ uint64_t low, uint64_t high)
153
{
154
uintptr_t ra = GETPC();
155
156
- if (!parallel) {
157
- check_alignment(env, addr, 16, ra);
158
- cpu_stq_data_ra(env, addr + 0, high, ra);
159
- cpu_stq_data_ra(env, addr + 8, low, ra);
160
- } else if (HAVE_ATOMIC128) {
161
+ check_alignment(env, addr, 16, ra);
162
+ cpu_stq_data_ra(env, addr + 0, high, ra);
163
+ cpu_stq_data_ra(env, addr + 8, low, ra);
164
+}
87
+}
165
+
88
+
166
+void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
89
static void tcg_out_bswap16(TCGContext *s, ARMCond cond,
167
+ uint64_t low, uint64_t high)
90
TCGReg rd, TCGReg rn, int flags)
91
{
92
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
93
index XXXXXXX..XXXXXXX 100644
94
--- a/tcg/i386/tcg-target.c.inc
95
+++ b/tcg/i386/tcg-target.c.inc
96
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
97
tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src);
98
}
99
100
-static inline void tcg_out_ext32u(TCGContext *s, int dest, int src)
101
+static void tcg_out_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
102
{
103
/* 32-bit mov zero extends. */
104
tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src);
105
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
106
tcg_out_bswap64(s, a0);
107
break;
108
case INDEX_op_extu_i32_i64:
109
- case INDEX_op_ext32u_i64:
110
case INDEX_op_extrl_i64_i32:
111
tcg_out_ext32u(s, a0, a1);
112
break;
113
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
114
case INDEX_op_ext16u_i32:
115
case INDEX_op_ext16u_i64:
116
case INDEX_op_ext32s_i64:
117
+ case INDEX_op_ext32u_i64:
118
default:
119
g_assert_not_reached();
120
}
121
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
122
index XXXXXXX..XXXXXXX 100644
123
--- a/tcg/loongarch64/tcg-target.c.inc
124
+++ b/tcg/loongarch64/tcg-target.c.inc
125
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
126
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
127
break;
128
129
- case INDEX_op_ext32u_i64:
130
case INDEX_op_extu_i32_i64:
131
tcg_out_ext32u(s, a0, a1);
132
break;
133
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
134
case INDEX_op_ext16u_i32:
135
case INDEX_op_ext16u_i64:
136
case INDEX_op_ext32s_i64:
137
+ case INDEX_op_ext32u_i64:
138
default:
139
g_assert_not_reached();
140
}
141
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
142
index XXXXXXX..XXXXXXX 100644
143
--- a/tcg/mips/tcg-target.c.inc
144
+++ b/tcg/mips/tcg-target.c.inc
145
@@ -XXX,XX +XXX,XX @@ static void tcg_out_bswap64(TCGContext *s, TCGReg ret, TCGReg arg)
146
147
static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
148
{
149
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
150
if (use_mips32r2_instructions) {
151
tcg_out_opc_bf(s, OPC_DEXT, ret, arg, 31, 0);
152
} else {
153
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
154
case INDEX_op_extrl_i64_i32:
155
tcg_out_ext32s(s, a0, a1);
156
break;
157
- case INDEX_op_ext32u_i64:
158
case INDEX_op_extu_i32_i64:
159
tcg_out_ext32u(s, a0, a1);
160
break;
161
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
162
case INDEX_op_ext16s_i32:
163
case INDEX_op_ext16s_i64:
164
case INDEX_op_ext32s_i64:
165
+ case INDEX_op_ext32u_i64:
166
default:
167
g_assert_not_reached();
168
}
169
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
170
index XXXXXXX..XXXXXXX 100644
171
--- a/tcg/ppc/tcg-target.c.inc
172
+++ b/tcg/ppc/tcg-target.c.inc
173
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg dst, TCGReg src)
174
tcg_out32(s, EXTSW | RA(dst) | RS(src));
175
}
176
177
-static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
178
+static void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
179
{
180
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
181
tcg_out_rld(s, RLDICL, dst, src, 0, 32);
182
}
183
184
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
185
case INDEX_op_ext16u_i32:
186
case INDEX_op_ext16u_i64:
187
case INDEX_op_ext32s_i64:
188
+ case INDEX_op_ext32u_i64:
189
default:
190
g_assert_not_reached();
191
}
192
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
193
index XXXXXXX..XXXXXXX 100644
194
--- a/tcg/riscv/tcg-target.c.inc
195
+++ b/tcg/riscv/tcg-target.c.inc
196
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
197
tcg_out_qemu_st(s, args, true);
198
break;
199
200
- case INDEX_op_ext32u_i64:
201
case INDEX_op_extu_i32_i64:
202
tcg_out_ext32u(s, a0, a1);
203
break;
204
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
205
case INDEX_op_ext16u_i32:
206
case INDEX_op_ext16u_i64:
207
case INDEX_op_ext32s_i64:
208
+ case INDEX_op_ext32u_i64:
209
default:
210
g_assert_not_reached();
211
}
212
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
213
index XXXXXXX..XXXXXXX 100644
214
--- a/tcg/s390x/tcg-target.c.inc
215
+++ b/tcg/s390x/tcg-target.c.inc
216
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
217
tcg_out_insn(s, RRE, LGFR, dest, src);
218
}
219
220
-static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
221
+static void tcg_out_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
222
{
223
tcg_out_insn(s, RRE, LLGFR, dest, src);
224
}
225
@@ -XXX,XX +XXX,XX @@ static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
226
227
/* Look for the zero-extensions. */
228
if ((val & valid) == 0xffffffff) {
229
- tgen_ext32u(s, dest, dest);
230
+ tcg_out_ext32u(s, dest, dest);
231
return;
232
}
233
if ((val & valid) == 0xff) {
234
@@ -XXX,XX +XXX,XX @@ static void tgen_ctpop(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
235
/* With MIE3, and bit 0 of m4 set, we get the complete result. */
236
if (HAVE_FACILITY(MISC_INSN_EXT3)) {
237
if (type == TCG_TYPE_I32) {
238
- tgen_ext32u(s, dest, src);
239
+ tcg_out_ext32u(s, dest, src);
240
src = dest;
241
}
242
tcg_out_insn(s, RRFc, POPCNT, dest, src, 8);
243
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data,
244
case MO_UL | MO_BSWAP:
245
/* swapped unsigned int load with upper bits zeroed */
246
tcg_out_insn(s, RXY, LRV, data, base, index, disp);
247
- tgen_ext32u(s, data, data);
248
+ tcg_out_ext32u(s, data, data);
249
break;
250
case MO_UL:
251
tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
252
@@ -XXX,XX +XXX,XX @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, MemOp opc,
253
offsetof(CPUTLBEntry, addend));
254
255
if (TARGET_LONG_BITS == 32) {
256
- tgen_ext32u(s, TCG_REG_R3, addr_reg);
257
+ tcg_out_ext32u(s, TCG_REG_R3, addr_reg);
258
return TCG_REG_R3;
259
}
260
return addr_reg;
261
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
262
tcg_out_ext16u(s, TCG_REG_R4, data_reg);
263
break;
264
case MO_UL:
265
- tgen_ext32u(s, TCG_REG_R4, data_reg);
266
+ tcg_out_ext32u(s, TCG_REG_R4, data_reg);
267
break;
268
case MO_UQ:
269
tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
270
@@ -XXX,XX +XXX,XX @@ static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
271
TCGReg *index_reg, tcg_target_long *disp)
272
{
273
if (TARGET_LONG_BITS == 32) {
274
- tgen_ext32u(s, TCG_TMP0, *addr_reg);
275
+ tcg_out_ext32u(s, TCG_TMP0, *addr_reg);
276
*addr_reg = TCG_TMP0;
277
}
278
if (guest_base < 0x80000) {
279
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
280
if (a2 & TCG_BSWAP_OS) {
281
tcg_out_ext32s(s, a0, a0);
282
} else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
283
- tgen_ext32u(s, a0, a0);
284
+ tcg_out_ext32u(s, a0, a0);
285
}
286
break;
287
288
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
289
tcg_out_ext32s(s, args[0], args[1]);
290
break;
291
case INDEX_op_extu_i32_i64:
292
- case INDEX_op_ext32u_i64:
293
- tgen_ext32u(s, args[0], args[1]);
294
+ tcg_out_ext32u(s, args[0], args[1]);
295
break;
296
297
case INDEX_op_add2_i64:
298
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
299
case INDEX_op_ext16u_i32:
300
case INDEX_op_ext16u_i64:
301
case INDEX_op_ext32s_i64:
302
+ case INDEX_op_ext32u_i64:
303
default:
304
g_assert_not_reached();
305
}
306
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
307
index XXXXXXX..XXXXXXX 100644
308
--- a/tcg/sparc64/tcg-target.c.inc
309
+++ b/tcg/sparc64/tcg-target.c.inc
310
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs)
311
tcg_out_arithi(s, rd, rs, 0, SHIFT_SRA);
312
}
313
314
+static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs)
168
+{
315
+{
169
+ uintptr_t ra = GETPC();
316
+ tcg_out_arithi(s, rd, rs, 0, SHIFT_SRL);
317
+}
170
+
318
+
171
+ if (HAVE_ATOMIC128) {
319
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
172
int mem_idx = cpu_mmu_index(env, false);
320
tcg_target_long imm)
173
TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
321
{
174
Int128 v = int128_make128(low, high);
322
@@ -XXX,XX +XXX,XX @@ static void emit_extend(TCGContext *s, TCGReg r, int op)
175
@@ -XXX,XX +XXX,XX @@ static void do_stpq(CPUS390XState *env, uint64_t addr,
323
tcg_out_ext16u(s, r, r);
176
}
324
break;
177
}
325
case MO_32:
178
326
- tcg_out_arith(s, r, r, 0, SHIFT_SRL);
179
-void HELPER(stpq)(CPUS390XState *env, uint64_t addr,
327
+ tcg_out_ext32u(s, r, r);
180
- uint64_t low, uint64_t high)
328
break;
181
-{
329
case MO_64:
182
- do_stpq(env, addr, low, high, false);
330
break;
183
-}
331
@@ -XXX,XX +XXX,XX @@ static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index,
184
-
332
185
-void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
333
/* If the guest address must be zero-extended, do so now. */
186
- uint64_t low, uint64_t high)
334
if (TARGET_LONG_BITS == 32) {
187
-{
335
- tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL);
188
- do_stpq(env, addr, low, high, true);
336
+ tcg_out_ext32u(s, r0, addr);
189
-}
337
return r0;
190
-
338
}
191
/* Execute instruction. This instruction executes an insn modified with
339
return addr;
192
the contents of r1. It does not change the executed instruction in memory;
340
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
193
it does not change the program counter.
341
unsigned t_bits;
342
343
if (TARGET_LONG_BITS == 32) {
344
- tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
345
+ tcg_out_ext32u(s, TCG_REG_T1, addr);
346
addr = TCG_REG_T1;
347
}
348
349
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
350
unsigned t_bits;
351
352
if (TARGET_LONG_BITS == 32) {
353
- tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
354
+ tcg_out_ext32u(s, TCG_REG_T1, addr);
355
addr = TCG_REG_T1;
356
}
357
358
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
359
tcg_out_ext32s(s, a0, a1);
360
break;
361
case INDEX_op_extu_i32_i64:
362
- case INDEX_op_ext32u_i64:
363
- tcg_out_arithi(s, a0, a1, 0, SHIFT_SRL);
364
+ tcg_out_ext32u(s, a0, a1);
365
break;
366
case INDEX_op_extrl_i64_i32:
367
tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
368
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
369
case INDEX_op_ext16u_i32:
370
case INDEX_op_ext16u_i64:
371
case INDEX_op_ext32s_i64:
372
+ case INDEX_op_ext32u_i64:
373
default:
374
g_assert_not_reached();
375
}
376
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
377
index XXXXXXX..XXXXXXX 100644
378
--- a/tcg/tci/tcg-target.c.inc
379
+++ b/tcg/tci/tcg-target.c.inc
380
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs)
381
tcg_out_op_rr(s, INDEX_op_ext32s_i64, rd, rs);
382
}
383
384
+static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs)
385
+{
386
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
387
+ tcg_debug_assert(TCG_TARGET_HAS_ext32u_i64);
388
+ tcg_out_op_rr(s, INDEX_op_ext32u_i64, rd, rs);
389
+}
390
+
391
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
392
tcg_target_long imm)
393
{
394
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
395
396
CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
397
CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */
398
- CASE_64(ext32u) /* Optional (TCG_TARGET_HAS_ext32u_i64). */
399
CASE_64(ext_i32)
400
CASE_64(extu_i32)
401
CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */
402
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
403
case INDEX_op_ext16u_i32:
404
case INDEX_op_ext16u_i64:
405
case INDEX_op_ext32s_i64:
406
+ case INDEX_op_ext32u_i64:
407
default:
408
g_assert_not_reached();
409
}
194
--
410
--
195
2.17.2
411
2.34.1
196
412
197
413
diff view generated by jsdifflib
1
When op raises an exception, it may not have initialized the output
1
We will need a backend interface for type extension with sign.
2
temps that would be written back by wout or cout.
2
Use it in tcg_reg_alloc_op in the meantime.
3
3
4
Reviewed-by: David Hildenbrand <david@redhat.com>
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
target/s390x/translate.c | 20 +++++++++++++++-----
7
tcg/tcg.c | 4 ++++
8
1 file changed, 15 insertions(+), 5 deletions(-)
8
tcg/aarch64/tcg-target.c.inc | 9 ++++++---
9
tcg/arm/tcg-target.c.inc | 5 +++++
10
tcg/i386/tcg-target.c.inc | 9 ++++++---
11
tcg/loongarch64/tcg-target.c.inc | 7 ++++++-
12
tcg/mips/tcg-target.c.inc | 7 ++++++-
13
tcg/ppc/tcg-target.c.inc | 9 ++++++---
14
tcg/riscv/tcg-target.c.inc | 7 ++++++-
15
tcg/s390x/tcg-target.c.inc | 9 ++++++---
16
tcg/sparc64/tcg-target.c.inc | 9 ++++++---
17
tcg/tci/tcg-target.c.inc | 7 ++++++-
18
11 files changed, 63 insertions(+), 19 deletions(-)
9
19
10
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
20
diff --git a/tcg/tcg.c b/tcg/tcg.c
11
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
12
--- a/target/s390x/translate.c
22
--- a/tcg/tcg.c
13
+++ b/target/s390x/translate.c
23
+++ b/tcg/tcg.c
14
@@ -XXX,XX +XXX,XX @@ struct DisasInsn {
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg);
15
25
static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg);
16
const char *name;
26
static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg);
17
27
static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg);
18
+ /* Pre-process arguments before HELP_OP. */
28
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
19
void (*help_in1)(DisasContext *, DisasFields *, DisasOps *);
29
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
20
void (*help_in2)(DisasContext *, DisasFields *, DisasOps *);
30
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
21
void (*help_prep)(DisasContext *, DisasFields *, DisasOps *);
31
static void tcg_out_goto_tb(TCGContext *s, int which);
22
+
32
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
23
+ /*
33
case INDEX_op_ext32u_i64:
24
+ * Post-process output after HELP_OP.
34
tcg_out_ext32u(s, new_args[0], new_args[1]);
25
+ * Note that these are not called if HELP_OP returns DISAS_NORETURN.
35
break;
26
+ */
36
+ case INDEX_op_ext_i32_i64:
27
void (*help_wout)(DisasContext *, DisasFields *, DisasOps *);
37
+ tcg_out_exts_i32_i64(s, new_args[0], new_args[1]);
28
void (*help_cout)(DisasContext *, DisasOps *);
38
+ break;
29
+
39
default:
30
+ /* Implement the operation itself. */
40
if (def->flags & TCG_OPF_VECTOR) {
31
DisasJumpType (*help_op)(DisasContext *, DisasOps *);
41
tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
32
42
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
33
uint64_t data;
43
index XXXXXXX..XXXXXXX 100644
34
@@ -XXX,XX +XXX,XX @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
44
--- a/tcg/aarch64/tcg-target.c.inc
35
if (insn->help_op) {
45
+++ b/tcg/aarch64/tcg-target.c.inc
36
ret = insn->help_op(s, &o);
46
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rn)
37
}
47
tcg_out_sxt(s, TCG_TYPE_I64, MO_32, rd, rn);
38
- if (insn->help_wout) {
48
}
39
- insn->help_wout(s, &f, &o);
49
40
- }
50
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn)
41
- if (insn->help_cout) {
51
+{
42
- insn->help_cout(s, &o);
52
+ tcg_out_ext32s(s, rd, rn);
43
+ if (ret != DISAS_NORETURN) {
53
+}
44
+ if (insn->help_wout) {
54
+
45
+ insn->help_wout(s, &f, &o);
55
static inline void tcg_out_uxt(TCGContext *s, MemOp s_bits,
46
+ }
56
TCGReg rd, TCGReg rn)
47
+ if (insn->help_cout) {
57
{
48
+ insn->help_cout(s, &o);
58
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
49
+ }
59
}
50
}
60
break;
51
61
52
/* Free any temporaries created by the helpers. */
62
- case INDEX_op_ext_i32_i64:
63
- tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1);
64
- break;
65
case INDEX_op_extu_i32_i64:
66
tcg_out_ext32u(s, a0, a1);
67
break;
68
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
69
case INDEX_op_ext16u_i32:
70
case INDEX_op_ext32s_i64:
71
case INDEX_op_ext32u_i64:
72
+ case INDEX_op_ext_i32_i64:
73
default:
74
g_assert_not_reached();
75
}
76
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
77
index XXXXXXX..XXXXXXX 100644
78
--- a/tcg/arm/tcg-target.c.inc
79
+++ b/tcg/arm/tcg-target.c.inc
80
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rn)
81
g_assert_not_reached();
82
}
83
84
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn)
85
+{
86
+ g_assert_not_reached();
87
+}
88
+
89
static void tcg_out_bswap16(TCGContext *s, ARMCond cond,
90
TCGReg rd, TCGReg rn, int flags)
91
{
92
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
93
index XXXXXXX..XXXXXXX 100644
94
--- a/tcg/i386/tcg-target.c.inc
95
+++ b/tcg/i386/tcg-target.c.inc
96
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
97
tcg_out_modrm(s, OPC_MOVSLQ, dest, src);
98
}
99
100
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dest, TCGReg src)
101
+{
102
+ tcg_out_ext32s(s, dest, src);
103
+}
104
+
105
static inline void tcg_out_bswap64(TCGContext *s, int reg)
106
{
107
tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0);
108
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
109
case INDEX_op_extrl_i64_i32:
110
tcg_out_ext32u(s, a0, a1);
111
break;
112
- case INDEX_op_ext_i32_i64:
113
- tcg_out_ext32s(s, a0, a1);
114
- break;
115
case INDEX_op_extrh_i64_i32:
116
tcg_out_shifti(s, SHIFT_SHR + P_REXW, a0, 32);
117
break;
118
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
119
case INDEX_op_ext16u_i64:
120
case INDEX_op_ext32s_i64:
121
case INDEX_op_ext32u_i64:
122
+ case INDEX_op_ext_i32_i64:
123
default:
124
g_assert_not_reached();
125
}
126
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
127
index XXXXXXX..XXXXXXX 100644
128
--- a/tcg/loongarch64/tcg-target.c.inc
129
+++ b/tcg/loongarch64/tcg-target.c.inc
130
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
131
tcg_out_opc_addi_w(s, ret, arg, 0);
132
}
133
134
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)
135
+{
136
+ tcg_out_ext32s(s, ret, arg);
137
+}
138
+
139
static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc,
140
TCGReg a0, TCGReg a1, TCGReg a2,
141
bool c2, bool is_32bit)
142
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
143
break;
144
145
case INDEX_op_extrl_i64_i32:
146
- case INDEX_op_ext_i32_i64:
147
tcg_out_ext32s(s, a0, a1);
148
break;
149
150
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
151
case INDEX_op_ext16u_i64:
152
case INDEX_op_ext32s_i64:
153
case INDEX_op_ext32u_i64:
154
+ case INDEX_op_ext_i32_i64:
155
default:
156
g_assert_not_reached();
157
}
158
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
159
index XXXXXXX..XXXXXXX 100644
160
--- a/tcg/mips/tcg-target.c.inc
161
+++ b/tcg/mips/tcg-target.c.inc
162
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs)
163
tcg_out_opc_sa(s, OPC_SLL, rd, rs, 0);
164
}
165
166
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
167
+{
168
+ tcg_out_ext32s(s, rd, rs);
169
+}
170
+
171
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
172
tcg_target_long imm)
173
{
174
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
175
case INDEX_op_extrh_i64_i32:
176
tcg_out_dsra(s, a0, a1, 32);
177
break;
178
- case INDEX_op_ext_i32_i64:
179
case INDEX_op_extrl_i64_i32:
180
tcg_out_ext32s(s, a0, a1);
181
break;
182
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
183
case INDEX_op_ext16s_i64:
184
case INDEX_op_ext32s_i64:
185
case INDEX_op_ext32u_i64:
186
+ case INDEX_op_ext_i32_i64:
187
default:
188
g_assert_not_reached();
189
}
190
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
191
index XXXXXXX..XXXXXXX 100644
192
--- a/tcg/ppc/tcg-target.c.inc
193
+++ b/tcg/ppc/tcg-target.c.inc
194
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
195
tcg_out_rld(s, RLDICL, dst, src, 0, 32);
196
}
197
198
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dst, TCGReg src)
199
+{
200
+ tcg_out_ext32s(s, dst, src);
201
+}
202
+
203
static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c)
204
{
205
tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c);
206
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
207
tcg_out_qemu_st(s, args, true);
208
break;
209
210
- case INDEX_op_ext_i32_i64:
211
- tcg_out_ext32s(s, args[0], args[1]);
212
- break;
213
case INDEX_op_extu_i32_i64:
214
tcg_out_ext32u(s, args[0], args[1]);
215
break;
216
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
217
case INDEX_op_ext16u_i64:
218
case INDEX_op_ext32s_i64:
219
case INDEX_op_ext32u_i64:
220
+ case INDEX_op_ext_i32_i64:
221
default:
222
g_assert_not_reached();
223
}
224
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
225
index XXXXXXX..XXXXXXX 100644
226
--- a/tcg/riscv/tcg-target.c.inc
227
+++ b/tcg/riscv/tcg-target.c.inc
228
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
229
tcg_out_opc_imm(s, OPC_ADDIW, ret, arg, 0);
230
}
231
232
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)
233
+{
234
+ tcg_out_ext32s(s, ret, arg);
235
+}
236
+
237
static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data,
238
TCGReg addr, intptr_t offset)
239
{
240
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
241
break;
242
243
case INDEX_op_extrl_i64_i32:
244
- case INDEX_op_ext_i32_i64:
245
tcg_out_ext32s(s, a0, a1);
246
break;
247
248
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
249
case INDEX_op_ext16u_i64:
250
case INDEX_op_ext32s_i64:
251
case INDEX_op_ext32u_i64:
252
+ case INDEX_op_ext_i32_i64:
253
default:
254
g_assert_not_reached();
255
}
256
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
257
index XXXXXXX..XXXXXXX 100644
258
--- a/tcg/s390x/tcg-target.c.inc
259
+++ b/tcg/s390x/tcg-target.c.inc
260
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
261
tcg_out_insn(s, RRE, LLGFR, dest, src);
262
}
263
264
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dest, TCGReg src)
265
+{
266
+ tcg_out_ext32s(s, dest, src);
267
+}
268
+
269
static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
270
{
271
int msb, lsb;
272
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
273
}
274
break;
275
276
- case INDEX_op_ext_i32_i64:
277
- tcg_out_ext32s(s, args[0], args[1]);
278
- break;
279
case INDEX_op_extu_i32_i64:
280
tcg_out_ext32u(s, args[0], args[1]);
281
break;
282
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
283
case INDEX_op_ext16u_i64:
284
case INDEX_op_ext32s_i64:
285
case INDEX_op_ext32u_i64:
286
+ case INDEX_op_ext_i32_i64:
287
default:
288
g_assert_not_reached();
289
}
290
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
291
index XXXXXXX..XXXXXXX 100644
292
--- a/tcg/sparc64/tcg-target.c.inc
293
+++ b/tcg/sparc64/tcg-target.c.inc
294
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs)
295
tcg_out_arithi(s, rd, rs, 0, SHIFT_SRL);
296
}
297
298
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
299
+{
300
+ tcg_out_ext32s(s, rd, rs);
301
+}
302
+
303
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
304
tcg_target_long imm)
305
{
306
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
307
case INDEX_op_divu_i64:
308
c = ARITH_UDIVX;
309
goto gen_arith;
310
- case INDEX_op_ext_i32_i64:
311
- tcg_out_ext32s(s, a0, a1);
312
- break;
313
case INDEX_op_extu_i32_i64:
314
tcg_out_ext32u(s, a0, a1);
315
break;
316
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
317
case INDEX_op_ext16u_i64:
318
case INDEX_op_ext32s_i64:
319
case INDEX_op_ext32u_i64:
320
+ case INDEX_op_ext_i32_i64:
321
default:
322
g_assert_not_reached();
323
}
324
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
325
index XXXXXXX..XXXXXXX 100644
326
--- a/tcg/tci/tcg-target.c.inc
327
+++ b/tcg/tci/tcg-target.c.inc
328
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs)
329
tcg_out_op_rr(s, INDEX_op_ext32u_i64, rd, rs);
330
}
331
332
+static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
333
+{
334
+ tcg_out_ext32s(s, rd, rs);
335
+}
336
+
337
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
338
tcg_target_long imm)
339
{
340
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
341
342
CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
343
CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */
344
- CASE_64(ext_i32)
345
CASE_64(extu_i32)
346
CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */
347
case INDEX_op_bswap32_i32: /* Optional (TCG_TARGET_HAS_bswap32_i32). */
348
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
349
case INDEX_op_ext16u_i64:
350
case INDEX_op_ext32s_i64:
351
case INDEX_op_ext32u_i64:
352
+ case INDEX_op_ext_i32_i64:
353
default:
354
g_assert_not_reached();
355
}
53
--
356
--
54
2.17.2
357
2.34.1
55
358
56
359
diff view generated by jsdifflib
1
Reviewed-by: Emilio G. Cota <cota@braap.org>
1
We will need a backend interface for type extension with zero.
2
Use it in tcg_reg_alloc_op in the meantime.
3
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
6
---
4
target/ppc/helper.h | 2 +-
7
tcg/tcg.c | 4 ++++
5
target/ppc/mem_helper.c | 33 ++++++++++--
8
tcg/aarch64/tcg-target.c.inc | 10 ++++++----
6
target/ppc/translate.c | 115 +++++++++++++++++++++-------------------
9
tcg/arm/tcg-target.c.inc | 5 +++++
7
3 files changed, 88 insertions(+), 62 deletions(-)
10
tcg/i386/tcg-target.c.inc | 7 ++++++-
11
tcg/loongarch64/tcg-target.c.inc | 10 ++++++----
12
tcg/mips/tcg-target.c.inc | 9 ++++++---
13
tcg/ppc/tcg-target.c.inc | 10 ++++++----
14
tcg/riscv/tcg-target.c.inc | 10 ++++++----
15
tcg/s390x/tcg-target.c.inc | 10 ++++++----
16
tcg/sparc64/tcg-target.c.inc | 9 ++++++---
17
tcg/tci/tcg-target.c.inc | 7 ++++++-
18
11 files changed, 63 insertions(+), 28 deletions(-)
8
19
9
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
20
diff --git a/tcg/tcg.c b/tcg/tcg.c
10
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
11
--- a/target/ppc/helper.h
22
--- a/tcg/tcg.c
12
+++ b/target/ppc/helper.h
23
+++ b/tcg/tcg.c
13
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
24
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg);
14
DEF_HELPER_1(tbegin, void, env)
25
static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg);
15
DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env)
26
static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg);
16
27
static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
17
-#if defined(TARGET_PPC64) && defined(CONFIG_ATOMIC128)
28
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
18
+#ifdef TARGET_PPC64
29
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
19
DEF_HELPER_FLAGS_3(lq_le_parallel, TCG_CALL_NO_WG, i64, env, tl, i32)
30
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
20
DEF_HELPER_FLAGS_3(lq_be_parallel, TCG_CALL_NO_WG, i64, env, tl, i32)
31
static void tcg_out_goto_tb(TCGContext *s, int which);
21
DEF_HELPER_FLAGS_5(stq_le_parallel, TCG_CALL_NO_WG,
32
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
22
diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c
33
case INDEX_op_ext_i32_i64:
23
index XXXXXXX..XXXXXXX 100644
34
tcg_out_exts_i32_i64(s, new_args[0], new_args[1]);
24
--- a/target/ppc/mem_helper.c
35
break;
25
+++ b/target/ppc/mem_helper.c
36
+ case INDEX_op_extu_i32_i64:
26
@@ -XXX,XX +XXX,XX @@
37
+ tcg_out_extu_i32_i64(s, new_args[0], new_args[1]);
27
#include "exec/cpu_ldst.h"
38
+ break;
28
#include "tcg.h"
39
default:
29
#include "internal.h"
40
if (def->flags & TCG_OPF_VECTOR) {
30
+#include "qemu/atomic128.h"
41
tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
31
42
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
32
//#define DEBUG_OP
43
index XXXXXXX..XXXXXXX 100644
33
44
--- a/tcg/aarch64/tcg-target.c.inc
34
@@ -XXX,XX +XXX,XX @@ target_ulong helper_lscbx(CPUPPCState *env, target_ulong addr, uint32_t reg,
45
+++ b/tcg/aarch64/tcg-target.c.inc
35
return i;
46
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rn)
36
}
47
tcg_out_movr(s, TCG_TYPE_I32, rd, rn);
37
48
}
38
-#if defined(TARGET_PPC64) && defined(CONFIG_ATOMIC128)
49
39
+#ifdef TARGET_PPC64
50
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn)
40
uint64_t helper_lq_le_parallel(CPUPPCState *env, target_ulong addr,
51
+{
41
uint32_t opidx)
52
+ tcg_out_ext32u(s, rd, rn);
42
{
53
+}
43
- Int128 ret = helper_atomic_ldo_le_mmu(env, addr, opidx, GETPC());
54
+
44
+ Int128 ret;
55
static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd,
45
+
56
TCGReg rn, int64_t aimm)
46
+ /* We will have raised EXCP_ATOMIC from the translator. */
57
{
47
+ assert(HAVE_ATOMIC128);
58
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
48
+ ret = helper_atomic_ldo_le_mmu(env, addr, opidx, GETPC());
49
env->retxh = int128_gethi(ret);
50
return int128_getlo(ret);
51
}
52
@@ -XXX,XX +XXX,XX @@ uint64_t helper_lq_le_parallel(CPUPPCState *env, target_ulong addr,
53
uint64_t helper_lq_be_parallel(CPUPPCState *env, target_ulong addr,
54
uint32_t opidx)
55
{
56
- Int128 ret = helper_atomic_ldo_be_mmu(env, addr, opidx, GETPC());
57
+ Int128 ret;
58
+
59
+ /* We will have raised EXCP_ATOMIC from the translator. */
60
+ assert(HAVE_ATOMIC128);
61
+ ret = helper_atomic_ldo_be_mmu(env, addr, opidx, GETPC());
62
env->retxh = int128_gethi(ret);
63
return int128_getlo(ret);
64
}
65
@@ -XXX,XX +XXX,XX @@ uint64_t helper_lq_be_parallel(CPUPPCState *env, target_ulong addr,
66
void helper_stq_le_parallel(CPUPPCState *env, target_ulong addr,
67
uint64_t lo, uint64_t hi, uint32_t opidx)
68
{
69
- Int128 val = int128_make128(lo, hi);
70
+ Int128 val;
71
+
72
+ /* We will have raised EXCP_ATOMIC from the translator. */
73
+ assert(HAVE_ATOMIC128);
74
+ val = int128_make128(lo, hi);
75
helper_atomic_sto_le_mmu(env, addr, val, opidx, GETPC());
76
}
77
78
void helper_stq_be_parallel(CPUPPCState *env, target_ulong addr,
79
uint64_t lo, uint64_t hi, uint32_t opidx)
80
{
81
- Int128 val = int128_make128(lo, hi);
82
+ Int128 val;
83
+
84
+ /* We will have raised EXCP_ATOMIC from the translator. */
85
+ assert(HAVE_ATOMIC128);
86
+ val = int128_make128(lo, hi);
87
helper_atomic_sto_be_mmu(env, addr, val, opidx, GETPC());
88
}
89
90
@@ -XXX,XX +XXX,XX @@ uint32_t helper_stqcx_le_parallel(CPUPPCState *env, target_ulong addr,
91
{
92
bool success = false;
93
94
+ /* We will have raised EXCP_ATOMIC from the translator. */
95
+ assert(HAVE_CMPXCHG128);
96
+
97
if (likely(addr == env->reserve_addr)) {
98
Int128 oldv, cmpv, newv;
99
100
@@ -XXX,XX +XXX,XX @@ uint32_t helper_stqcx_be_parallel(CPUPPCState *env, target_ulong addr,
101
{
102
bool success = false;
103
104
+ /* We will have raised EXCP_ATOMIC from the translator. */
105
+ assert(HAVE_CMPXCHG128);
106
+
107
if (likely(addr == env->reserve_addr)) {
108
Int128 oldv, cmpv, newv;
109
110
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/ppc/translate.c
113
+++ b/target/ppc/translate.c
114
@@ -XXX,XX +XXX,XX @@
115
#include "trace-tcg.h"
116
#include "exec/translator.h"
117
#include "exec/log.h"
118
+#include "qemu/atomic128.h"
119
120
121
#define CPU_SINGLE_STEP 0x1
122
@@ -XXX,XX +XXX,XX @@ static void gen_lq(DisasContext *ctx)
123
hi = cpu_gpr[rd];
124
125
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
126
-#ifdef CONFIG_ATOMIC128
127
- TCGv_i32 oi = tcg_temp_new_i32();
128
- if (ctx->le_mode) {
129
- tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
130
- gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
131
+ if (HAVE_ATOMIC128) {
132
+ TCGv_i32 oi = tcg_temp_new_i32();
133
+ if (ctx->le_mode) {
134
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
135
+ gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
136
+ } else {
137
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
138
+ gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
139
+ }
140
+ tcg_temp_free_i32(oi);
141
+ tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
142
} else {
143
- tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
144
- gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
145
+ /* Restart with exclusive lock. */
146
+ gen_helper_exit_atomic(cpu_env);
147
+ ctx->base.is_jmp = DISAS_NORETURN;
148
}
59
}
149
- tcg_temp_free_i32(oi);
60
break;
150
- tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
61
151
-#else
62
- case INDEX_op_extu_i32_i64:
152
- /* Restart with exclusive lock. */
63
- tcg_out_ext32u(s, a0, a1);
153
- gen_helper_exit_atomic(cpu_env);
64
- break;
154
- ctx->base.is_jmp = DISAS_NORETURN;
65
-
155
-#endif
66
case INDEX_op_deposit_i64:
156
} else if (ctx->le_mode) {
67
case INDEX_op_deposit_i32:
157
tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ);
68
tcg_out_dep(s, ext, a0, REG0(2), args[3], args[4]);
158
gen_addr_add(ctx, EA, EA, 8);
69
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
159
@@ -XXX,XX +XXX,XX @@ static void gen_std(DisasContext *ctx)
70
case INDEX_op_ext32s_i64:
160
hi = cpu_gpr[rs];
71
case INDEX_op_ext32u_i64:
161
72
case INDEX_op_ext_i32_i64:
162
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
73
+ case INDEX_op_extu_i32_i64:
163
-#ifdef CONFIG_ATOMIC128
74
default:
164
- TCGv_i32 oi = tcg_temp_new_i32();
75
g_assert_not_reached();
165
- if (ctx->le_mode) {
76
}
166
- tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
77
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
167
- gen_helper_stq_le_parallel(cpu_env, EA, lo, hi, oi);
78
index XXXXXXX..XXXXXXX 100644
168
+ if (HAVE_ATOMIC128) {
79
--- a/tcg/arm/tcg-target.c.inc
169
+ TCGv_i32 oi = tcg_temp_new_i32();
80
+++ b/tcg/arm/tcg-target.c.inc
170
+ if (ctx->le_mode) {
81
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn)
171
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
82
g_assert_not_reached();
172
+ gen_helper_stq_le_parallel(cpu_env, EA, lo, hi, oi);
83
}
173
+ } else {
84
174
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
85
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn)
175
+ gen_helper_stq_be_parallel(cpu_env, EA, lo, hi, oi);
86
+{
176
+ }
87
+ g_assert_not_reached();
177
+ tcg_temp_free_i32(oi);
88
+}
178
} else {
89
+
179
- tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
90
static void tcg_out_bswap16(TCGContext *s, ARMCond cond,
180
- gen_helper_stq_be_parallel(cpu_env, EA, lo, hi, oi);
91
TCGReg rd, TCGReg rn, int flags)
181
+ /* Restart with exclusive lock. */
92
{
182
+ gen_helper_exit_atomic(cpu_env);
93
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
183
+ ctx->base.is_jmp = DISAS_NORETURN;
94
index XXXXXXX..XXXXXXX 100644
184
}
95
--- a/tcg/i386/tcg-target.c.inc
185
- tcg_temp_free_i32(oi);
96
+++ b/tcg/i386/tcg-target.c.inc
186
-#else
97
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dest, TCGReg src)
187
- /* Restart with exclusive lock. */
98
tcg_out_ext32s(s, dest, src);
188
- gen_helper_exit_atomic(cpu_env);
99
}
189
- ctx->base.is_jmp = DISAS_NORETURN;
100
190
-#endif
101
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dest, TCGReg src)
191
} else if (ctx->le_mode) {
102
+{
192
tcg_gen_qemu_st_i64(lo, EA, ctx->mem_idx, MO_LEQ);
103
+ tcg_out_ext32u(s, dest, src);
193
gen_addr_add(ctx, EA, EA, 8);
104
+}
194
@@ -XXX,XX +XXX,XX @@ static void gen_lqarx(DisasContext *ctx)
105
+
195
hi = cpu_gpr[rd];
106
static inline void tcg_out_bswap64(TCGContext *s, int reg)
196
107
{
197
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
108
tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0);
198
-#ifdef CONFIG_ATOMIC128
109
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
199
- TCGv_i32 oi = tcg_temp_new_i32();
110
case INDEX_op_bswap64_i64:
200
- if (ctx->le_mode) {
111
tcg_out_bswap64(s, a0);
201
- tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ | MO_ALIGN_16,
112
break;
202
- ctx->mem_idx));
113
- case INDEX_op_extu_i32_i64:
203
- gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
114
case INDEX_op_extrl_i64_i32:
204
+ if (HAVE_ATOMIC128) {
115
tcg_out_ext32u(s, a0, a1);
205
+ TCGv_i32 oi = tcg_temp_new_i32();
116
break;
206
+ if (ctx->le_mode) {
117
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
207
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ | MO_ALIGN_16,
118
case INDEX_op_ext32s_i64:
208
+ ctx->mem_idx));
119
case INDEX_op_ext32u_i64:
209
+ gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
120
case INDEX_op_ext_i32_i64:
210
+ } else {
121
+ case INDEX_op_extu_i32_i64:
211
+ tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ | MO_ALIGN_16,
122
default:
212
+ ctx->mem_idx));
123
g_assert_not_reached();
213
+ gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
124
}
214
+ }
125
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
215
+ tcg_temp_free_i32(oi);
126
index XXXXXXX..XXXXXXX 100644
216
+ tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
127
--- a/tcg/loongarch64/tcg-target.c.inc
217
} else {
128
+++ b/tcg/loongarch64/tcg-target.c.inc
218
- tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ | MO_ALIGN_16,
129
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)
219
- ctx->mem_idx));
130
tcg_out_ext32s(s, ret, arg);
220
- gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
131
}
221
+ /* Restart with exclusive lock. */
132
222
+ gen_helper_exit_atomic(cpu_env);
133
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)
223
+ ctx->base.is_jmp = DISAS_NORETURN;
134
+{
224
+ tcg_temp_free(EA);
135
+ tcg_out_ext32u(s, ret, arg);
225
+ return;
136
+}
137
+
138
static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc,
139
TCGReg a0, TCGReg a1, TCGReg a2,
140
bool c2, bool is_32bit)
141
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
142
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
143
break;
144
145
- case INDEX_op_extu_i32_i64:
146
- tcg_out_ext32u(s, a0, a1);
147
- break;
148
-
149
case INDEX_op_extrl_i64_i32:
150
tcg_out_ext32s(s, a0, a1);
151
break;
152
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
153
case INDEX_op_ext32s_i64:
154
case INDEX_op_ext32u_i64:
155
case INDEX_op_ext_i32_i64:
156
+ case INDEX_op_extu_i32_i64:
157
default:
158
g_assert_not_reached();
159
}
160
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
161
index XXXXXXX..XXXXXXX 100644
162
--- a/tcg/mips/tcg-target.c.inc
163
+++ b/tcg/mips/tcg-target.c.inc
164
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
165
tcg_out_ext32s(s, rd, rs);
166
}
167
168
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
169
+{
170
+ tcg_out_ext32u(s, rd, rs);
171
+}
172
+
173
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
174
tcg_target_long imm)
175
{
176
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
177
case INDEX_op_extrl_i64_i32:
178
tcg_out_ext32s(s, a0, a1);
179
break;
180
- case INDEX_op_extu_i32_i64:
181
- tcg_out_ext32u(s, a0, a1);
182
- break;
183
184
case INDEX_op_sar_i32:
185
i1 = OPC_SRAV, i2 = OPC_SRA;
186
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
187
case INDEX_op_ext32s_i64:
188
case INDEX_op_ext32u_i64:
189
case INDEX_op_ext_i32_i64:
190
+ case INDEX_op_extu_i32_i64:
191
default:
192
g_assert_not_reached();
193
}
194
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
195
index XXXXXXX..XXXXXXX 100644
196
--- a/tcg/ppc/tcg-target.c.inc
197
+++ b/tcg/ppc/tcg-target.c.inc
198
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dst, TCGReg src)
199
tcg_out_ext32s(s, dst, src);
200
}
201
202
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dst, TCGReg src)
203
+{
204
+ tcg_out_ext32u(s, dst, src);
205
+}
206
+
207
static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c)
208
{
209
tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c);
210
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
211
tcg_out_qemu_st(s, args, true);
212
break;
213
214
- case INDEX_op_extu_i32_i64:
215
- tcg_out_ext32u(s, args[0], args[1]);
216
- break;
217
-
218
case INDEX_op_setcond_i32:
219
tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
220
const_args[2]);
221
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
222
case INDEX_op_ext32s_i64:
223
case INDEX_op_ext32u_i64:
224
case INDEX_op_ext_i32_i64:
225
+ case INDEX_op_extu_i32_i64:
226
default:
227
g_assert_not_reached();
228
}
229
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
230
index XXXXXXX..XXXXXXX 100644
231
--- a/tcg/riscv/tcg-target.c.inc
232
+++ b/tcg/riscv/tcg-target.c.inc
233
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)
234
tcg_out_ext32s(s, ret, arg);
235
}
236
237
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)
238
+{
239
+ tcg_out_ext32u(s, ret, arg);
240
+}
241
+
242
static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data,
243
TCGReg addr, intptr_t offset)
244
{
245
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
246
tcg_out_qemu_st(s, args, true);
247
break;
248
249
- case INDEX_op_extu_i32_i64:
250
- tcg_out_ext32u(s, a0, a1);
251
- break;
252
-
253
case INDEX_op_extrl_i64_i32:
254
tcg_out_ext32s(s, a0, a1);
255
break;
256
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
257
case INDEX_op_ext32s_i64:
258
case INDEX_op_ext32u_i64:
259
case INDEX_op_ext_i32_i64:
260
+ case INDEX_op_extu_i32_i64:
261
default:
262
g_assert_not_reached();
263
}
264
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
265
index XXXXXXX..XXXXXXX 100644
266
--- a/tcg/s390x/tcg-target.c.inc
267
+++ b/tcg/s390x/tcg-target.c.inc
268
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dest, TCGReg src)
269
tcg_out_ext32s(s, dest, src);
270
}
271
272
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dest, TCGReg src)
273
+{
274
+ tcg_out_ext32u(s, dest, src);
275
+}
276
+
277
static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
278
{
279
int msb, lsb;
280
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
226
}
281
}
227
- tcg_temp_free_i32(oi);
282
break;
228
- tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
283
229
-#else
284
- case INDEX_op_extu_i32_i64:
230
- /* Restart with exclusive lock. */
285
- tcg_out_ext32u(s, args[0], args[1]);
231
- gen_helper_exit_atomic(cpu_env);
286
- break;
232
- ctx->base.is_jmp = DISAS_NORETURN;
287
-
233
- tcg_temp_free(EA);
288
case INDEX_op_add2_i64:
234
- return;
289
if (const_args[4]) {
235
-#endif
290
if ((int64_t)args[4] >= 0) {
236
} else if (ctx->le_mode) {
291
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
237
tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ | MO_ALIGN_16);
292
case INDEX_op_ext32s_i64:
238
tcg_gen_mov_tl(cpu_reserve, EA);
293
case INDEX_op_ext32u_i64:
239
@@ -XXX,XX +XXX,XX @@ static void gen_stqcx_(DisasContext *ctx)
294
case INDEX_op_ext_i32_i64:
240
hi = cpu_gpr[rs];
295
+ case INDEX_op_extu_i32_i64:
241
296
default:
242
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
297
g_assert_not_reached();
243
- TCGv_i32 oi = tcg_const_i32(DEF_MEMOP(MO_Q) | MO_ALIGN_16);
298
}
244
-#ifdef CONFIG_ATOMIC128
299
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
245
- if (ctx->le_mode) {
300
index XXXXXXX..XXXXXXX 100644
246
- gen_helper_stqcx_le_parallel(cpu_crf[0], cpu_env, EA, lo, hi, oi);
301
--- a/tcg/sparc64/tcg-target.c.inc
247
+ if (HAVE_CMPXCHG128) {
302
+++ b/tcg/sparc64/tcg-target.c.inc
248
+ TCGv_i32 oi = tcg_const_i32(DEF_MEMOP(MO_Q) | MO_ALIGN_16);
303
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
249
+ if (ctx->le_mode) {
304
tcg_out_ext32s(s, rd, rs);
250
+ gen_helper_stqcx_le_parallel(cpu_crf[0], cpu_env,
305
}
251
+ EA, lo, hi, oi);
306
252
+ } else {
307
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
253
+ gen_helper_stqcx_be_parallel(cpu_crf[0], cpu_env,
308
+{
254
+ EA, lo, hi, oi);
309
+ tcg_out_ext32u(s, rd, rs);
255
+ }
310
+}
256
+ tcg_temp_free_i32(oi);
311
+
257
} else {
312
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
258
- gen_helper_stqcx_le_parallel(cpu_crf[0], cpu_env, EA, lo, hi, oi);
313
tcg_target_long imm)
259
+ /* Restart with exclusive lock. */
314
{
260
+ gen_helper_exit_atomic(cpu_env);
315
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
261
+ ctx->base.is_jmp = DISAS_NORETURN;
316
case INDEX_op_divu_i64:
262
}
317
c = ARITH_UDIVX;
263
-#else
318
goto gen_arith;
264
- /* Restart with exclusive lock. */
319
- case INDEX_op_extu_i32_i64:
265
- gen_helper_exit_atomic(cpu_env);
320
- tcg_out_ext32u(s, a0, a1);
266
- ctx->base.is_jmp = DISAS_NORETURN;
321
- break;
267
-#endif
322
case INDEX_op_extrl_i64_i32:
268
tcg_temp_free(EA);
323
tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
269
- tcg_temp_free_i32(oi);
324
break;
270
} else {
325
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
271
TCGLabel *lab_fail = gen_new_label();
326
case INDEX_op_ext32s_i64:
272
TCGLabel *lab_over = gen_new_label();
327
case INDEX_op_ext32u_i64:
328
case INDEX_op_ext_i32_i64:
329
+ case INDEX_op_extu_i32_i64:
330
default:
331
g_assert_not_reached();
332
}
333
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
334
index XXXXXXX..XXXXXXX 100644
335
--- a/tcg/tci/tcg-target.c.inc
336
+++ b/tcg/tci/tcg-target.c.inc
337
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
338
tcg_out_ext32s(s, rd, rs);
339
}
340
341
+static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
342
+{
343
+ tcg_out_ext32u(s, rd, rs);
344
+}
345
+
346
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
347
tcg_target_long imm)
348
{
349
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
350
351
CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
352
CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */
353
- CASE_64(extu_i32)
354
CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */
355
case INDEX_op_bswap32_i32: /* Optional (TCG_TARGET_HAS_bswap32_i32). */
356
case INDEX_op_bswap64_i64: /* Optional (TCG_TARGET_HAS_bswap64_i64). */
357
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
358
case INDEX_op_ext32s_i64:
359
case INDEX_op_ext32u_i64:
360
case INDEX_op_ext_i32_i64:
361
+ case INDEX_op_extu_i32_i64:
362
default:
363
g_assert_not_reached();
364
}
273
--
365
--
274
2.17.2
366
2.34.1
275
367
276
368
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
We will need a backend interface for type truncation. For those backends
2
that did not enable TCG_TARGET_HAS_extrl_i64_i32, use tcg_out_mov.
3
Use it in tcg_reg_alloc_op in the meantime.
2
4
3
We forgot to initialize n in commit 15fa08f845 ("tcg: Dynamically
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
allocate TCGOps", 2017-12-29).
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Emilio G. Cota <cota@braap.org>
8
Message-Id: <20181010144853.13005-3-cota@braap.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
7
---
11
tcg/tcg.c | 2 +-
8
tcg/tcg.c | 4 ++++
12
1 file changed, 1 insertion(+), 1 deletion(-)
9
tcg/aarch64/tcg-target.c.inc | 6 ++++++
10
tcg/arm/tcg-target.c.inc | 5 +++++
11
tcg/i386/tcg-target.c.inc | 9 ++++++---
12
tcg/loongarch64/tcg-target.c.inc | 10 ++++++----
13
tcg/mips/tcg-target.c.inc | 9 ++++++---
14
tcg/ppc/tcg-target.c.inc | 7 +++++++
15
tcg/riscv/tcg-target.c.inc | 10 ++++++----
16
tcg/s390x/tcg-target.c.inc | 6 ++++++
17
tcg/sparc64/tcg-target.c.inc | 9 ++++++---
18
tcg/tci/tcg-target.c.inc | 7 +++++++
19
11 files changed, 65 insertions(+), 17 deletions(-)
13
20
14
diff --git a/tcg/tcg.c b/tcg/tcg.c
21
diff --git a/tcg/tcg.c b/tcg/tcg.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/tcg.c
23
--- a/tcg/tcg.c
17
+++ b/tcg/tcg.c
24
+++ b/tcg/tcg.c
18
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
25
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg);
19
26
static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg);
20
#ifdef CONFIG_PROFILER
27
static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
21
{
28
static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
22
- int n;
29
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg);
23
+ int n = 0;
30
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
24
31
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
25
QTAILQ_FOREACH(op, &s->ops, link) {
32
static void tcg_out_goto_tb(TCGContext *s, int which);
26
n++;
33
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
34
case INDEX_op_extu_i32_i64:
35
tcg_out_extu_i32_i64(s, new_args[0], new_args[1]);
36
break;
37
+ case INDEX_op_extrl_i64_i32:
38
+ tcg_out_extrl_i64_i32(s, new_args[0], new_args[1]);
39
+ break;
40
default:
41
if (def->flags & TCG_OPF_VECTOR) {
42
tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op),
43
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
44
index XXXXXXX..XXXXXXX 100644
45
--- a/tcg/aarch64/tcg-target.c.inc
46
+++ b/tcg/aarch64/tcg-target.c.inc
47
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn)
48
tcg_out_ext32u(s, rd, rn);
49
}
50
51
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rn)
52
+{
53
+ tcg_out_mov(s, TCG_TYPE_I32, rd, rn);
54
+}
55
+
56
static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd,
57
TCGReg rn, int64_t aimm)
58
{
59
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
60
case INDEX_op_ext32u_i64:
61
case INDEX_op_ext_i32_i64:
62
case INDEX_op_extu_i32_i64:
63
+ case INDEX_op_extrl_i64_i32:
64
default:
65
g_assert_not_reached();
66
}
67
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
68
index XXXXXXX..XXXXXXX 100644
69
--- a/tcg/arm/tcg-target.c.inc
70
+++ b/tcg/arm/tcg-target.c.inc
71
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn)
72
g_assert_not_reached();
73
}
74
75
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rn)
76
+{
77
+ g_assert_not_reached();
78
+}
79
+
80
static void tcg_out_bswap16(TCGContext *s, ARMCond cond,
81
TCGReg rd, TCGReg rn, int flags)
82
{
83
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
84
index XXXXXXX..XXXXXXX 100644
85
--- a/tcg/i386/tcg-target.c.inc
86
+++ b/tcg/i386/tcg-target.c.inc
87
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dest, TCGReg src)
88
tcg_out_ext32u(s, dest, src);
89
}
90
91
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg dest, TCGReg src)
92
+{
93
+ tcg_out_ext32u(s, dest, src);
94
+}
95
+
96
static inline void tcg_out_bswap64(TCGContext *s, int reg)
97
{
98
tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0);
99
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
100
case INDEX_op_bswap64_i64:
101
tcg_out_bswap64(s, a0);
102
break;
103
- case INDEX_op_extrl_i64_i32:
104
- tcg_out_ext32u(s, a0, a1);
105
- break;
106
case INDEX_op_extrh_i64_i32:
107
tcg_out_shifti(s, SHIFT_SHR + P_REXW, a0, 32);
108
break;
109
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
110
case INDEX_op_ext32u_i64:
111
case INDEX_op_ext_i32_i64:
112
case INDEX_op_extu_i32_i64:
113
+ case INDEX_op_extrl_i64_i32:
114
default:
115
g_assert_not_reached();
116
}
117
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
118
index XXXXXXX..XXXXXXX 100644
119
--- a/tcg/loongarch64/tcg-target.c.inc
120
+++ b/tcg/loongarch64/tcg-target.c.inc
121
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)
122
tcg_out_ext32u(s, ret, arg);
123
}
124
125
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg)
126
+{
127
+ tcg_out_ext32s(s, ret, arg);
128
+}
129
+
130
static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc,
131
TCGReg a0, TCGReg a1, TCGReg a2,
132
bool c2, bool is_32bit)
133
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
134
tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
135
break;
136
137
- case INDEX_op_extrl_i64_i32:
138
- tcg_out_ext32s(s, a0, a1);
139
- break;
140
-
141
case INDEX_op_extrh_i64_i32:
142
tcg_out_opc_srai_d(s, a0, a1, 32);
143
break;
144
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
145
case INDEX_op_ext32u_i64:
146
case INDEX_op_ext_i32_i64:
147
case INDEX_op_extu_i32_i64:
148
+ case INDEX_op_extrl_i64_i32:
149
default:
150
g_assert_not_reached();
151
}
152
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
153
index XXXXXXX..XXXXXXX 100644
154
--- a/tcg/mips/tcg-target.c.inc
155
+++ b/tcg/mips/tcg-target.c.inc
156
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
157
tcg_out_ext32u(s, rd, rs);
158
}
159
160
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
161
+{
162
+ tcg_out_ext32s(s, rd, rs);
163
+}
164
+
165
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
166
tcg_target_long imm)
167
{
168
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
169
case INDEX_op_extrh_i64_i32:
170
tcg_out_dsra(s, a0, a1, 32);
171
break;
172
- case INDEX_op_extrl_i64_i32:
173
- tcg_out_ext32s(s, a0, a1);
174
- break;
175
176
case INDEX_op_sar_i32:
177
i1 = OPC_SRAV, i2 = OPC_SRA;
178
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
179
case INDEX_op_ext32u_i64:
180
case INDEX_op_ext_i32_i64:
181
case INDEX_op_extu_i32_i64:
182
+ case INDEX_op_extrl_i64_i32:
183
default:
184
g_assert_not_reached();
185
}
186
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
187
index XXXXXXX..XXXXXXX 100644
188
--- a/tcg/ppc/tcg-target.c.inc
189
+++ b/tcg/ppc/tcg-target.c.inc
190
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dst, TCGReg src)
191
tcg_out_ext32u(s, dst, src);
192
}
193
194
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rn)
195
+{
196
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
197
+ tcg_out_mov(s, TCG_TYPE_I32, rd, rn);
198
+}
199
+
200
static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c)
201
{
202
tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c);
203
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
204
case INDEX_op_ext32u_i64:
205
case INDEX_op_ext_i32_i64:
206
case INDEX_op_extu_i32_i64:
207
+ case INDEX_op_extrl_i64_i32:
208
default:
209
g_assert_not_reached();
210
}
211
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
212
index XXXXXXX..XXXXXXX 100644
213
--- a/tcg/riscv/tcg-target.c.inc
214
+++ b/tcg/riscv/tcg-target.c.inc
215
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)
216
tcg_out_ext32u(s, ret, arg);
217
}
218
219
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg)
220
+{
221
+ tcg_out_ext32s(s, ret, arg);
222
+}
223
+
224
static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data,
225
TCGReg addr, intptr_t offset)
226
{
227
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
228
tcg_out_qemu_st(s, args, true);
229
break;
230
231
- case INDEX_op_extrl_i64_i32:
232
- tcg_out_ext32s(s, a0, a1);
233
- break;
234
-
235
case INDEX_op_extrh_i64_i32:
236
tcg_out_opc_imm(s, OPC_SRAI, a0, a1, 32);
237
break;
238
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
239
case INDEX_op_ext32u_i64:
240
case INDEX_op_ext_i32_i64:
241
case INDEX_op_extu_i32_i64:
242
+ case INDEX_op_extrl_i64_i32:
243
default:
244
g_assert_not_reached();
245
}
246
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
247
index XXXXXXX..XXXXXXX 100644
248
--- a/tcg/s390x/tcg-target.c.inc
249
+++ b/tcg/s390x/tcg-target.c.inc
250
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dest, TCGReg src)
251
tcg_out_ext32u(s, dest, src);
252
}
253
254
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg dest, TCGReg src)
255
+{
256
+ tcg_out_mov(s, TCG_TYPE_I32, dest, src);
257
+}
258
+
259
static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
260
{
261
int msb, lsb;
262
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
263
case INDEX_op_ext32u_i64:
264
case INDEX_op_ext_i32_i64:
265
case INDEX_op_extu_i32_i64:
266
+ case INDEX_op_extrl_i64_i32:
267
default:
268
g_assert_not_reached();
269
}
270
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
271
index XXXXXXX..XXXXXXX 100644
272
--- a/tcg/sparc64/tcg-target.c.inc
273
+++ b/tcg/sparc64/tcg-target.c.inc
274
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
275
tcg_out_ext32u(s, rd, rs);
276
}
277
278
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
279
+{
280
+ tcg_out_mov(s, TCG_TYPE_I32, rd, rs);
281
+}
282
+
283
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
284
tcg_target_long imm)
285
{
286
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
287
case INDEX_op_divu_i64:
288
c = ARITH_UDIVX;
289
goto gen_arith;
290
- case INDEX_op_extrl_i64_i32:
291
- tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
292
- break;
293
case INDEX_op_extrh_i64_i32:
294
tcg_out_arithi(s, a0, a1, 32, SHIFT_SRLX);
295
break;
296
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
297
case INDEX_op_ext32u_i64:
298
case INDEX_op_ext_i32_i64:
299
case INDEX_op_extu_i32_i64:
300
+ case INDEX_op_extrl_i64_i32:
301
default:
302
g_assert_not_reached();
303
}
304
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
305
index XXXXXXX..XXXXXXX 100644
306
--- a/tcg/tci/tcg-target.c.inc
307
+++ b/tcg/tci/tcg-target.c.inc
308
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
309
tcg_out_ext32u(s, rd, rs);
310
}
311
312
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
313
+{
314
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
315
+ tcg_out_mov(s, TCG_TYPE_I32, rd, rs);
316
+}
317
+
318
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
319
tcg_target_long imm)
320
{
321
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
322
case INDEX_op_ext32u_i64:
323
case INDEX_op_ext_i32_i64:
324
case INDEX_op_extu_i32_i64:
325
+ case INDEX_op_extrl_i64_i32:
326
default:
327
g_assert_not_reached();
328
}
27
--
329
--
28
2.17.2
330
2.34.1
29
331
30
332
diff view generated by jsdifflib
1
Reviewed-by: Emilio G. Cota <cota@braap.org>
1
This is common code in most qemu_{ld,st} slow paths, extending the
2
input value for the store helper data argument or extending the
3
return value from the load helper.
4
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
7
---
4
target/arm/helper-a64.c | 259 +++++++++++++++++++++-------------------
8
tcg/tcg.c | 63 ++++++++++++++++++++++++++++++++
5
1 file changed, 133 insertions(+), 126 deletions(-)
9
tcg/aarch64/tcg-target.c.inc | 8 +---
10
tcg/arm/tcg-target.c.inc | 16 ++------
11
tcg/i386/tcg-target.c.inc | 30 +++------------
12
tcg/loongarch64/tcg-target.c.inc | 53 ++++-----------------------
13
tcg/ppc/tcg-target.c.inc | 38 +++++--------------
14
tcg/riscv/tcg-target.c.inc | 13 +------
15
tcg/s390x/tcg-target.c.inc | 19 ++--------
16
tcg/sparc64/tcg-target.c.inc | 31 +++-------------
17
9 files changed, 103 insertions(+), 168 deletions(-)
6
18
7
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
19
diff --git a/tcg/tcg.c b/tcg/tcg.c
8
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
9
--- a/target/arm/helper-a64.c
21
--- a/tcg/tcg.c
10
+++ b/target/arm/helper-a64.c
22
+++ b/tcg/tcg.c
11
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ void tcg_raise_tb_overflow(TCGContext *s)
12
#include "exec/exec-all.h"
24
siglongjmp(s->jmp_trans, -2);
13
#include "exec/cpu_ldst.h"
14
#include "qemu/int128.h"
15
+#include "qemu/atomic128.h"
16
#include "tcg.h"
17
#include "fpu/softfloat.h"
18
#include <zlib.h> /* For crc32 */
19
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(crc32c_64)(uint64_t acc, uint64_t val, uint32_t bytes)
20
return crc32c(acc, buf, bytes) ^ 0xffffffff;
21
}
25
}
22
26
23
-/* Returns 0 on success; 1 otherwise. */
27
+/**
24
-static uint64_t do_paired_cmpxchg64_le(CPUARMState *env, uint64_t addr,
28
+ * tcg_out_movext -- move and extend
25
- uint64_t new_lo, uint64_t new_hi,
29
+ * @s: tcg context
26
- bool parallel, uintptr_t ra)
30
+ * @dst_type: integral type for destination
27
+uint64_t HELPER(paired_cmpxchg64_le)(CPUARMState *env, uint64_t addr,
31
+ * @dst: destination register
28
+ uint64_t new_lo, uint64_t new_hi)
32
+ * @src_type: integral type for source
33
+ * @src_ext: extension to apply to source
34
+ * @src: source register
35
+ *
36
+ * Move or extend @src into @dst, depending on @src_ext and the types.
37
+ */
38
+static void __attribute__((unused))
39
+tcg_out_movext(TCGContext *s, TCGType dst_type, TCGReg dst,
40
+ TCGType src_type, MemOp src_ext, TCGReg src)
41
+{
42
+ switch (src_ext) {
43
+ case MO_UB:
44
+ tcg_out_ext8u(s, dst, src);
45
+ break;
46
+ case MO_SB:
47
+ tcg_out_ext8s(s, dst_type, dst, src);
48
+ break;
49
+ case MO_UW:
50
+ tcg_out_ext16u(s, dst, src);
51
+ break;
52
+ case MO_SW:
53
+ tcg_out_ext16s(s, dst_type, dst, src);
54
+ break;
55
+ case MO_UL:
56
+ case MO_SL:
57
+ if (dst_type == TCG_TYPE_I32) {
58
+ if (src_type == TCG_TYPE_I32) {
59
+ tcg_out_mov(s, TCG_TYPE_I32, dst, src);
60
+ } else {
61
+ tcg_out_extrl_i64_i32(s, dst, src);
62
+ }
63
+ } else if (src_type == TCG_TYPE_I32) {
64
+ if (src_ext & MO_SIGN) {
65
+ tcg_out_exts_i32_i64(s, dst, src);
66
+ } else {
67
+ tcg_out_extu_i32_i64(s, dst, src);
68
+ }
69
+ } else {
70
+ if (src_ext & MO_SIGN) {
71
+ tcg_out_ext32s(s, dst, src);
72
+ } else {
73
+ tcg_out_ext32u(s, dst, src);
74
+ }
75
+ }
76
+ break;
77
+ case MO_UQ:
78
+ tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
79
+ if (dst_type == TCG_TYPE_I32) {
80
+ tcg_out_extrl_i64_i32(s, dst, src);
81
+ } else {
82
+ tcg_out_mov(s, TCG_TYPE_I64, dst, src);
83
+ }
84
+ break;
85
+ default:
86
+ g_assert_not_reached();
87
+ }
88
+}
89
+
90
#define C_PFX1(P, A) P##A
91
#define C_PFX2(P, A, B) P##A##_##B
92
#define C_PFX3(P, A, B, C) P##A##_##B##_##C
93
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
94
index XXXXXXX..XXXXXXX 100644
95
--- a/tcg/aarch64/tcg-target.c.inc
96
+++ b/tcg/aarch64/tcg-target.c.inc
97
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
29
{
98
{
30
- Int128 oldv, cmpv, newv;
99
MemOpIdx oi = lb->oi;
31
+ Int128 cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
100
MemOp opc = get_memop(oi);
32
+ Int128 newv = int128_make128(new_lo, new_hi);
101
- MemOp size = opc & MO_SIZE;
33
+ Int128 oldv;
102
34
+ uintptr_t ra = GETPC();
103
if (!reloc_pc19(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
35
+ uint64_t o0, o1;
104
return false;
36
bool success;
105
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
37
106
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, oi);
38
- cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
107
tcg_out_adr(s, TCG_REG_X3, lb->raddr);
39
- newv = int128_make128(new_lo, new_hi);
108
tcg_out_call_int(s, qemu_ld_helpers[opc & MO_SIZE]);
109
- if (opc & MO_SIGN) {
110
- tcg_out_sxt(s, lb->type, size, lb->datalo_reg, TCG_REG_X0);
111
- } else {
112
- tcg_out_mov(s, size == MO_64, lb->datalo_reg, TCG_REG_X0);
113
- }
114
115
+ tcg_out_movext(s, lb->type, lb->datalo_reg,
116
+ TCG_TYPE_REG, opc & MO_SSIZE, TCG_REG_X0);
117
tcg_out_goto(s, lb->raddr);
118
return true;
119
}
120
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
121
index XXXXXXX..XXXXXXX 100644
122
--- a/tcg/arm/tcg-target.c.inc
123
+++ b/tcg/arm/tcg-target.c.inc
124
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
125
126
datalo = lb->datalo_reg;
127
datahi = lb->datahi_reg;
128
- switch (opc & MO_SSIZE) {
129
- case MO_SB:
130
- tcg_out_ext8s(s, TCG_TYPE_I32, datalo, TCG_REG_R0);
131
- break;
132
- case MO_SW:
133
- tcg_out_ext16s(s, TCG_TYPE_I32, datalo, TCG_REG_R0);
134
- break;
135
- default:
136
- tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0);
137
- break;
138
- case MO_UQ:
139
+ if ((opc & MO_SIZE) == MO_64) {
140
if (datalo != TCG_REG_R1) {
141
tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0);
142
tcg_out_mov_reg(s, COND_AL, datahi, TCG_REG_R1);
143
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
144
tcg_out_mov_reg(s, COND_AL, datahi, TCG_REG_R1);
145
tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_TMP);
146
}
147
- break;
148
+ } else {
149
+ tcg_out_movext(s, TCG_TYPE_I32, datalo,
150
+ TCG_TYPE_I32, opc & MO_SSIZE, TCG_REG_R0);
151
}
152
153
tcg_out_goto(s, COND_AL, lb->raddr);
154
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
155
index XXXXXXX..XXXXXXX 100644
156
--- a/tcg/i386/tcg-target.c.inc
157
+++ b/tcg/i386/tcg-target.c.inc
158
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
159
tcg_out_branch(s, 1, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]);
160
161
data_reg = l->datalo_reg;
162
- switch (opc & MO_SSIZE) {
163
- case MO_SB:
164
- tcg_out_ext8s(s, l->type, data_reg, TCG_REG_EAX);
165
- break;
166
- case MO_SW:
167
- tcg_out_ext16s(s, l->type, data_reg, TCG_REG_EAX);
168
- break;
169
-#if TCG_TARGET_REG_BITS == 64
170
- case MO_SL:
171
- tcg_out_ext32s(s, data_reg, TCG_REG_EAX);
172
- break;
173
-#endif
174
- case MO_UB:
175
- case MO_UW:
176
- /* Note that the helpers have zero-extended to tcg_target_long. */
177
- case MO_UL:
178
- tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
179
- break;
180
- case MO_UQ:
181
- if (TCG_TARGET_REG_BITS == 64) {
182
- tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX);
183
- } else if (data_reg == TCG_REG_EDX) {
184
+ if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
185
+ if (data_reg == TCG_REG_EDX) {
186
/* xchg %edx, %eax */
187
tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0);
188
tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EAX);
189
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
190
tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
191
tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EDX);
192
}
193
- break;
194
- default:
195
- g_assert_not_reached();
196
+ } else {
197
+ tcg_out_movext(s, l->type, data_reg,
198
+ TCG_TYPE_REG, opc & MO_SSIZE, TCG_REG_EAX);
199
}
200
201
/* Jump to the code corresponding to next IR of qemu_st */
202
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
203
index XXXXXXX..XXXXXXX 100644
204
--- a/tcg/loongarch64/tcg-target.c.inc
205
+++ b/tcg/loongarch64/tcg-target.c.inc
206
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
207
MemOpIdx oi = l->oi;
208
MemOp opc = get_memop(oi);
209
MemOp size = opc & MO_SIZE;
210
- TCGType type = l->type;
211
212
/* resolve label address */
213
if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
214
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
215
216
tcg_out_call_int(s, qemu_ld_helpers[size], false);
217
218
- switch (opc & MO_SSIZE) {
219
- case MO_SB:
220
- tcg_out_ext8s(s, type, l->datalo_reg, TCG_REG_A0);
221
- break;
222
- case MO_SW:
223
- tcg_out_ext16s(s, type, l->datalo_reg, TCG_REG_A0);
224
- break;
225
- case MO_SL:
226
- tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0);
227
- break;
228
- case MO_UL:
229
- if (type == TCG_TYPE_I32) {
230
- /* MO_UL loads of i32 should be sign-extended too */
231
- tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0);
232
- break;
233
- }
234
- /* fallthrough */
235
- default:
236
- tcg_out_mov(s, type, l->datalo_reg, TCG_REG_A0);
237
- break;
238
- }
40
-
239
-
41
- if (parallel) {
240
+ tcg_out_movext(s, l->type, l->datalo_reg,
42
-#ifndef CONFIG_ATOMIC128
241
+ TCG_TYPE_REG, opc & MO_SSIZE, TCG_REG_A0);
43
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
242
return tcg_out_goto(s, l->raddr);
44
-#else
243
}
45
- int mem_idx = cpu_mmu_index(env, false);
244
46
- TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
245
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
47
- oldv = helper_atomic_cmpxchgo_le_mmu(env, addr, cmpv, newv, oi, ra);
246
/* call store helper */
48
- success = int128_eq(oldv, cmpv);
247
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0);
49
-#endif
248
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg);
50
- } else {
249
- switch (size) {
51
- uint64_t o0, o1;
250
- case MO_8:
251
- tcg_out_ext8u(s, TCG_REG_A2, l->datalo_reg);
252
- break;
253
- case MO_16:
254
- tcg_out_ext16u(s, TCG_REG_A2, l->datalo_reg);
255
- break;
256
- case MO_32:
257
- tcg_out_ext32u(s, TCG_REG_A2, l->datalo_reg);
258
- break;
259
- case MO_64:
260
- tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_A2, l->datalo_reg);
261
- break;
262
- default:
263
- g_assert_not_reached();
264
- break;
265
- }
266
+ tcg_out_movext(s, size == MO_64 ? TCG_TYPE_I32 : TCG_TYPE_I32, TCG_REG_A2,
267
+ l->type, size, l->datalo_reg);
268
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, oi);
269
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A4, (tcg_target_long)l->raddr);
270
271
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_indexed(TCGContext *s, TCGReg data,
272
}
273
}
274
275
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args)
276
+static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGType type)
277
{
278
TCGReg addr_regl;
279
TCGReg data_regl;
280
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args)
281
tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 0);
282
base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0);
283
tcg_out_qemu_st_indexed(s, data_regl, base, TCG_REG_TMP2, opc);
284
- add_qemu_ldst_label(s, 0, oi,
285
- 0, /* type param is unused for stores */
286
+ add_qemu_ldst_label(s, 0, oi, type,
287
data_regl, addr_regl,
288
s->code_ptr, label_ptr);
289
#else
290
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
291
tcg_out_qemu_ld(s, args, TCG_TYPE_I64);
292
break;
293
case INDEX_op_qemu_st_i32:
294
- tcg_out_qemu_st(s, args);
295
+ tcg_out_qemu_st(s, args, TCG_TYPE_I32);
296
break;
297
case INDEX_op_qemu_st_i64:
298
- tcg_out_qemu_st(s, args);
299
+ tcg_out_qemu_st(s, args, TCG_TYPE_I64);
300
break;
301
302
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
303
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
304
index XXXXXXX..XXXXXXX 100644
305
--- a/tcg/ppc/tcg-target.c.inc
306
+++ b/tcg/ppc/tcg-target.c.inc
307
@@ -XXX,XX +XXX,XX @@ static const uint32_t qemu_stx_opc[(MO_SIZE + MO_BSWAP) + 1] = {
308
[MO_BSWAP | MO_UQ] = STDBRX,
309
};
310
311
-static const uint32_t qemu_exts_opc[4] = {
312
- EXTSB, EXTSH, EXTSW, 0
313
-};
52
-
314
-
53
#ifdef CONFIG_USER_ONLY
315
#if defined (CONFIG_SOFTMMU)
54
- /* ??? Enforce alignment. */
316
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
55
- uint64_t *haddr = g2h(addr);
317
* int mmu_idx, uintptr_t ra)
56
+ /* ??? Enforce alignment. */
318
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
57
+ uint64_t *haddr = g2h(addr);
319
if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
58
320
tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_REG_R4);
59
- helper_retaddr = ra;
321
tcg_out_mov(s, TCG_TYPE_I32, hi, TCG_REG_R3);
60
- o0 = ldq_le_p(haddr + 0);
322
- } else if (opc & MO_SIGN) {
61
- o1 = ldq_le_p(haddr + 1);
323
- uint32_t insn = qemu_exts_opc[opc & MO_SIZE];
62
- oldv = int128_make128(o0, o1);
324
- tcg_out32(s, insn | RA(lo) | RS(TCG_REG_R3));
63
+ helper_retaddr = ra;
325
} else {
64
+ o0 = ldq_le_p(haddr + 0);
326
- tcg_out_mov(s, TCG_TYPE_REG, lo, TCG_REG_R3);
65
+ o1 = ldq_le_p(haddr + 1);
327
+ tcg_out_movext(s, lb->type, lo,
66
+ oldv = int128_make128(o0, o1);
328
+ TCG_TYPE_REG, opc & MO_SSIZE, TCG_REG_R3);
67
329
}
68
- success = int128_eq(oldv, cmpv);
330
69
- if (success) {
331
tcg_out_b(s, 0, lb->raddr);
70
- stq_le_p(haddr + 0, int128_getlo(newv));
332
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
71
- stq_le_p(haddr + 1, int128_gethi(newv));
333
334
lo = lb->datalo_reg;
335
hi = lb->datahi_reg;
336
- if (TCG_TARGET_REG_BITS == 32) {
337
- switch (s_bits) {
338
- case MO_64:
339
- arg |= (TCG_TARGET_CALL_ARG_I64 == TCG_CALL_ARG_EVEN);
340
- tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
341
- /* FALLTHRU */
342
- case MO_32:
343
- tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
344
- break;
345
- default:
346
- tcg_out_rlw(s, RLWINM, arg++, lo, 0, 32 - (8 << s_bits), 31);
347
- break;
72
- }
348
- }
73
- helper_retaddr = 0;
349
+ if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
74
-#else
350
+ arg |= (TCG_TARGET_CALL_ARG_I64 == TCG_CALL_ARG_EVEN);
75
- int mem_idx = cpu_mmu_index(env, false);
351
+ tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
76
- TCGMemOpIdx oi0 = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
352
+ tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
77
- TCGMemOpIdx oi1 = make_memop_idx(MO_LEQ, mem_idx);
353
} else {
78
-
354
- if (s_bits == MO_64) {
79
- o0 = helper_le_ldq_mmu(env, addr + 0, oi0, ra);
355
- tcg_out_mov(s, TCG_TYPE_I64, arg++, lo);
80
- o1 = helper_le_ldq_mmu(env, addr + 8, oi1, ra);
356
- } else {
81
- oldv = int128_make128(o0, o1);
357
- tcg_out_rld(s, RLDICL, arg++, lo, 0, 64 - (8 << s_bits));
82
-
83
- success = int128_eq(oldv, cmpv);
84
- if (success) {
85
- helper_le_stq_mmu(env, addr + 0, int128_getlo(newv), oi1, ra);
86
- helper_le_stq_mmu(env, addr + 8, int128_gethi(newv), oi1, ra);
87
- }
358
- }
88
-#endif
359
+ tcg_out_movext(s, s_bits == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32,
89
+ success = int128_eq(oldv, cmpv);
360
+ arg++, lb->type, s_bits, lo);
90
+ if (success) {
361
}
91
+ stq_le_p(haddr + 0, int128_getlo(newv));
362
92
+ stq_le_p(haddr + 1, int128_gethi(newv));
363
tcg_out_movi(s, TCG_TYPE_I32, arg++, oi);
93
}
364
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
94
+ helper_retaddr = 0;
365
} else {
95
+#else
366
insn = qemu_ldx_opc[opc & (MO_SIZE | MO_BSWAP)];
96
+ int mem_idx = cpu_mmu_index(env, false);
367
tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
97
+ TCGMemOpIdx oi0 = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
368
- insn = qemu_exts_opc[s_bits];
98
+ TCGMemOpIdx oi1 = make_memop_idx(MO_LEQ, mem_idx);
369
- tcg_out32(s, insn | RA(datalo) | RS(datalo));
99
+
370
+ tcg_out_movext(s, TCG_TYPE_REG, datalo,
100
+ o0 = helper_le_ldq_mmu(env, addr + 0, oi0, ra);
371
+ TCG_TYPE_REG, opc & MO_SSIZE, datalo);
101
+ o1 = helper_le_ldq_mmu(env, addr + 8, oi1, ra);
372
}
102
+ oldv = int128_make128(o0, o1);
373
}
103
+
374
104
+ success = int128_eq(oldv, cmpv);
375
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
105
+ if (success) {
376
index XXXXXXX..XXXXXXX 100644
106
+ helper_le_stq_mmu(env, addr + 0, int128_getlo(newv), oi1, ra);
377
--- a/tcg/riscv/tcg-target.c.inc
107
+ helper_le_stq_mmu(env, addr + 8, int128_gethi(newv), oi1, ra);
378
+++ b/tcg/riscv/tcg-target.c.inc
108
+ }
379
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
109
+#endif
380
/* call store helper */
110
381
tcg_out_mov(s, TCG_TYPE_PTR, a0, TCG_AREG0);
111
return !success;
382
tcg_out_mov(s, TCG_TYPE_PTR, a1, l->addrlo_reg);
112
}
383
- tcg_out_mov(s, TCG_TYPE_PTR, a2, l->datalo_reg);
113
384
- switch (s_bits) {
114
-uint64_t HELPER(paired_cmpxchg64_le)(CPUARMState *env, uint64_t addr,
385
- case MO_8:
115
- uint64_t new_lo, uint64_t new_hi)
386
- tcg_out_ext8u(s, a2, a2);
387
- break;
388
- case MO_16:
389
- tcg_out_ext16u(s, a2, a2);
390
- break;
391
- default:
392
- break;
393
- }
394
+ tcg_out_movext(s, s_bits == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32, a2,
395
+ l->type, s_bits, l->datalo_reg);
396
tcg_out_movi(s, TCG_TYPE_PTR, a3, oi);
397
tcg_out_movi(s, TCG_TYPE_PTR, a4, (tcg_target_long)l->raddr);
398
399
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
400
index XXXXXXX..XXXXXXX 100644
401
--- a/tcg/s390x/tcg-target.c.inc
402
+++ b/tcg/s390x/tcg-target.c.inc
403
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
404
TCGReg data_reg = lb->datalo_reg;
405
MemOpIdx oi = lb->oi;
406
MemOp opc = get_memop(oi);
407
+ MemOp size = opc & MO_SIZE;
408
409
if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
410
(intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
411
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
412
if (TARGET_LONG_BITS == 64) {
413
tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
414
}
415
- switch (opc & MO_SIZE) {
416
- case MO_UB:
417
- tcg_out_ext8u(s, TCG_REG_R4, data_reg);
418
- break;
419
- case MO_UW:
420
- tcg_out_ext16u(s, TCG_REG_R4, data_reg);
421
- break;
422
- case MO_UL:
423
- tcg_out_ext32u(s, TCG_REG_R4, data_reg);
424
- break;
425
- case MO_UQ:
426
- tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg);
427
- break;
428
- default:
429
- g_assert_not_reached();
430
- }
431
+ tcg_out_movext(s, size == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32,
432
+ TCG_REG_R4, lb->type, size, data_reg);
433
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi);
434
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr);
435
tcg_out_call_int(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
436
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
437
index XXXXXXX..XXXXXXX 100644
438
--- a/tcg/sparc64/tcg-target.c.inc
439
+++ b/tcg/sparc64/tcg-target.c.inc
440
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
441
static const tcg_insn_unit *qemu_ld_trampoline[(MO_SSIZE | MO_BSWAP) + 1];
442
static const tcg_insn_unit *qemu_st_trampoline[(MO_SIZE | MO_BSWAP) + 1];
443
444
-static void emit_extend(TCGContext *s, TCGReg r, int op)
116
-{
445
-{
117
- return do_paired_cmpxchg64_le(env, addr, new_lo, new_hi, false, GETPC());
446
- /* Emit zero extend of 8, 16 or 32 bit data as
447
- * required by the MO_* value op; do nothing for 64 bit.
448
- */
449
- switch (op & MO_SIZE) {
450
- case MO_8:
451
- tcg_out_ext8u(s, r, r);
452
- break;
453
- case MO_16:
454
- tcg_out_ext16u(s, r, r);
455
- break;
456
- case MO_32:
457
- tcg_out_ext32u(s, r, r);
458
- break;
459
- case MO_64:
460
- break;
461
- }
118
-}
462
-}
119
-
463
-
120
uint64_t HELPER(paired_cmpxchg64_le_parallel)(CPUARMState *env, uint64_t addr,
464
static void build_trampolines(TCGContext *s)
121
uint64_t new_lo, uint64_t new_hi)
465
{
122
-{
466
static void * const qemu_ld_helpers[] = {
123
- return do_paired_cmpxchg64_le(env, addr, new_lo, new_hi, true, GETPC());
467
@@ -XXX,XX +XXX,XX @@ static void build_trampolines(TCGContext *s)
124
-}
468
}
469
qemu_st_trampoline[i] = tcg_splitwx_to_rx(s->code_ptr);
470
471
- emit_extend(s, TCG_REG_O2, i);
125
-
472
-
126
-static uint64_t do_paired_cmpxchg64_be(CPUARMState *env, uint64_t addr,
473
/* Set the retaddr operand. */
127
- uint64_t new_lo, uint64_t new_hi,
474
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O4, TCG_REG_O7);
128
- bool parallel, uintptr_t ra)
475
476
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
477
}
478
479
static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
480
- MemOpIdx oi)
481
+ MemOpIdx oi, TCGType data_type)
129
{
482
{
130
Int128 oldv, cmpv, newv;
483
MemOp memop = get_memop(oi);
131
+ uintptr_t ra = GETPC();
484
tcg_insn_unit *label_ptr;
132
bool success;
485
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
133
+ int mem_idx;
486
/* TLB Miss. */
134
+ TCGMemOpIdx oi;
487
135
488
tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O1, addrz);
136
- /* high and low need to be switched here because this is not actually a
489
- tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O2, data);
137
- * 128bit store but two doublewords stored consecutively
490
+ tcg_out_movext(s, (memop & MO_SIZE) == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32,
138
- */
491
+ TCG_REG_O2, data_type, memop & MO_SIZE, data);
139
- cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
492
140
- newv = int128_make128(new_hi, new_lo);
493
func = qemu_st_trampoline[memop & (MO_BSWAP | MO_SIZE)];
141
-
494
tcg_debug_assert(func != NULL);
142
- if (parallel) {
495
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
143
-#ifndef CONFIG_ATOMIC128
496
tcg_out_qemu_ld(s, a0, a1, a2, true);
144
+ if (!HAVE_CMPXCHG128) {
497
break;
145
cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
498
case INDEX_op_qemu_st_i32:
146
-#else
499
+ tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32);
147
- int mem_idx = cpu_mmu_index(env, false);
500
+ break;
148
- TCGMemOpIdx oi = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
501
case INDEX_op_qemu_st_i64:
149
- oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
502
- tcg_out_qemu_st(s, a0, a1, a2);
150
- success = int128_eq(oldv, cmpv);
503
+ tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64);
151
-#endif
504
break;
152
- } else {
505
153
- uint64_t o0, o1;
506
case INDEX_op_ld32s_i64:
154
-
155
-#ifdef CONFIG_USER_ONLY
156
- /* ??? Enforce alignment. */
157
- uint64_t *haddr = g2h(addr);
158
-
159
- helper_retaddr = ra;
160
- o1 = ldq_be_p(haddr + 0);
161
- o0 = ldq_be_p(haddr + 1);
162
- oldv = int128_make128(o0, o1);
163
-
164
- success = int128_eq(oldv, cmpv);
165
- if (success) {
166
- stq_be_p(haddr + 0, int128_gethi(newv));
167
- stq_be_p(haddr + 1, int128_getlo(newv));
168
- }
169
- helper_retaddr = 0;
170
-#else
171
- int mem_idx = cpu_mmu_index(env, false);
172
- TCGMemOpIdx oi0 = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
173
- TCGMemOpIdx oi1 = make_memop_idx(MO_BEQ, mem_idx);
174
-
175
- o1 = helper_be_ldq_mmu(env, addr + 0, oi0, ra);
176
- o0 = helper_be_ldq_mmu(env, addr + 8, oi1, ra);
177
- oldv = int128_make128(o0, o1);
178
-
179
- success = int128_eq(oldv, cmpv);
180
- if (success) {
181
- helper_be_stq_mmu(env, addr + 0, int128_gethi(newv), oi1, ra);
182
- helper_be_stq_mmu(env, addr + 8, int128_getlo(newv), oi1, ra);
183
- }
184
-#endif
185
}
186
187
+ mem_idx = cpu_mmu_index(env, false);
188
+ oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
189
+
190
+ cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
191
+ newv = int128_make128(new_lo, new_hi);
192
+ oldv = helper_atomic_cmpxchgo_le_mmu(env, addr, cmpv, newv, oi, ra);
193
+
194
+ success = int128_eq(oldv, cmpv);
195
return !success;
196
}
197
198
uint64_t HELPER(paired_cmpxchg64_be)(CPUARMState *env, uint64_t addr,
199
uint64_t new_lo, uint64_t new_hi)
200
{
201
- return do_paired_cmpxchg64_be(env, addr, new_lo, new_hi, false, GETPC());
202
+ /*
203
+ * High and low need to be switched here because this is not actually a
204
+ * 128bit store but two doublewords stored consecutively
205
+ */
206
+ Int128 cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
207
+ Int128 newv = int128_make128(new_lo, new_hi);
208
+ Int128 oldv;
209
+ uintptr_t ra = GETPC();
210
+ uint64_t o0, o1;
211
+ bool success;
212
+
213
+#ifdef CONFIG_USER_ONLY
214
+ /* ??? Enforce alignment. */
215
+ uint64_t *haddr = g2h(addr);
216
+
217
+ helper_retaddr = ra;
218
+ o1 = ldq_be_p(haddr + 0);
219
+ o0 = ldq_be_p(haddr + 1);
220
+ oldv = int128_make128(o0, o1);
221
+
222
+ success = int128_eq(oldv, cmpv);
223
+ if (success) {
224
+ stq_be_p(haddr + 0, int128_gethi(newv));
225
+ stq_be_p(haddr + 1, int128_getlo(newv));
226
+ }
227
+ helper_retaddr = 0;
228
+#else
229
+ int mem_idx = cpu_mmu_index(env, false);
230
+ TCGMemOpIdx oi0 = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
231
+ TCGMemOpIdx oi1 = make_memop_idx(MO_BEQ, mem_idx);
232
+
233
+ o1 = helper_be_ldq_mmu(env, addr + 0, oi0, ra);
234
+ o0 = helper_be_ldq_mmu(env, addr + 8, oi1, ra);
235
+ oldv = int128_make128(o0, o1);
236
+
237
+ success = int128_eq(oldv, cmpv);
238
+ if (success) {
239
+ helper_be_stq_mmu(env, addr + 0, int128_gethi(newv), oi1, ra);
240
+ helper_be_stq_mmu(env, addr + 8, int128_getlo(newv), oi1, ra);
241
+ }
242
+#endif
243
+
244
+ return !success;
245
}
246
247
uint64_t HELPER(paired_cmpxchg64_be_parallel)(CPUARMState *env, uint64_t addr,
248
- uint64_t new_lo, uint64_t new_hi)
249
+ uint64_t new_lo, uint64_t new_hi)
250
{
251
- return do_paired_cmpxchg64_be(env, addr, new_lo, new_hi, true, GETPC());
252
+ Int128 oldv, cmpv, newv;
253
+ uintptr_t ra = GETPC();
254
+ bool success;
255
+ int mem_idx;
256
+ TCGMemOpIdx oi;
257
+
258
+ if (!HAVE_CMPXCHG128) {
259
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
260
+ }
261
+
262
+ mem_idx = cpu_mmu_index(env, false);
263
+ oi = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
264
+
265
+ /*
266
+ * High and low need to be switched here because this is not actually a
267
+ * 128bit store but two doublewords stored consecutively
268
+ */
269
+ cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
270
+ newv = int128_make128(new_hi, new_lo);
271
+ oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
272
+
273
+ success = int128_eq(oldv, cmpv);
274
+ return !success;
275
}
276
277
/* Writes back the old data into Rs. */
278
void HELPER(casp_le_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
279
uint64_t new_lo, uint64_t new_hi)
280
{
281
- uintptr_t ra = GETPC();
282
-#ifndef CONFIG_ATOMIC128
283
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
284
-#else
285
Int128 oldv, cmpv, newv;
286
+ uintptr_t ra = GETPC();
287
+ int mem_idx;
288
+ TCGMemOpIdx oi;
289
+
290
+ if (!HAVE_CMPXCHG128) {
291
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
292
+ }
293
+
294
+ mem_idx = cpu_mmu_index(env, false);
295
+ oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
296
297
cmpv = int128_make128(env->xregs[rs], env->xregs[rs + 1]);
298
newv = int128_make128(new_lo, new_hi);
299
-
300
- int mem_idx = cpu_mmu_index(env, false);
301
- TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
302
oldv = helper_atomic_cmpxchgo_le_mmu(env, addr, cmpv, newv, oi, ra);
303
304
env->xregs[rs] = int128_getlo(oldv);
305
env->xregs[rs + 1] = int128_gethi(oldv);
306
-#endif
307
}
308
309
void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
310
uint64_t new_hi, uint64_t new_lo)
311
{
312
- uintptr_t ra = GETPC();
313
-#ifndef CONFIG_ATOMIC128
314
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
315
-#else
316
Int128 oldv, cmpv, newv;
317
+ uintptr_t ra = GETPC();
318
+ int mem_idx;
319
+ TCGMemOpIdx oi;
320
+
321
+ if (!HAVE_CMPXCHG128) {
322
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
323
+ }
324
+
325
+ mem_idx = cpu_mmu_index(env, false);
326
+ oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
327
328
cmpv = int128_make128(env->xregs[rs + 1], env->xregs[rs]);
329
newv = int128_make128(new_lo, new_hi);
330
-
331
- int mem_idx = cpu_mmu_index(env, false);
332
- TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
333
oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
334
335
env->xregs[rs + 1] = int128_getlo(oldv);
336
env->xregs[rs] = int128_gethi(oldv);
337
-#endif
338
}
339
340
/*
341
--
507
--
342
2.17.2
508
2.34.1
343
509
344
510
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
We will want a backend interface for register swapping.
2
2
This is only properly defined for x86; all others get a
3
Currently we rely on atomic operations for cross-CPU invalidations.
3
stub version that always indicates failure.
4
There are two cases that these atomics miss: cross-CPU invalidations
4
5
can race with either (1) vCPU threads flushing their TLB, which
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
happens via memset, or (2) vCPUs calling tlb_reset_dirty on their TLB,
7
which updates .addr_write with a regular store. This results in
8
undefined behaviour, since we're mixing regular and atomic ops
9
on concurrent accesses.
10
11
Fix it by using tlb_lock, a per-vCPU lock. All updaters of tlb_table
12
and the corresponding victim cache now hold the lock.
13
The readers that do not hold tlb_lock must use atomic reads when
14
reading .addr_write, since this field can be updated by other threads;
15
the conversion to atomic reads is done in the next patch.
16
17
Note that an alternative fix would be to expand the use of atomic ops.
18
However, in the case of TLB flushes this would have a huge performance
19
impact, since (1) TLB flushes can happen very frequently and (2) we
20
currently use a full memory barrier to flush each TLB entry, and a TLB
21
has many entries. Instead, acquiring the lock is barely slower than a
22
full memory barrier since it is uncontended, and with a single lock
23
acquisition we can flush the entire TLB.
24
25
Tested-by: Alex Bennée <alex.bennee@linaro.org>
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
27
Signed-off-by: Emilio G. Cota <cota@braap.org>
28
Message-Id: <20181009174557.16125-6-cota@braap.org>
29
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
30
---
7
---
31
include/exec/cpu-defs.h | 3 +
8
tcg/tcg.c | 2 ++
32
accel/tcg/cputlb.c | 155 ++++++++++++++++++++++------------------
9
tcg/aarch64/tcg-target.c.inc | 5 +++++
33
2 files changed, 87 insertions(+), 71 deletions(-)
10
tcg/arm/tcg-target.c.inc | 5 +++++
34
11
tcg/i386/tcg-target.c.inc | 8 ++++++++
35
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
12
tcg/loongarch64/tcg-target.c.inc | 5 +++++
36
index XXXXXXX..XXXXXXX 100644
13
tcg/mips/tcg-target.c.inc | 5 +++++
37
--- a/include/exec/cpu-defs.h
14
tcg/ppc/tcg-target.c.inc | 5 +++++
38
+++ b/include/exec/cpu-defs.h
15
tcg/riscv/tcg-target.c.inc | 5 +++++
39
@@ -XXX,XX +XXX,XX @@
16
tcg/s390x/tcg-target.c.inc | 5 +++++
40
#endif
17
tcg/sparc64/tcg-target.c.inc | 5 +++++
41
18
tcg/tci/tcg-target.c.inc | 5 +++++
42
#include "qemu/host-utils.h"
19
11 files changed, 55 insertions(+)
43
+#include "qemu/thread.h"
20
44
#include "qemu/queue.h"
21
diff --git a/tcg/tcg.c b/tcg/tcg.c
45
#ifdef CONFIG_TCG
22
index XXXXXXX..XXXXXXX 100644
46
#include "tcg-target.h"
23
--- a/tcg/tcg.c
47
@@ -XXX,XX +XXX,XX @@ typedef struct CPUIOTLBEntry {
24
+++ b/tcg/tcg.c
48
25
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
49
#define CPU_COMMON_TLB \
26
static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg);
50
/* The meaning of the MMU modes is defined in the target code. */ \
27
static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg);
51
+ /* tlb_lock serializes updates to tlb_table and tlb_v_table */ \
28
static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long);
52
+ QemuSpin tlb_lock; \
29
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
53
CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \
30
+ __attribute__((unused));
54
CPUTLBEntry tlb_v_table[NB_MMU_MODES][CPU_VTLB_SIZE]; \
31
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg);
55
CPUIOTLBEntry iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; \
32
static void tcg_out_goto_tb(TCGContext *s, int which);
56
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
33
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
57
index XXXXXXX..XXXXXXX 100644
34
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
58
--- a/accel/tcg/cputlb.c
35
index XXXXXXX..XXXXXXX 100644
59
+++ b/accel/tcg/cputlb.c
36
--- a/tcg/aarch64/tcg-target.c.inc
60
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(NB_MMU_MODES > 16);
37
+++ b/tcg/aarch64/tcg-target.c.inc
61
38
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
62
void tlb_init(CPUState *cpu)
39
tcg_out_insn(s, 3305, LDR, 0, rd);
63
{
40
}
64
+ CPUArchState *env = cpu->env_ptr;
41
65
+
42
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
66
+ qemu_spin_init(&env->tlb_lock);
43
+{
67
}
44
+ return false;
68
45
+}
69
/* flush_all_helper: run fn across all cpus
46
+
70
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_nocheck(CPUState *cpu)
47
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
71
atomic_set(&env->tlb_flush_count, env->tlb_flush_count + 1);
48
tcg_target_long imm)
72
tlb_debug("(count: %zu)\n", tlb_flush_count());
49
{
73
50
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
74
+ /*
51
index XXXXXXX..XXXXXXX 100644
75
+ * tlb_table/tlb_v_table updates from any thread must hold tlb_lock.
52
--- a/tcg/arm/tcg-target.c.inc
76
+ * However, updates from the owner thread (as is the case here; see the
53
+++ b/tcg/arm/tcg-target.c.inc
77
+ * above assert_cpu_is_self) do not need atomic_set because all reads
54
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type,
78
+ * that do not hold the lock are performed by the same owner thread.
55
tcg_out_movi32(s, COND_AL, ret, arg);
79
+ */
56
}
80
+ qemu_spin_lock(&env->tlb_lock);
57
81
memset(env->tlb_table, -1, sizeof(env->tlb_table));
58
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
82
memset(env->tlb_v_table, -1, sizeof(env->tlb_v_table));
59
+{
83
+ qemu_spin_unlock(&env->tlb_lock);
60
+ return false;
84
+
61
+}
85
cpu_tb_jmp_cache_clear(cpu);
62
+
86
63
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
87
env->vtlb_index = 0;
64
tcg_target_long imm)
88
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data)
65
{
89
66
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
90
tlb_debug("start: mmu_idx:0x%04lx\n", mmu_idx_bitmask);
67
index XXXXXXX..XXXXXXX 100644
91
68
--- a/tcg/i386/tcg-target.c.inc
92
+ qemu_spin_lock(&env->tlb_lock);
69
+++ b/tcg/i386/tcg-target.c.inc
93
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
70
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
94
71
#define OPC_VPTERNLOGQ (0x25 | P_EXT3A | P_DATA16 | P_VEXW | P_EVEX)
95
if (test_bit(mmu_idx, &mmu_idx_bitmask)) {
72
#define OPC_VZEROUPPER (0x77 | P_EXT)
96
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data)
73
#define OPC_XCHG_ax_r32    (0x90)
97
memset(env->tlb_v_table[mmu_idx], -1, sizeof(env->tlb_v_table[0]));
74
+#define OPC_XCHG_EvGv (0x87)
98
}
75
76
#define OPC_GRP3_Eb (0xf6)
77
#define OPC_GRP3_Ev (0xf7)
78
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type,
99
}
79
}
100
+ qemu_spin_unlock(&env->tlb_lock);
80
}
101
81
102
cpu_tb_jmp_cache_clear(cpu);
82
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
103
83
+{
104
@@ -XXX,XX +XXX,XX @@ static inline bool tlb_hit_page_anyprot(CPUTLBEntry *tlb_entry,
84
+ int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW;
105
tlb_hit_page(tlb_entry->addr_code, page);
85
+ tcg_out_modrm(s, OPC_XCHG_EvGv + rexw, r1, r2);
106
}
86
+ return true;
107
87
+}
108
-static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong page)
88
+
109
+/* Called with tlb_lock held */
89
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
110
+static inline void tlb_flush_entry_locked(CPUTLBEntry *tlb_entry,
90
tcg_target_long imm)
111
+ target_ulong page)
91
{
112
{
92
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
113
if (tlb_hit_page_anyprot(tlb_entry, page)) {
93
index XXXXXXX..XXXXXXX 100644
114
memset(tlb_entry, -1, sizeof(*tlb_entry));
94
--- a/tcg/loongarch64/tcg-target.c.inc
95
+++ b/tcg/loongarch64/tcg-target.c.inc
96
@@ -XXX,XX +XXX,XX @@ static void tcg_out_addi(TCGContext *s, TCGType type, TCGReg rd,
115
}
97
}
116
}
98
}
117
99
118
-static inline void tlb_flush_vtlb_page(CPUArchState *env, int mmu_idx,
100
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
119
- target_ulong page)
101
+{
120
+/* Called with tlb_lock held */
102
+ return false;
121
+static inline void tlb_flush_vtlb_page_locked(CPUArchState *env, int mmu_idx,
103
+}
122
+ target_ulong page)
104
+
123
{
105
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
124
int k;
106
tcg_target_long imm)
125
+
107
{
126
+ assert_cpu_is_self(ENV_GET_CPU(env));
108
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
127
for (k = 0; k < CPU_VTLB_SIZE; k++) {
109
index XXXXXXX..XXXXXXX 100644
128
- tlb_flush_entry(&env->tlb_v_table[mmu_idx][k], page);
110
--- a/tcg/mips/tcg-target.c.inc
129
+ tlb_flush_entry_locked(&env->tlb_v_table[mmu_idx][k], page);
111
+++ b/tcg/mips/tcg-target.c.inc
112
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
113
tcg_out_ext32s(s, rd, rs);
114
}
115
116
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
117
+{
118
+ return false;
119
+}
120
+
121
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
122
tcg_target_long imm)
123
{
124
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
125
index XXXXXXX..XXXXXXX 100644
126
--- a/tcg/ppc/tcg-target.c.inc
127
+++ b/tcg/ppc/tcg-target.c.inc
128
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
130
}
129
}
131
}
130
}
132
131
133
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_async_work(CPUState *cpu, run_on_cpu_data data)
132
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
134
133
+{
135
addr &= TARGET_PAGE_MASK;
134
+ return false;
136
i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
135
+}
137
+ qemu_spin_lock(&env->tlb_lock);
136
+
138
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
137
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
139
- tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
138
tcg_target_long imm)
140
- tlb_flush_vtlb_page(env, mmu_idx, addr);
139
{
141
+ tlb_flush_entry_locked(&env->tlb_table[mmu_idx][i], addr);
140
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
142
+ tlb_flush_vtlb_page_locked(env, mmu_idx, addr);
141
index XXXXXXX..XXXXXXX 100644
143
}
142
--- a/tcg/riscv/tcg-target.c.inc
144
+ qemu_spin_unlock(&env->tlb_lock);
143
+++ b/tcg/riscv/tcg-target.c.inc
145
144
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
146
tb_flush_jmp_cache(cpu, addr);
145
tcg_out_opc_imm(s, OPC_LD, rd, rd, 0);
147
}
146
}
148
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_by_mmuidx_async_work(CPUState *cpu,
147
149
tlb_debug("page:%d addr:"TARGET_FMT_lx" mmu_idx:0x%lx\n",
148
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
150
page, addr, mmu_idx_bitmap);
149
+{
151
150
+ return false;
152
+ qemu_spin_lock(&env->tlb_lock);
151
+}
153
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
152
+
154
if (test_bit(mmu_idx, &mmu_idx_bitmap)) {
153
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
155
- tlb_flush_entry(&env->tlb_table[mmu_idx][page], addr);
154
tcg_target_long imm)
156
- tlb_flush_vtlb_page(env, mmu_idx, addr);
155
{
157
+ tlb_flush_entry_locked(&env->tlb_table[mmu_idx][page], addr);
156
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
158
+ tlb_flush_vtlb_page_locked(env, mmu_idx, addr);
157
index XXXXXXX..XXXXXXX 100644
159
}
158
--- a/tcg/s390x/tcg-target.c.inc
160
}
159
+++ b/tcg/s390x/tcg-target.c.inc
161
+ qemu_spin_unlock(&env->tlb_lock);
160
@@ -XXX,XX +XXX,XX @@ static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
162
161
return false;
163
tb_flush_jmp_cache(cpu, addr);
162
}
164
}
163
165
@@ -XXX,XX +XXX,XX @@ void tlb_unprotect_code(ram_addr_t ram_addr)
164
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
166
* most usual is detecting writes to code regions which may invalidate
165
+{
167
* generated code.
166
+ return false;
168
*
167
+}
169
- * Because we want other vCPUs to respond to changes straight away we
168
+
170
- * update the te->addr_write field atomically. If the TLB entry has
169
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
171
- * been changed by the vCPU in the mean time we skip the update.
170
tcg_target_long imm)
172
+ * Other vCPUs might be reading their TLBs during guest execution, so we update
171
{
173
+ * te->addr_write with atomic_set. We don't need to worry about this for
172
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
174
+ * oversized guests as MTTCG is disabled for them.
173
index XXXXXXX..XXXXXXX 100644
175
*
174
--- a/tcg/sparc64/tcg-target.c.inc
176
- * As this function uses atomic accesses we also need to ensure
175
+++ b/tcg/sparc64/tcg-target.c.inc
177
- * updates to tlb_entries follow the same access rules. We don't need
176
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
178
- * to worry about this for oversized guests as MTTCG is disabled for
177
tcg_out_mov(s, TCG_TYPE_I32, rd, rs);
179
- * them.
178
}
180
+ * Called with tlb_lock held.
179
181
*/
180
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
182
-
181
+{
183
-static void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
182
+ return false;
184
- uintptr_t length)
183
+}
185
+static void tlb_reset_dirty_range_locked(CPUTLBEntry *tlb_entry,
184
+
186
+ uintptr_t start, uintptr_t length)
185
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
187
{
186
tcg_target_long imm)
188
-#if TCG_OVERSIZED_GUEST
187
{
189
uintptr_t addr = tlb_entry->addr_write;
188
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
190
189
index XXXXXXX..XXXXXXX 100644
191
if ((addr & (TLB_INVALID_MASK | TLB_MMIO | TLB_NOTDIRTY)) == 0) {
190
--- a/tcg/tci/tcg-target.c.inc
192
addr &= TARGET_PAGE_MASK;
191
+++ b/tcg/tci/tcg-target.c.inc
193
addr += tlb_entry->addend;
192
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
194
if ((addr - start) < length) {
193
tcg_out_mov(s, TCG_TYPE_I32, rd, rs);
195
+#if TCG_OVERSIZED_GUEST
194
}
196
tlb_entry->addr_write |= TLB_NOTDIRTY;
195
197
- }
196
+static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
198
- }
197
+{
199
#else
198
+ return false;
200
- /* paired with atomic_mb_set in tlb_set_page_with_attrs */
199
+}
201
- uintptr_t orig_addr = atomic_mb_read(&tlb_entry->addr_write);
200
+
202
- uintptr_t addr = orig_addr;
201
static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs,
203
-
202
tcg_target_long imm)
204
- if ((addr & (TLB_INVALID_MASK | TLB_MMIO | TLB_NOTDIRTY)) == 0) {
203
{
205
- addr &= TARGET_PAGE_MASK;
206
- addr += atomic_read(&tlb_entry->addend);
207
- if ((addr - start) < length) {
208
- uintptr_t notdirty_addr = orig_addr | TLB_NOTDIRTY;
209
- atomic_cmpxchg(&tlb_entry->addr_write, orig_addr, notdirty_addr);
210
+ atomic_set(&tlb_entry->addr_write,
211
+ tlb_entry->addr_write | TLB_NOTDIRTY);
212
+#endif
213
}
214
}
215
-#endif
216
}
217
218
-/* For atomic correctness when running MTTCG we need to use the right
219
- * primitives when copying entries */
220
-static inline void copy_tlb_helper(CPUTLBEntry *d, CPUTLBEntry *s,
221
- bool atomic_set)
222
+/*
223
+ * Called with tlb_lock held.
224
+ * Called only from the vCPU context, i.e. the TLB's owner thread.
225
+ */
226
+static inline void copy_tlb_helper_locked(CPUTLBEntry *d, const CPUTLBEntry *s)
227
{
228
-#if TCG_OVERSIZED_GUEST
229
*d = *s;
230
-#else
231
- if (atomic_set) {
232
- d->addr_read = s->addr_read;
233
- d->addr_code = s->addr_code;
234
- atomic_set(&d->addend, atomic_read(&s->addend));
235
- /* Pairs with flag setting in tlb_reset_dirty_range */
236
- atomic_mb_set(&d->addr_write, atomic_read(&s->addr_write));
237
- } else {
238
- d->addr_read = s->addr_read;
239
- d->addr_write = atomic_read(&s->addr_write);
240
- d->addr_code = s->addr_code;
241
- d->addend = atomic_read(&s->addend);
242
- }
243
-#endif
244
}
245
246
/* This is a cross vCPU call (i.e. another vCPU resetting the flags of
247
- * the target vCPU). As such care needs to be taken that we don't
248
- * dangerously race with another vCPU update. The only thing actually
249
- * updated is the target TLB entry ->addr_write flags.
250
+ * the target vCPU).
251
+ * We must take tlb_lock to avoid racing with another vCPU update. The only
252
+ * thing actually updated is the target TLB entry ->addr_write flags.
253
*/
254
void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length)
255
{
256
@@ -XXX,XX +XXX,XX @@ void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length)
257
int mmu_idx;
258
259
env = cpu->env_ptr;
260
+ qemu_spin_lock(&env->tlb_lock);
261
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
262
unsigned int i;
263
264
for (i = 0; i < CPU_TLB_SIZE; i++) {
265
- tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i],
266
- start1, length);
267
+ tlb_reset_dirty_range_locked(&env->tlb_table[mmu_idx][i], start1,
268
+ length);
269
}
270
271
for (i = 0; i < CPU_VTLB_SIZE; i++) {
272
- tlb_reset_dirty_range(&env->tlb_v_table[mmu_idx][i],
273
- start1, length);
274
+ tlb_reset_dirty_range_locked(&env->tlb_v_table[mmu_idx][i], start1,
275
+ length);
276
}
277
}
278
+ qemu_spin_unlock(&env->tlb_lock);
279
}
280
281
-static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr)
282
+/* Called with tlb_lock held */
283
+static inline void tlb_set_dirty1_locked(CPUTLBEntry *tlb_entry,
284
+ target_ulong vaddr)
285
{
286
if (tlb_entry->addr_write == (vaddr | TLB_NOTDIRTY)) {
287
tlb_entry->addr_write = vaddr;
288
@@ -XXX,XX +XXX,XX @@ void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
289
290
vaddr &= TARGET_PAGE_MASK;
291
i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
292
+ qemu_spin_lock(&env->tlb_lock);
293
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
294
- tlb_set_dirty1(&env->tlb_table[mmu_idx][i], vaddr);
295
+ tlb_set_dirty1_locked(&env->tlb_table[mmu_idx][i], vaddr);
296
}
297
298
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
299
int k;
300
for (k = 0; k < CPU_VTLB_SIZE; k++) {
301
- tlb_set_dirty1(&env->tlb_v_table[mmu_idx][k], vaddr);
302
+ tlb_set_dirty1_locked(&env->tlb_v_table[mmu_idx][k], vaddr);
303
}
304
}
305
+ qemu_spin_unlock(&env->tlb_lock);
306
}
307
308
/* Our TLB does not support large pages, so remember the area covered by
309
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
310
addend = (uintptr_t)memory_region_get_ram_ptr(section->mr) + xlat;
311
}
312
313
- /* Make sure there's no cached translation for the new page. */
314
- tlb_flush_vtlb_page(env, mmu_idx, vaddr_page);
315
-
316
code_address = address;
317
iotlb = memory_region_section_get_iotlb(cpu, section, vaddr_page,
318
paddr_page, xlat, prot, &address);
319
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
320
index = (vaddr_page >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
321
te = &env->tlb_table[mmu_idx][index];
322
323
+ /*
324
+ * Hold the TLB lock for the rest of the function. We could acquire/release
325
+ * the lock several times in the function, but it is faster to amortize the
326
+ * acquisition cost by acquiring it just once. Note that this leads to
327
+ * a longer critical section, but this is not a concern since the TLB lock
328
+ * is unlikely to be contended.
329
+ */
330
+ qemu_spin_lock(&env->tlb_lock);
331
+
332
+ /* Make sure there's no cached translation for the new page. */
333
+ tlb_flush_vtlb_page_locked(env, mmu_idx, vaddr_page);
334
+
335
/*
336
* Only evict the old entry to the victim tlb if it's for a
337
* different page; otherwise just overwrite the stale data.
338
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
339
CPUTLBEntry *tv = &env->tlb_v_table[mmu_idx][vidx];
340
341
/* Evict the old entry into the victim tlb. */
342
- copy_tlb_helper(tv, te, true);
343
+ copy_tlb_helper_locked(tv, te);
344
env->iotlb_v[mmu_idx][vidx] = env->iotlb[mmu_idx][index];
345
}
346
347
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
348
}
349
}
350
351
- /* Pairs with flag setting in tlb_reset_dirty_range */
352
- copy_tlb_helper(te, &tn, true);
353
- /* atomic_mb_set(&te->addr_write, write_address); */
354
+ copy_tlb_helper_locked(te, &tn);
355
+ qemu_spin_unlock(&env->tlb_lock);
356
}
357
358
/* Add a new TLB entry, but without specifying the memory
359
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
360
size_t elt_ofs, target_ulong page)
361
{
362
size_t vidx;
363
+
364
+ assert_cpu_is_self(ENV_GET_CPU(env));
365
for (vidx = 0; vidx < CPU_VTLB_SIZE; ++vidx) {
366
CPUTLBEntry *vtlb = &env->tlb_v_table[mmu_idx][vidx];
367
target_ulong cmp = *(target_ulong *)((uintptr_t)vtlb + elt_ofs);
368
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
369
/* Found entry in victim tlb, swap tlb and iotlb. */
370
CPUTLBEntry tmptlb, *tlb = &env->tlb_table[mmu_idx][index];
371
372
- copy_tlb_helper(&tmptlb, tlb, false);
373
- copy_tlb_helper(tlb, vtlb, true);
374
- copy_tlb_helper(vtlb, &tmptlb, true);
375
+ qemu_spin_lock(&env->tlb_lock);
376
+ copy_tlb_helper_locked(&tmptlb, tlb);
377
+ copy_tlb_helper_locked(tlb, vtlb);
378
+ copy_tlb_helper_locked(vtlb, &tmptlb);
379
+ qemu_spin_unlock(&env->tlb_lock);
380
381
CPUIOTLBEntry tmpio, *io = &env->iotlb[mmu_idx][index];
382
CPUIOTLBEntry *vio = &env->iotlb_v[mmu_idx][vidx];
383
--
204
--
384
2.17.2
205
2.34.1
385
206
386
207
diff view generated by jsdifflib
1
Reviewed-by: Emilio G. Cota <cota@braap.org>
1
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
3
---
5
target/arm/helper-a64.c | 16 ++++------------
4
tcg/tcg-ldst.c.inc | 1 +
6
target/arm/translate-a64.c | 38 ++++++++++++++++++++++----------------
5
1 file changed, 1 insertion(+)
7
2 files changed, 26 insertions(+), 28 deletions(-)
8
6
9
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
7
diff --git a/tcg/tcg-ldst.c.inc b/tcg/tcg-ldst.c.inc
10
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
11
--- a/target/arm/helper-a64.c
9
--- a/tcg/tcg-ldst.c.inc
12
+++ b/target/arm/helper-a64.c
10
+++ b/tcg/tcg-ldst.c.inc
13
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_le_parallel)(CPUARMState *env, uint64_t addr,
11
@@ -XXX,XX +XXX,XX @@ static inline TCGLabelQemuLdst *new_ldst_label(TCGContext *s)
14
int mem_idx;
12
{
15
TCGMemOpIdx oi;
13
TCGLabelQemuLdst *l = tcg_malloc(sizeof(*l));
16
14
17
- if (!HAVE_CMPXCHG128) {
15
+ memset(l, 0, sizeof(*l));
18
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
16
QSIMPLEQ_INSERT_TAIL(&s->ldst_labels, l, next);
19
- }
17
20
+ assert(HAVE_CMPXCHG128);
18
return l;
21
22
mem_idx = cpu_mmu_index(env, false);
23
oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
24
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be_parallel)(CPUARMState *env, uint64_t addr,
25
int mem_idx;
26
TCGMemOpIdx oi;
27
28
- if (!HAVE_CMPXCHG128) {
29
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
30
- }
31
+ assert(HAVE_CMPXCHG128);
32
33
mem_idx = cpu_mmu_index(env, false);
34
oi = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
35
@@ -XXX,XX +XXX,XX @@ void HELPER(casp_le_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
36
int mem_idx;
37
TCGMemOpIdx oi;
38
39
- if (!HAVE_CMPXCHG128) {
40
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
41
- }
42
+ assert(HAVE_CMPXCHG128);
43
44
mem_idx = cpu_mmu_index(env, false);
45
oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
46
@@ -XXX,XX +XXX,XX @@ void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
47
int mem_idx;
48
TCGMemOpIdx oi;
49
50
- if (!HAVE_CMPXCHG128) {
51
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
52
- }
53
+ assert(HAVE_CMPXCHG128);
54
55
mem_idx = cpu_mmu_index(env, false);
56
oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
57
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/translate-a64.c
60
+++ b/target/arm/translate-a64.c
61
@@ -XXX,XX +XXX,XX @@
62
63
#include "trace-tcg.h"
64
#include "translate-a64.h"
65
+#include "qemu/atomic128.h"
66
67
static TCGv_i64 cpu_X[32];
68
static TCGv_i64 cpu_pc;
69
@@ -XXX,XX +XXX,XX @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
70
get_mem_index(s),
71
MO_64 | MO_ALIGN | s->be_data);
72
tcg_gen_setcond_i64(TCG_COND_NE, tmp, tmp, cpu_exclusive_val);
73
- } else if (s->be_data == MO_LE) {
74
- if (tb_cflags(s->base.tb) & CF_PARALLEL) {
75
+ } else if (tb_cflags(s->base.tb) & CF_PARALLEL) {
76
+ if (!HAVE_CMPXCHG128) {
77
+ gen_helper_exit_atomic(cpu_env);
78
+ s->base.is_jmp = DISAS_NORETURN;
79
+ } else if (s->be_data == MO_LE) {
80
gen_helper_paired_cmpxchg64_le_parallel(tmp, cpu_env,
81
cpu_exclusive_addr,
82
cpu_reg(s, rt),
83
cpu_reg(s, rt2));
84
} else {
85
- gen_helper_paired_cmpxchg64_le(tmp, cpu_env, cpu_exclusive_addr,
86
- cpu_reg(s, rt), cpu_reg(s, rt2));
87
- }
88
- } else {
89
- if (tb_cflags(s->base.tb) & CF_PARALLEL) {
90
gen_helper_paired_cmpxchg64_be_parallel(tmp, cpu_env,
91
cpu_exclusive_addr,
92
cpu_reg(s, rt),
93
cpu_reg(s, rt2));
94
- } else {
95
- gen_helper_paired_cmpxchg64_be(tmp, cpu_env, cpu_exclusive_addr,
96
- cpu_reg(s, rt), cpu_reg(s, rt2));
97
}
98
+ } else if (s->be_data == MO_LE) {
99
+ gen_helper_paired_cmpxchg64_le(tmp, cpu_env, cpu_exclusive_addr,
100
+ cpu_reg(s, rt), cpu_reg(s, rt2));
101
+ } else {
102
+ gen_helper_paired_cmpxchg64_be(tmp, cpu_env, cpu_exclusive_addr,
103
+ cpu_reg(s, rt), cpu_reg(s, rt2));
104
}
105
} else {
106
tcg_gen_atomic_cmpxchg_i64(tmp, cpu_exclusive_addr, cpu_exclusive_val,
107
@@ -XXX,XX +XXX,XX @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
108
}
109
tcg_temp_free_i64(cmp);
110
} else if (tb_cflags(s->base.tb) & CF_PARALLEL) {
111
- TCGv_i32 tcg_rs = tcg_const_i32(rs);
112
-
113
- if (s->be_data == MO_LE) {
114
- gen_helper_casp_le_parallel(cpu_env, tcg_rs, addr, t1, t2);
115
+ if (HAVE_CMPXCHG128) {
116
+ TCGv_i32 tcg_rs = tcg_const_i32(rs);
117
+ if (s->be_data == MO_LE) {
118
+ gen_helper_casp_le_parallel(cpu_env, tcg_rs, addr, t1, t2);
119
+ } else {
120
+ gen_helper_casp_be_parallel(cpu_env, tcg_rs, addr, t1, t2);
121
+ }
122
+ tcg_temp_free_i32(tcg_rs);
123
} else {
124
- gen_helper_casp_be_parallel(cpu_env, tcg_rs, addr, t1, t2);
125
+ gen_helper_exit_atomic(cpu_env);
126
+ s->base.is_jmp = DISAS_NORETURN;
127
}
128
- tcg_temp_free_i32(tcg_rs);
129
} else {
130
TCGv_i64 d1 = tcg_temp_new_i64();
131
TCGv_i64 d2 = tcg_temp_new_i64();
132
--
19
--
133
2.17.2
20
2.34.1
134
21
135
22
diff view generated by jsdifflib
1
Rather than test NOCHAIN before linking, do not emit the
1
Since TCG_TYPE_I32 values are kept sign-extended in registers, via "w"
2
goto_tb opcode at all. We already do this for goto_ptr.
2
instructions, we don't need to extend if the register matches.
3
This is already relied upon by comparisons.
3
4
5
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
7
---
6
accel/tcg/cpu-exec.c | 2 +-
8
tcg/riscv/tcg-target.c.inc | 4 +++-
7
tcg/tcg-op.c | 9 ++++++++-
9
1 file changed, 3 insertions(+), 1 deletion(-)
8
2 files changed, 9 insertions(+), 2 deletions(-)
9
10
10
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
11
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
11
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
12
--- a/accel/tcg/cpu-exec.c
13
--- a/tcg/riscv/tcg-target.c.inc
13
+++ b/accel/tcg/cpu-exec.c
14
+++ b/tcg/riscv/tcg-target.c.inc
14
@@ -XXX,XX +XXX,XX @@ static inline TranslationBlock *tb_find(CPUState *cpu,
15
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
15
}
16
16
#endif
17
static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)
17
/* See if we can patch the calling TB. */
18
{
18
- if (last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
19
- tcg_out_ext32s(s, ret, arg);
19
+ if (last_tb) {
20
+ if (ret != arg) {
20
tb_add_jump(last_tb, tb_exit, tb);
21
+ tcg_out_ext32s(s, ret, arg);
21
}
22
return tb;
23
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/tcg/tcg-op.c
26
+++ b/tcg/tcg-op.c
27
@@ -XXX,XX +XXX,XX @@ void tcg_gen_exit_tb(TranslationBlock *tb, unsigned idx)
28
seen this numbered exit before, via tcg_gen_goto_tb. */
29
tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx));
30
#endif
31
+ /* When not chaining, exit without indicating a link. */
32
+ if (qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
33
+ val = 0;
34
+ }
35
} else {
36
/* This is an exit via the exitreq label. */
37
tcg_debug_assert(idx == TB_EXIT_REQUESTED);
38
@@ -XXX,XX +XXX,XX @@ void tcg_gen_goto_tb(unsigned idx)
39
tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0);
40
tcg_ctx->goto_tb_issue_mask |= 1 << idx;
41
#endif
42
- tcg_gen_op1i(INDEX_op_goto_tb, idx);
43
+ /* When not chaining, we simply fall through to the "fallback" exit. */
44
+ if (!qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
45
+ tcg_gen_op1i(INDEX_op_goto_tb, idx);
46
+ }
22
+ }
47
}
23
}
48
24
49
void tcg_gen_lookup_and_goto_ptr(void)
25
static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)
50
--
26
--
51
2.17.2
27
2.34.1
52
53
diff view generated by jsdifflib
Deleted patch
1
From: "Emilio G. Cota" <cota@braap.org>
2
1
3
Consistently access u16.high with atomics to avoid
4
undefined behaviour in MTTCG.
5
6
Note that icount_decr.u16.low is only used in icount mode,
7
so regular accesses to it are OK.
8
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Emilio G. Cota <cota@braap.org>
11
Message-Id: <20181010144853.13005-2-cota@braap.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
---
14
accel/tcg/tcg-all.c | 2 +-
15
accel/tcg/translate-all.c | 2 +-
16
qom/cpu.c | 2 +-
17
3 files changed, 3 insertions(+), 3 deletions(-)
18
19
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/accel/tcg/tcg-all.c
22
+++ b/accel/tcg/tcg-all.c
23
@@ -XXX,XX +XXX,XX @@ static void tcg_handle_interrupt(CPUState *cpu, int mask)
24
if (!qemu_cpu_is_self(cpu)) {
25
qemu_cpu_kick(cpu);
26
} else {
27
- cpu->icount_decr.u16.high = -1;
28
+ atomic_set(&cpu->icount_decr.u16.high, -1);
29
if (use_icount &&
30
!cpu->can_do_io
31
&& (mask & ~old_mask) != 0) {
32
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/accel/tcg/translate-all.c
35
+++ b/accel/tcg/translate-all.c
36
@@ -XXX,XX +XXX,XX @@ void cpu_interrupt(CPUState *cpu, int mask)
37
{
38
g_assert(qemu_mutex_iothread_locked());
39
cpu->interrupt_request |= mask;
40
- cpu->icount_decr.u16.high = -1;
41
+ atomic_set(&cpu->icount_decr.u16.high, -1);
42
}
43
44
/*
45
diff --git a/qom/cpu.c b/qom/cpu.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/qom/cpu.c
48
+++ b/qom/cpu.c
49
@@ -XXX,XX +XXX,XX @@ static void cpu_common_reset(CPUState *cpu)
50
cpu->mem_io_pc = 0;
51
cpu->mem_io_vaddr = 0;
52
cpu->icount_extra = 0;
53
- cpu->icount_decr.u32 = 0;
54
+ atomic_set(&cpu->icount_decr.u32, 0);
55
cpu->can_do_io = 1;
56
cpu->exception_index = -1;
57
cpu->crash_occurred = false;
58
--
59
2.17.2
60
61
diff view generated by jsdifflib
Deleted patch
1
From: "Emilio G. Cota" <cota@braap.org>
2
1
3
This plugs two 4-byte holes in 64-bit.
4
5
Signed-off-by: Emilio G. Cota <cota@braap.org>
6
Message-Id: <20181010144853.13005-4-cota@braap.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
tcg/tcg.h | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/tcg/tcg.h b/tcg/tcg.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/tcg.h
15
+++ b/tcg/tcg.h
16
@@ -XXX,XX +XXX,XX @@ typedef struct TCGProfile {
17
int64_t tb_count;
18
int64_t op_count; /* total insn count */
19
int op_count_max; /* max insn per TB */
20
- int64_t temp_count;
21
int temp_count_max;
22
+ int64_t temp_count;
23
int64_t del_op_count;
24
int64_t code_in_len;
25
int64_t code_out_len;
26
--
27
2.17.2
28
29
diff view generated by jsdifflib
Deleted patch
1
From: "Emilio G. Cota" <cota@braap.org>
2
1
3
As far as I can tell tlb_flush does not need to be called
4
this early. tlb_flush is eventually called after the CPU
5
has been realized.
6
7
This change paves the way to the introduction of tlb_init,
8
which will be called from cpu_exec_realizefn.
9
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Emilio G. Cota <cota@braap.org>
13
Message-Id: <20181009174557.16125-2-cota@braap.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
---
16
target/alpha/cpu.c | 1 -
17
1 file changed, 1 deletion(-)
18
19
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/alpha/cpu.c
22
+++ b/target/alpha/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
24
CPUAlphaState *env = &cpu->env;
25
26
cs->env_ptr = env;
27
- tlb_flush(cs);
28
29
env->lock_addr = -1;
30
#if defined(CONFIG_USER_ONLY)
31
--
32
2.17.2
33
34
diff view generated by jsdifflib
Deleted patch
1
From: "Emilio G. Cota" <cota@braap.org>
2
1
3
As far as I can tell tlb_flush does not need to be called
4
this early. tlb_flush is eventually called after the CPU
5
has been realized.
6
7
This change paves the way to the introduction of tlb_init,
8
which will be called from cpu_exec_realizefn.
9
10
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Emilio G. Cota <cota@braap.org>
14
Message-Id: <20181009174557.16125-3-cota@braap.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
---
17
target/unicore32/cpu.c | 2 --
18
1 file changed, 2 deletions(-)
19
20
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/unicore32/cpu.c
23
+++ b/target/unicore32/cpu.c
24
@@ -XXX,XX +XXX,XX @@ static void uc32_cpu_initfn(Object *obj)
25
env->uncached_asr = ASR_MODE_PRIV;
26
env->regs[31] = 0x03000000;
27
#endif
28
-
29
- tlb_flush(cs);
30
}
31
32
static const VMStateDescription vmstate_uc32_cpu = {
33
--
34
2.17.2
35
36
diff view generated by jsdifflib
Deleted patch
1
From: "Emilio G. Cota" <cota@braap.org>
2
1
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Emilio G. Cota <cota@braap.org>
6
Message-Id: <20181009174557.16125-5-cota@braap.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
accel/tcg/cputlb.c | 4 ++--
10
1 file changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/accel/tcg/cputlb.c
15
+++ b/accel/tcg/cputlb.c
16
@@ -XXX,XX +XXX,XX @@
17
} \
18
} while (0)
19
20
-#define assert_cpu_is_self(this_cpu) do { \
21
+#define assert_cpu_is_self(cpu) do { \
22
if (DEBUG_TLB_GATE) { \
23
- g_assert(!cpu->created || qemu_cpu_is_self(cpu)); \
24
+ g_assert(!(cpu)->created || qemu_cpu_is_self(cpu)); \
25
} \
26
} while (0)
27
28
--
29
2.17.2
30
31
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Emilio G. Cota <cota@braap.org>
2
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
target/i386/mem_helper.c | 9 ++++-----
6
1 file changed, 4 insertions(+), 5 deletions(-)
7
1
8
diff --git a/target/i386/mem_helper.c b/target/i386/mem_helper.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/target/i386/mem_helper.c
11
+++ b/target/i386/mem_helper.c
12
@@ -XXX,XX +XXX,XX @@
13
#include "exec/exec-all.h"
14
#include "exec/cpu_ldst.h"
15
#include "qemu/int128.h"
16
+#include "qemu/atomic128.h"
17
#include "tcg.h"
18
19
void helper_cmpxchg8b_unlocked(CPUX86State *env, target_ulong a0)
20
@@ -XXX,XX +XXX,XX @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
21
22
if ((a0 & 0xf) != 0) {
23
raise_exception_ra(env, EXCP0D_GPF, ra);
24
- } else {
25
-#ifndef CONFIG_ATOMIC128
26
- cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
27
-#else
28
+ } else if (HAVE_CMPXCHG128) {
29
int eflags = cpu_cc_compute_all(env, CC_OP);
30
31
Int128 cmpv = int128_make128(env->regs[R_EAX], env->regs[R_EDX]);
32
@@ -XXX,XX +XXX,XX @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
33
eflags &= ~CC_Z;
34
}
35
CC_SRC = eflags;
36
-#endif
37
+ } else {
38
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
39
}
40
}
41
#endif
42
--
43
2.17.2
44
45
diff view generated by jsdifflib