1
The following changes since commit 3ccf6cd0e3e1dfd663814640b3b18b55715d7a75:
1
The following changes since commit d1181d29370a4318a9f11ea92065bea6bb159f83:
2
2
3
Merge remote-tracking branch 'remotes/kraxel/tags/audio-20210617-pull-request' into staging (2021-06-18 09:54:42 +0100)
3
Merge tag 'pull-nbd-2023-07-19' of https://repo.or.cz/qemu/ericb into staging (2023-07-20 09:54:07 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20210619
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20230724
8
8
9
for you to fetch changes up to 8169ec35eb766a12ad0ae898119060fde148ab61:
9
for you to fetch changes up to 32b120394c578bc824f1db4835b3bffbeca88fae:
10
10
11
util/oslib-win32: Fix fatal assertion in qemu_try_memalign (2021-06-19 11:09:11 -0700)
11
accel/tcg: Fix type of 'last' for pageflags_{find,next} (2023-07-24 09:48:49 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
TCI cleanup and re-encoding
14
accel/tcg: Zero-pad vaddr in tlb debug output
15
Fixes for #367 and #390.
15
accel/tcg: Fix type of 'last' for pageflags_{find,next}
16
Move TCGCond to tcg/tcg-cond.h.
16
accel/tcg: Fix sense of read-only probes in ldst_atomicity
17
Fix for win32 qemu_try_memalign.
17
accel/tcg: Take mmap_lock in load_atomic*_or_exit
18
tcg: Add earlyclobber to op_add2 for x86 and s390x
19
tcg/ppc: Fix race in goto_tb implementation
18
20
19
----------------------------------------------------------------
21
----------------------------------------------------------------
20
Alessandro Di Federico (1):
22
Anton Johansson (1):
21
tcg: expose TCGCond manipulation routines
23
accel/tcg: Zero-pad vaddr in tlb_debug output
22
24
23
Richard Henderson (31):
25
Ilya Leoshkevich (1):
24
tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode
26
tcg/{i386, s390x}: Add earlyclobber to the op_add2's first output
25
tcg: Add tcg_call_flags
26
accel/tcg/plugin-gen: Drop inline markers
27
plugins: Drop tcg_flags from struct qemu_plugin_dyn_cb
28
accel/tcg: Add tcg call flags to plugins helpers
29
tcg: Store the TCGHelperInfo in the TCGOp for call
30
tcg: Add tcg_call_func
31
tcg: Build ffi data structures for helpers
32
tcg/tci: Improve tcg_target_call_clobber_regs
33
tcg/tci: Move call-return regs to end of tcg_target_reg_alloc_order
34
tcg/tci: Use ffi for calls
35
tcg/tci: Reserve r13 for a temporary
36
tcg/tci: Emit setcond before brcond
37
tcg/tci: Remove tci_write_reg
38
tcg/tci: Change encoding to uint32_t units
39
tcg/tci: Implement goto_ptr
40
tcg/tci: Implement movcond
41
tcg/tci: Implement andc, orc, eqv, nand, nor
42
tcg/tci: Implement extract, sextract
43
tcg/tci: Implement clz, ctz, ctpop
44
tcg/tci: Implement mulu2, muls2
45
tcg/tci: Implement add2, sub2
46
tcg/tci: Split out tci_qemu_ld, tci_qemu_st
47
Revert "tcg/tci: Use exec/cpu_ldst.h interfaces"
48
tcg/tci: Remove the qemu_ld/st_type macros
49
tcg/tci: Use {set,clear}_helper_retaddr
50
tests/tcg: Increase timeout for TCI
51
accel/tcg: Probe the proper permissions for atomic ops
52
tcg/sparc: Fix temp_allocate_frame vs sparc stack bias
53
tcg: Allocate sufficient storage in temp_allocate_frame
54
tcg: Restart when exhausting the stack frame
55
27
56
Stefan Weil (1):
28
Jordan Niethe (1):
57
util/oslib-win32: Fix fatal assertion in qemu_try_memalign
29
tcg/ppc: Fix race in goto_tb implementation
58
30
59
configure | 3 +
31
Luca Bonissi (1):
60
accel/tcg/atomic_template.h | 24 +-
32
accel/tcg: Fix type of 'last' for pageflags_{find,next}
61
accel/tcg/plugin-helpers.h | 5 +-
62
include/exec/helper-head.h | 37 +-
63
include/exec/helper-tcg.h | 34 +-
64
include/qemu/plugin.h | 1 -
65
include/tcg/tcg-cond.h | 101 ++
66
include/tcg/tcg-opc.h | 4 +-
67
include/tcg/tcg.h | 71 +-
68
target/hppa/helper.h | 3 -
69
target/i386/ops_sse_header.h | 3 -
70
target/m68k/helper.h | 1 -
71
target/ppc/helper.h | 3 -
72
tcg/tcg-internal.h | 22 +
73
tcg/tci/tcg-target-con-set.h | 1 +
74
tcg/tci/tcg-target.h | 68 +-
75
accel/tcg/cputlb.c | 95 +-
76
accel/tcg/plugin-gen.c | 20 +-
77
accel/tcg/user-exec.c | 8 +-
78
plugins/core.c | 30 +-
79
tcg/optimize.c | 3 +-
80
tcg/tcg.c | 300 +++--
81
tcg/tci.c | 1203 ++++++++++----------
82
util/oslib-win32.c | 6 +-
83
tcg/sparc/tcg-target.c.inc | 16 +-
84
tcg/tci/tcg-target.c.inc | 550 ++++-----
85
tcg/meson.build | 8 +-
86
tcg/tci/README | 20 +-
87
tests/docker/dockerfiles/alpine.docker | 1 +
88
tests/docker/dockerfiles/centos8.docker | 1 +
89
tests/docker/dockerfiles/debian10.docker | 1 +
90
tests/docker/dockerfiles/fedora-i386-cross.docker | 1 +
91
tests/docker/dockerfiles/fedora-win32-cross.docker | 1 +
92
tests/docker/dockerfiles/fedora-win64-cross.docker | 1 +
93
tests/docker/dockerfiles/fedora.docker | 1 +
94
tests/docker/dockerfiles/ubuntu.docker | 1 +
95
tests/docker/dockerfiles/ubuntu1804.docker | 1 +
96
tests/docker/dockerfiles/ubuntu2004.docker | 1 +
97
tests/tcg/Makefile.target | 6 +-
98
39 files changed, 1454 insertions(+), 1202 deletions(-)
99
create mode 100644 include/tcg/tcg-cond.h
100
33
34
Richard Henderson (3):
35
include/exec: Add WITH_MMAP_LOCK_GUARD
36
accel/tcg: Fix sense of read-only probes in ldst_atomicity
37
accel/tcg: Take mmap_lock in load_atomic*_or_exit
38
39
include/exec/exec-all.h | 10 ++++++++++
40
tcg/i386/tcg-target-con-set.h | 5 ++++-
41
tcg/s390x/tcg-target-con-set.h | 8 +++++---
42
accel/tcg/cputlb.c | 20 ++++++++++----------
43
accel/tcg/user-exec.c | 4 ++--
44
bsd-user/mmap.c | 1 +
45
linux-user/mmap.c | 1 +
46
tcg/tcg.c | 8 +++++++-
47
accel/tcg/ldst_atomicity.c.inc | 32 ++++++++++++++++++--------------
48
tcg/i386/tcg-target.c.inc | 2 +-
49
tcg/ppc/tcg-target.c.inc | 9 +++++----
50
tcg/s390x/tcg-target.c.inc | 4 ++--
51
12 files changed, 66 insertions(+), 38 deletions(-)
diff view generated by jsdifflib
1
We will shortly be interested in distinguishing pointers
1
From: Jordan Niethe <jniethe5@gmail.com>
2
from integers in the helper's declaration, as well as a
3
true void return. We currently have two parallel 1 bit
4
fields; merge them and expand to a 3 bit field.
5
2
6
Our current maximum is 7 helper arguments, plus the return
3
Commit 20b6643324 ("tcg/ppc: Reorg goto_tb implementation") modified
7
makes 8 * 3 = 24 bits used within the uint32_t typemask.
4
goto_tb to ensure only a single instruction was patched to prevent
5
incorrect behavior if a thread was in the middle of multiple
6
instructions when they were replaced. However this introduced a race
7
between loading the jmp target into TCG_REG_TB and patching and
8
executing the direct branch.
8
9
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
The relevant part of the goto_tb implementation:
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
ld TCG_REG_TB, TARGET_ADDR_LOCATION(TCG_REG_TB)
13
patch_location:
14
mtctr TCG_REG_TB
15
bctr
16
17
tb_target_set_jmp_target() will replace 'patch_location' with a direct
18
branch if the target is in range. The direct branch now relies on
19
TCG_REG_TB being set up correctly by the ld. Prior to this commit
20
multiple instructions were patched in for the direct branch case; these
21
instructions would initialize TCG_REG_TB to the same value as the branch
22
target.
23
24
Imagine the following sequence:
25
26
1) Thread A is executing the goto_tb sequence and loads the jmp
27
target into TCG_REG_TB.
28
29
2) Thread B updates the jmp target address and calls
30
tb_target_set_jmp_target(). This patches a new direct branch into the
31
goto_tb sequence.
32
33
3) Thread A executes the newly patched direct branch. The value in
34
TCG_REG_TB still contains the old jmp target.
35
36
TCG_REG_TB MUST contain the translation block's tc.ptr. Execution will
37
eventually crash after performing memory accesses generated from a
38
faulty value in TCG_REG_TB.
39
40
This presents as segfaults or illegal instruction exceptions.
41
42
Do not revert commit 20b6643324 as it did fix a different race
43
condition. Instead remove the direct branch optimization and always use
44
indirect branches.
45
46
The direct branch optimization can be re-added later with a race free
47
sequence.
48
49
Fixes: 20b6643324 ("tcg/ppc: Reorg goto_tb implementation")
50
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1726
51
Reported-by: Anushree Mathur <anushree.mathur@linux.vnet.ibm.com>
52
Tested-by: Anushree Mathur <anushree.mathur@linux.vnet.ibm.com>
53
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
54
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
55
Co-developed-by: Benjamin Gray <bgray@linux.ibm.com>
56
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
57
Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>
58
Message-Id: <20230717093001.13167-1-jniethe5@gmail.com>
12
---
59
---
13
include/exec/helper-head.h | 37 +++++--------------
60
tcg/ppc/tcg-target.c.inc | 9 +++++----
14
include/exec/helper-tcg.h | 34 ++++++++---------
61
1 file changed, 5 insertions(+), 4 deletions(-)
15
target/hppa/helper.h | 3 --
16
target/i386/ops_sse_header.h | 3 --
17
target/m68k/helper.h | 1 -
18
target/ppc/helper.h | 3 --
19
tcg/tcg.c | 71 +++++++++++++++++++++---------------
20
7 files changed, 67 insertions(+), 85 deletions(-)
21
62
22
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
63
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
23
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
24
--- a/include/exec/helper-head.h
65
--- a/tcg/ppc/tcg-target.c.inc
25
+++ b/include/exec/helper-head.h
66
+++ b/tcg/ppc/tcg-target.c.inc
26
@@ -XXX,XX +XXX,XX @@
67
@@ -XXX,XX +XXX,XX @@ static void tcg_out_goto_tb(TCGContext *s, int which)
27
#define dh_retvar_ptr tcgv_ptr_temp(retval)
68
ptrdiff_t offset = tcg_tbrel_diff(s, (void *)ptr);
28
#define dh_retvar(t) glue(dh_retvar_, dh_alias(t))
69
tcg_out_mem_long(s, LD, LDX, TCG_REG_TB, TCG_REG_TB, offset);
29
70
30
-#define dh_is_64bit_void 0
71
- /* Direct branch will be patched by tb_target_set_jmp_target. */
31
-#define dh_is_64bit_noreturn 0
72
+ /* TODO: Use direct branches when possible. */
32
-#define dh_is_64bit_i32 0
73
set_jmp_insn_offset(s, which);
33
-#define dh_is_64bit_i64 1
74
tcg_out32(s, MTSPR | RS(TCG_REG_TB) | CTR);
34
-#define dh_is_64bit_ptr (sizeof(void *) == 8)
75
35
-#define dh_is_64bit_cptr dh_is_64bit_ptr
76
- /* When branch is out of range, fall through to indirect. */
36
-#define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))
77
tcg_out32(s, BCCTR | BO_ALWAYS);
37
-
78
38
-#define dh_is_signed_void 0
79
/* For the unlinked case, need to reset TCG_REG_TB. */
39
-#define dh_is_signed_noreturn 0
80
@@ -XXX,XX +XXX,XX @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
40
-#define dh_is_signed_i32 0
81
intptr_t diff = addr - jmp_rx;
41
-#define dh_is_signed_s32 1
82
tcg_insn_unit insn;
42
-#define dh_is_signed_i64 0
83
43
-#define dh_is_signed_s64 1
84
+ if (USE_REG_TB) {
44
-#define dh_is_signed_f16 0
85
+ return;
45
-#define dh_is_signed_f32 0
86
+ }
46
-#define dh_is_signed_f64 0
47
-#define dh_is_signed_tl 0
48
-#define dh_is_signed_int 1
49
-/* ??? This is highly specific to the host cpu. There are even special
50
- extension instructions that may be required, e.g. ia64's addp4. But
51
- for now we don't support any 64-bit targets with 32-bit pointers. */
52
-#define dh_is_signed_ptr 0
53
-#define dh_is_signed_cptr dh_is_signed_ptr
54
-#define dh_is_signed_env dh_is_signed_ptr
55
-#define dh_is_signed(t) dh_is_signed_##t
56
+#define dh_typecode_void 0
57
+#define dh_typecode_noreturn 0
58
+#define dh_typecode_i32 2
59
+#define dh_typecode_s32 3
60
+#define dh_typecode_i64 4
61
+#define dh_typecode_s64 5
62
+#define dh_typecode_ptr 6
63
+#define dh_typecode(t) glue(dh_typecode_, dh_alias(t))
64
65
#define dh_callflag_i32 0
66
#define dh_callflag_s32 0
67
@@ -XXX,XX +XXX,XX @@
68
#define dh_callflag_noreturn TCG_CALL_NO_RETURN
69
#define dh_callflag(t) glue(dh_callflag_, dh_alias(t))
70
71
-#define dh_sizemask(t, n) \
72
- ((dh_is_64bit(t) << (n*2)) | (dh_is_signed(t) << (n*2+1)))
73
+#define dh_typemask(t, n) (dh_typecode(t) << (n * 3))
74
75
#define dh_arg(t, n) \
76
glue(glue(tcgv_, dh_alias(t)), _temp)(glue(arg, n))
77
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
78
index XXXXXXX..XXXXXXX 100644
79
--- a/include/exec/helper-tcg.h
80
+++ b/include/exec/helper-tcg.h
81
@@ -XXX,XX +XXX,XX @@
82
#define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
83
{ .func = HELPER(NAME), .name = str(NAME), \
84
.flags = FLAGS | dh_callflag(ret), \
85
- .sizemask = dh_sizemask(ret, 0) },
86
+ .typemask = dh_typemask(ret, 0) },
87
88
#define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \
89
{ .func = HELPER(NAME), .name = str(NAME), \
90
.flags = FLAGS | dh_callflag(ret), \
91
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) },
92
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) },
93
94
#define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \
95
{ .func = HELPER(NAME), .name = str(NAME), \
96
.flags = FLAGS | dh_callflag(ret), \
97
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
98
- | dh_sizemask(t2, 2) },
99
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
100
+ | dh_typemask(t2, 2) },
101
102
#define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \
103
{ .func = HELPER(NAME), .name = str(NAME), \
104
.flags = FLAGS | dh_callflag(ret), \
105
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
106
- | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) },
107
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
108
+ | dh_typemask(t2, 2) | dh_typemask(t3, 3) },
109
110
#define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \
111
{ .func = HELPER(NAME), .name = str(NAME), \
112
.flags = FLAGS | dh_callflag(ret), \
113
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
114
- | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) },
115
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
116
+ | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) },
117
118
#define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \
119
{ .func = HELPER(NAME), .name = str(NAME), \
120
.flags = FLAGS | dh_callflag(ret), \
121
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
122
- | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
123
- | dh_sizemask(t5, 5) },
124
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
125
+ | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
126
+ | dh_typemask(t5, 5) },
127
128
#define DEF_HELPER_FLAGS_6(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6) \
129
{ .func = HELPER(NAME), .name = str(NAME), \
130
.flags = FLAGS | dh_callflag(ret), \
131
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
132
- | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
133
- | dh_sizemask(t5, 5) | dh_sizemask(t6, 6) },
134
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
135
+ | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
136
+ | dh_typemask(t5, 5) | dh_typemask(t6, 6) },
137
138
#define DEF_HELPER_FLAGS_7(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6, t7) \
139
{ .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
140
- .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
141
- | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
142
- | dh_sizemask(t5, 5) | dh_sizemask(t6, 6) | dh_sizemask(t7, 7) },
143
+ .typemask = dh_typemask(ret, 0) | dh_typemask(t1, 1) \
144
+ | dh_typemask(t2, 2) | dh_typemask(t3, 3) | dh_typemask(t4, 4) \
145
+ | dh_typemask(t5, 5) | dh_typemask(t6, 6) | dh_typemask(t7, 7) },
146
147
#include "helper.h"
148
#include "trace/generated-helpers.h"
149
diff --git a/target/hppa/helper.h b/target/hppa/helper.h
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/hppa/helper.h
152
+++ b/target/hppa/helper.h
153
@@ -XXX,XX +XXX,XX @@
154
#if TARGET_REGISTER_BITS == 64
155
# define dh_alias_tr i64
156
-# define dh_is_64bit_tr 1
157
#else
158
# define dh_alias_tr i32
159
-# define dh_is_64bit_tr 0
160
#endif
161
#define dh_ctype_tr target_ureg
162
-#define dh_is_signed_tr 0
163
164
DEF_HELPER_2(excp, noreturn, env, int)
165
DEF_HELPER_FLAGS_2(tsv, TCG_CALL_NO_WG, void, env, tr)
166
diff --git a/target/i386/ops_sse_header.h b/target/i386/ops_sse_header.h
167
index XXXXXXX..XXXXXXX 100644
168
--- a/target/i386/ops_sse_header.h
169
+++ b/target/i386/ops_sse_header.h
170
@@ -XXX,XX +XXX,XX @@
171
#define dh_ctype_Reg Reg *
172
#define dh_ctype_ZMMReg ZMMReg *
173
#define dh_ctype_MMXReg MMXReg *
174
-#define dh_is_signed_Reg dh_is_signed_ptr
175
-#define dh_is_signed_ZMMReg dh_is_signed_ptr
176
-#define dh_is_signed_MMXReg dh_is_signed_ptr
177
178
DEF_HELPER_3(glue(psrlw, SUFFIX), void, env, Reg, Reg)
179
DEF_HELPER_3(glue(psraw, SUFFIX), void, env, Reg, Reg)
180
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
181
index XXXXXXX..XXXXXXX 100644
182
--- a/target/m68k/helper.h
183
+++ b/target/m68k/helper.h
184
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(cas2l_parallel, void, env, i32, i32, i32)
185
186
#define dh_alias_fp ptr
187
#define dh_ctype_fp FPReg *
188
-#define dh_is_signed_fp dh_is_signed_ptr
189
190
DEF_HELPER_3(exts32, void, env, fp, s32)
191
DEF_HELPER_3(extf32, void, env, fp, f32)
192
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
193
index XXXXXXX..XXXXXXX 100644
194
--- a/target/ppc/helper.h
195
+++ b/target/ppc/helper.h
196
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64)
197
198
#define dh_alias_avr ptr
199
#define dh_ctype_avr ppc_avr_t *
200
-#define dh_is_signed_avr dh_is_signed_ptr
201
202
#define dh_alias_vsr ptr
203
#define dh_ctype_vsr ppc_vsr_t *
204
-#define dh_is_signed_vsr dh_is_signed_ptr
205
206
DEF_HELPER_3(vavgub, void, avr, avr, avr)
207
DEF_HELPER_3(vavguh, void, avr, avr, avr)
208
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl)
209
210
#define dh_alias_fprp ptr
211
#define dh_ctype_fprp ppc_fprp_t *
212
-#define dh_is_signed_fprp dh_is_signed_ptr
213
214
DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
215
DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp)
216
diff --git a/tcg/tcg.c b/tcg/tcg.c
217
index XXXXXXX..XXXXXXX 100644
218
--- a/tcg/tcg.c
219
+++ b/tcg/tcg.c
220
@@ -XXX,XX +XXX,XX @@ typedef struct TCGHelperInfo {
221
void *func;
222
const char *name;
223
unsigned flags;
224
- unsigned sizemask;
225
+ unsigned typemask;
226
} TCGHelperInfo;
227
228
#include "exec/helper-proto.h"
229
@@ -XXX,XX +XXX,XX @@ bool tcg_op_supported(TCGOpcode op)
230
void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
231
{
232
int i, real_args, nb_rets, pi;
233
- unsigned sizemask, flags;
234
+ unsigned typemask, flags;
235
TCGHelperInfo *info;
236
TCGOp *op;
237
238
info = g_hash_table_lookup(helper_table, (gpointer)func);
239
flags = info->flags;
240
- sizemask = info->sizemask;
241
+ typemask = info->typemask;
242
243
#ifdef CONFIG_PLUGIN
244
/* detect non-plugin helpers */
245
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
246
&& !defined(CONFIG_TCG_INTERPRETER)
247
/* We have 64-bit values in one register, but need to pass as two
248
separate parameters. Split them. */
249
- int orig_sizemask = sizemask;
250
+ int orig_typemask = typemask;
251
int orig_nargs = nargs;
252
TCGv_i64 retl, reth;
253
TCGTemp *split_args[MAX_OPC_PARAM];
254
255
retl = NULL;
256
reth = NULL;
257
- if (sizemask != 0) {
258
- for (i = real_args = 0; i < nargs; ++i) {
259
- int is_64bit = sizemask & (1 << (i+1)*2);
260
- if (is_64bit) {
261
- TCGv_i64 orig = temp_tcgv_i64(args[i]);
262
- TCGv_i32 h = tcg_temp_new_i32();
263
- TCGv_i32 l = tcg_temp_new_i32();
264
- tcg_gen_extr_i64_i32(l, h, orig);
265
- split_args[real_args++] = tcgv_i32_temp(h);
266
- split_args[real_args++] = tcgv_i32_temp(l);
267
- } else {
268
- split_args[real_args++] = args[i];
269
- }
270
+ typemask = 0;
271
+ for (i = real_args = 0; i < nargs; ++i) {
272
+ int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
273
+ bool is_64bit = (argtype & ~1) == dh_typecode_i64;
274
+
87
+
275
+ if (is_64bit) {
88
if (in_range_b(diff)) {
276
+ TCGv_i64 orig = temp_tcgv_i64(args[i]);
89
insn = B | (diff & 0x3fffffc);
277
+ TCGv_i32 h = tcg_temp_new_i32();
90
- } else if (USE_REG_TB) {
278
+ TCGv_i32 l = tcg_temp_new_i32();
91
- insn = MTSPR | RS(TCG_REG_TB) | CTR;
279
+ tcg_gen_extr_i64_i32(l, h, orig);
92
} else {
280
+ split_args[real_args++] = tcgv_i32_temp(h);
93
insn = NOP;
281
+ typemask |= dh_typecode_i32 << (real_args * 3);
282
+ split_args[real_args++] = tcgv_i32_temp(l);
283
+ typemask |= dh_typecode_i32 << (real_args * 3);
284
+ } else {
285
+ split_args[real_args++] = args[i];
286
+ typemask |= argtype << (real_args * 3);
287
}
288
- nargs = real_args;
289
- args = split_args;
290
- sizemask = 0;
291
}
292
+ nargs = real_args;
293
+ args = split_args;
294
#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
295
for (i = 0; i < nargs; ++i) {
296
- int is_64bit = sizemask & (1 << (i+1)*2);
297
- int is_signed = sizemask & (2 << (i+1)*2);
298
- if (!is_64bit) {
299
+ int argtype = extract32(typemask, (i + 1) * 3, 3);
300
+ bool is_32bit = (argtype & ~1) == dh_typecode_i32;
301
+ bool is_signed = argtype & 1;
302
+
303
+ if (is_32bit) {
304
TCGv_i64 temp = tcg_temp_new_i64();
305
TCGv_i64 orig = temp_tcgv_i64(args[i]);
306
if (is_signed) {
307
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
308
if (ret != NULL) {
309
#if defined(__sparc__) && !defined(__arch64__) \
310
&& !defined(CONFIG_TCG_INTERPRETER)
311
- if (orig_sizemask & 1) {
312
+ if ((typemask & 6) == dh_typecode_i64) {
313
/* The 32-bit ABI is going to return the 64-bit value in
314
the %o0/%o1 register pair. Prepare for this by using
315
two return temporaries, and reassemble below. */
316
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
317
nb_rets = 1;
318
}
319
#else
320
- if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) {
321
+ if (TCG_TARGET_REG_BITS < 64 && (typemask & 6) == dh_typecode_i64) {
322
#ifdef HOST_WORDS_BIGENDIAN
323
op->args[pi++] = temp_arg(ret + 1);
324
op->args[pi++] = temp_arg(ret);
325
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
326
327
real_args = 0;
328
for (i = 0; i < nargs; i++) {
329
- int is_64bit = sizemask & (1 << (i+1)*2);
330
+ int argtype = extract32(typemask, (i + 1) * 3, 3);
331
+ bool is_64bit = (argtype & ~1) == dh_typecode_i64;
332
+
333
if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
334
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
335
/* some targets want aligned 64 bit args */
336
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
337
&& !defined(CONFIG_TCG_INTERPRETER)
338
/* Free all of the parts we allocated above. */
339
for (i = real_args = 0; i < orig_nargs; ++i) {
340
- int is_64bit = orig_sizemask & (1 << (i+1)*2);
341
+ int argtype = extract32(orig_typemask, (i + 1) * 3, 3);
342
+ bool is_64bit = (argtype & ~1) == dh_typecode_i64;
343
+
344
if (is_64bit) {
345
tcg_temp_free_internal(args[real_args++]);
346
tcg_temp_free_internal(args[real_args++]);
347
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
348
real_args++;
349
}
350
}
351
- if (orig_sizemask & 1) {
352
+ if ((orig_typemask & 6) == dh_typecode_i64) {
353
/* The 32-bit ABI returned two 32-bit pieces. Re-assemble them.
354
Note that describing these as TCGv_i64 eliminates an unnecessary
355
zero-extension that tcg_gen_concat_i32_i64 would create. */
356
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
357
}
358
#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
359
for (i = 0; i < nargs; ++i) {
360
- int is_64bit = sizemask & (1 << (i+1)*2);
361
- if (!is_64bit) {
362
+ int argtype = extract32(typemask, (i + 1) * 3, 3);
363
+ bool is_32bit = (argtype & ~1) == dh_typecode_i32;
364
+
365
+ if (is_32bit) {
366
tcg_temp_free_internal(args[i]);
367
}
368
}
94
}
369
--
95
--
370
2.25.1
96
2.34.1
371
372
diff view generated by jsdifflib
Deleted patch
1
We're going to change how to look up the call flags from a TCGop,
2
so extract it as a helper.
3
1
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
tcg/tcg-internal.h | 5 +++++
9
tcg/optimize.c | 3 ++-
10
tcg/tcg.c | 14 ++++++--------
11
3 files changed, 13 insertions(+), 9 deletions(-)
12
13
diff --git a/tcg/tcg-internal.h b/tcg/tcg-internal.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tcg/tcg-internal.h
16
+++ b/tcg/tcg-internal.h
17
@@ -XXX,XX +XXX,XX @@ bool tcg_region_alloc(TCGContext *s);
18
void tcg_region_initial_alloc(TCGContext *s);
19
void tcg_region_prologue_set(TCGContext *s);
20
21
+static inline unsigned tcg_call_flags(TCGOp *op)
22
+{
23
+ return op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
24
+}
25
+
26
#endif /* TCG_INTERNAL_H */
27
diff --git a/tcg/optimize.c b/tcg/optimize.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/tcg/optimize.c
30
+++ b/tcg/optimize.c
31
@@ -XXX,XX +XXX,XX @@
32
33
#include "qemu/osdep.h"
34
#include "tcg/tcg-op.h"
35
+#include "tcg-internal.h"
36
37
#define CASE_OP_32_64(x) \
38
glue(glue(case INDEX_op_, x), _i32): \
39
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
40
break;
41
42
case INDEX_op_call:
43
- if (!(op->args[nb_oargs + nb_iargs + 1]
44
+ if (!(tcg_call_flags(op)
45
& (TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_WRITE_GLOBALS))) {
46
for (i = 0; i < nb_globals; i++) {
47
if (test_bit(i, temps_used.l)) {
48
diff --git a/tcg/tcg.c b/tcg/tcg.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/tcg/tcg.c
51
+++ b/tcg/tcg.c
52
@@ -XXX,XX +XXX,XX @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
53
nb_cargs = def->nb_cargs;
54
55
/* function name, flags, out args */
56
- col += qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
57
+ col += qemu_log(" %s %s,$0x%x,$%d", def->name,
58
tcg_find_helper(s, op->args[nb_oargs + nb_iargs]),
59
- op->args[nb_oargs + nb_iargs + 1], nb_oargs);
60
+ tcg_call_flags(op), nb_oargs);
61
for (i = 0; i < nb_oargs; i++) {
62
col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf),
63
op->args[i]));
64
@@ -XXX,XX +XXX,XX @@ static void reachable_code_pass(TCGContext *s)
65
QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) {
66
bool remove = dead;
67
TCGLabel *label;
68
- int call_flags;
69
70
switch (op->opc) {
71
case INDEX_op_set_label:
72
@@ -XXX,XX +XXX,XX @@ static void reachable_code_pass(TCGContext *s)
73
74
case INDEX_op_call:
75
/* Notice noreturn helper calls, raising exceptions. */
76
- call_flags = op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
77
- if (call_flags & TCG_CALL_NO_RETURN) {
78
+ if (tcg_call_flags(op) & TCG_CALL_NO_RETURN) {
79
dead = true;
80
}
81
break;
82
@@ -XXX,XX +XXX,XX @@ static void liveness_pass_1(TCGContext *s)
83
84
nb_oargs = TCGOP_CALLO(op);
85
nb_iargs = TCGOP_CALLI(op);
86
- call_flags = op->args[nb_oargs + nb_iargs + 1];
87
+ call_flags = tcg_call_flags(op);
88
89
/* pure functions can be removed if their result is unused */
90
if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) {
91
@@ -XXX,XX +XXX,XX @@ static bool liveness_pass_2(TCGContext *s)
92
if (opc == INDEX_op_call) {
93
nb_oargs = TCGOP_CALLO(op);
94
nb_iargs = TCGOP_CALLI(op);
95
- call_flags = op->args[nb_oargs + nb_iargs + 1];
96
+ call_flags = tcg_call_flags(op);
97
} else {
98
nb_iargs = def->nb_iargs;
99
nb_oargs = def->nb_oargs;
100
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
101
TCGRegSet allocated_regs;
102
103
func_addr = (tcg_insn_unit *)(intptr_t)op->args[nb_oargs + nb_iargs];
104
- flags = op->args[nb_oargs + nb_iargs + 1];
105
+ flags = tcg_call_flags(op);
106
107
nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
108
if (nb_regs > nb_iargs) {
109
--
110
2.25.1
111
112
diff view generated by jsdifflib
Deleted patch
1
Let the compiler decide on inlining.
2
1
3
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
accel/tcg/plugin-gen.c | 12 +++++-------
8
1 file changed, 5 insertions(+), 7 deletions(-)
9
10
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/accel/tcg/plugin-gen.c
13
+++ b/accel/tcg/plugin-gen.c
14
@@ -XXX,XX +XXX,XX @@ static void gen_empty_mem_helper(void)
15
tcg_temp_free_ptr(ptr);
16
}
17
18
-static inline
19
-void gen_plugin_cb_start(enum plugin_gen_from from,
20
- enum plugin_gen_cb type, unsigned wr)
21
+static void gen_plugin_cb_start(enum plugin_gen_from from,
22
+ enum plugin_gen_cb type, unsigned wr)
23
{
24
TCGOp *op;
25
26
@@ -XXX,XX +XXX,XX @@ static void gen_wrapped(enum plugin_gen_from from,
27
tcg_gen_plugin_cb_end();
28
}
29
30
-static inline void plugin_gen_empty_callback(enum plugin_gen_from from)
31
+static void plugin_gen_empty_callback(enum plugin_gen_from from)
32
{
33
switch (from) {
34
case PLUGIN_GEN_AFTER_INSN:
35
@@ -XXX,XX +XXX,XX @@ static bool op_rw(const TCGOp *op, const struct qemu_plugin_dyn_cb *cb)
36
return !!(cb->rw & (w + 1));
37
}
38
39
-static inline
40
-void inject_cb_type(const GArray *cbs, TCGOp *begin_op, inject_fn inject,
41
- op_ok_fn ok)
42
+static void inject_cb_type(const GArray *cbs, TCGOp *begin_op,
43
+ inject_fn inject, op_ok_fn ok)
44
{
45
TCGOp *end_op;
46
TCGOp *op;
47
--
48
2.25.1
49
50
diff view generated by jsdifflib
Deleted patch
1
As noted by qemu-plugins.h, enum qemu_plugin_cb_flags is
2
currently unused -- plugins can neither read nor write
3
guest registers.
4
1
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
accel/tcg/plugin-helpers.h | 1 -
9
include/qemu/plugin.h | 1 -
10
accel/tcg/plugin-gen.c | 8 ++++----
11
plugins/core.c | 30 ++++++------------------------
12
4 files changed, 10 insertions(+), 30 deletions(-)
13
14
diff --git a/accel/tcg/plugin-helpers.h b/accel/tcg/plugin-helpers.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/accel/tcg/plugin-helpers.h
17
+++ b/accel/tcg/plugin-helpers.h
18
@@ -XXX,XX +XXX,XX @@
19
#ifdef CONFIG_PLUGIN
20
-/* Note: no TCG flags because those are overwritten later */
21
DEF_HELPER_2(plugin_vcpu_udata_cb, void, i32, ptr)
22
DEF_HELPER_4(plugin_vcpu_mem_cb, void, i32, i32, i64, ptr)
23
#endif
24
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/qemu/plugin.h
27
+++ b/include/qemu/plugin.h
28
@@ -XXX,XX +XXX,XX @@ enum plugin_dyn_cb_subtype {
29
struct qemu_plugin_dyn_cb {
30
union qemu_plugin_cb_sig f;
31
void *userp;
32
- unsigned tcg_flags;
33
enum plugin_dyn_cb_subtype type;
34
/* @rw applies to mem callbacks only (both regular and inline) */
35
enum qemu_plugin_mem_rw rw;
36
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/accel/tcg/plugin-gen.c
39
+++ b/accel/tcg/plugin-gen.c
40
@@ -XXX,XX +XXX,XX @@ static TCGOp *copy_st_ptr(TCGOp **begin_op, TCGOp *op)
41
}
42
43
static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *empty_func,
44
- void *func, unsigned tcg_flags, int *cb_idx)
45
+ void *func, int *cb_idx)
46
{
47
/* copy all ops until the call */
48
do {
49
@@ -XXX,XX +XXX,XX @@ static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *empty_func,
50
tcg_debug_assert(i < MAX_OPC_PARAM_ARGS);
51
}
52
op->args[*cb_idx] = (uintptr_t)func;
53
- op->args[*cb_idx + 1] = tcg_flags;
54
+ op->args[*cb_idx + 1] = (*begin_op)->args[*cb_idx + 1];
55
56
return op;
57
}
58
@@ -XXX,XX +XXX,XX @@ static TCGOp *append_udata_cb(const struct qemu_plugin_dyn_cb *cb,
59
60
/* call */
61
op = copy_call(&begin_op, op, HELPER(plugin_vcpu_udata_cb),
62
- cb->f.vcpu_udata, cb->tcg_flags, cb_idx);
63
+ cb->f.vcpu_udata, cb_idx);
64
65
return op;
66
}
67
@@ -XXX,XX +XXX,XX @@ static TCGOp *append_mem_cb(const struct qemu_plugin_dyn_cb *cb,
68
if (type == PLUGIN_GEN_CB_MEM) {
69
/* call */
70
op = copy_call(&begin_op, op, HELPER(plugin_vcpu_mem_cb),
71
- cb->f.vcpu_udata, cb->tcg_flags, cb_idx);
72
+ cb->f.vcpu_udata, cb_idx);
73
}
74
75
return op;
76
diff --git a/plugins/core.c b/plugins/core.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/plugins/core.c
79
+++ b/plugins/core.c
80
@@ -XXX,XX +XXX,XX @@ void plugin_register_inline_op(GArray **arr,
81
dyn_cb->inline_insn.imm = imm;
82
}
83
84
-static inline uint32_t cb_to_tcg_flags(enum qemu_plugin_cb_flags flags)
85
-{
86
- uint32_t ret;
87
-
88
- switch (flags) {
89
- case QEMU_PLUGIN_CB_RW_REGS:
90
- ret = 0;
91
- break;
92
- case QEMU_PLUGIN_CB_R_REGS:
93
- ret = TCG_CALL_NO_WG;
94
- break;
95
- case QEMU_PLUGIN_CB_NO_REGS:
96
- default:
97
- ret = TCG_CALL_NO_RWG;
98
- }
99
- return ret;
100
-}
101
-
102
-inline void
103
-plugin_register_dyn_cb__udata(GArray **arr,
104
- qemu_plugin_vcpu_udata_cb_t cb,
105
- enum qemu_plugin_cb_flags flags, void *udata)
106
+void plugin_register_dyn_cb__udata(GArray **arr,
107
+ qemu_plugin_vcpu_udata_cb_t cb,
108
+ enum qemu_plugin_cb_flags flags,
109
+ void *udata)
110
{
111
struct qemu_plugin_dyn_cb *dyn_cb = plugin_get_dyn_cb(arr);
112
113
dyn_cb->userp = udata;
114
- dyn_cb->tcg_flags = cb_to_tcg_flags(flags);
115
+ /* Note flags are discarded as unused. */
116
dyn_cb->f.vcpu_udata = cb;
117
dyn_cb->type = PLUGIN_CB_REGULAR;
118
}
119
@@ -XXX,XX +XXX,XX @@ void plugin_register_vcpu_mem_cb(GArray **arr,
120
121
dyn_cb = plugin_get_dyn_cb(arr);
122
dyn_cb->userp = udata;
123
- dyn_cb->tcg_flags = cb_to_tcg_flags(flags);
124
+ /* Note flags are discarded as unused. */
125
dyn_cb->type = PLUGIN_CB_REGULAR;
126
dyn_cb->rw = rw;
127
dyn_cb->f.generic = cb;
128
--
129
2.25.1
130
131
diff view generated by jsdifflib
1
From: Alessandro Di Federico <ale@rev.ng>
1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2
3
This commit moves into a separate file routines used to manipulate
4
TCGCond. These will be employed by the idef-parser.
5
6
Signed-off-by: Alessandro Di Federico <ale@rev.ng>
7
Signed-off-by: Paolo Montesel <babush@rev.ng>
8
Message-Id: <20210619093713.1845446-2-ale.qemu@rev.ng>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
3
---
11
include/tcg/tcg-cond.h | 101 +++++++++++++++++++++++++++++++++++++++++
4
include/exec/exec-all.h | 10 ++++++++++
12
include/tcg/tcg.h | 70 +---------------------------
5
bsd-user/mmap.c | 1 +
13
2 files changed, 102 insertions(+), 69 deletions(-)
6
linux-user/mmap.c | 1 +
14
create mode 100644 include/tcg/tcg-cond.h
7
3 files changed, 12 insertions(+)
15
8
16
diff --git a/include/tcg/tcg-cond.h b/include/tcg/tcg-cond.h
9
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
17
new file mode 100644
10
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX
11
--- a/include/exec/exec-all.h
19
--- /dev/null
12
+++ b/include/exec/exec-all.h
20
+++ b/include/tcg/tcg-cond.h
13
@@ -XXX,XX +XXX,XX @@ void TSA_NO_TSA mmap_lock(void);
21
@@ -XXX,XX +XXX,XX @@
14
void TSA_NO_TSA mmap_unlock(void);
22
+/*
15
bool have_mmap_lock(void);
23
+ * Tiny Code Generator for QEMU
16
24
+ *
17
+static inline void mmap_unlock_guard(void *unused)
25
+ * Copyright (c) 2008 Fabrice Bellard
26
+ *
27
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
28
+ * of this software and associated documentation files (the "Software"), to deal
29
+ * in the Software without restriction, including without limitation the rights
30
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
31
+ * copies of the Software, and to permit persons to whom the Software is
32
+ * furnished to do so, subject to the following conditions:
33
+ *
34
+ * The above copyright notice and this permission notice shall be included in
35
+ * all copies or substantial portions of the Software.
36
+ *
37
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
40
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
43
+ * THE SOFTWARE.
44
+ */
45
+
46
+#ifndef TCG_COND_H
47
+#define TCG_COND_H
48
+
49
+/*
50
+ * Conditions. Note that these are laid out for easy manipulation by
51
+ * the functions below:
52
+ * bit 0 is used for inverting;
53
+ * bit 1 is signed,
54
+ * bit 2 is unsigned,
55
+ * bit 3 is used with bit 0 for swapping signed/unsigned.
56
+ */
57
+typedef enum {
58
+ /* non-signed */
59
+ TCG_COND_NEVER = 0 | 0 | 0 | 0,
60
+ TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
61
+ TCG_COND_EQ = 8 | 0 | 0 | 0,
62
+ TCG_COND_NE = 8 | 0 | 0 | 1,
63
+ /* signed */
64
+ TCG_COND_LT = 0 | 0 | 2 | 0,
65
+ TCG_COND_GE = 0 | 0 | 2 | 1,
66
+ TCG_COND_LE = 8 | 0 | 2 | 0,
67
+ TCG_COND_GT = 8 | 0 | 2 | 1,
68
+ /* unsigned */
69
+ TCG_COND_LTU = 0 | 4 | 0 | 0,
70
+ TCG_COND_GEU = 0 | 4 | 0 | 1,
71
+ TCG_COND_LEU = 8 | 4 | 0 | 0,
72
+ TCG_COND_GTU = 8 | 4 | 0 | 1,
73
+} TCGCond;
74
+
75
+/* Invert the sense of the comparison. */
76
+static inline TCGCond tcg_invert_cond(TCGCond c)
77
+{
18
+{
78
+ return (TCGCond)(c ^ 1);
19
+ mmap_unlock();
79
+}
20
+}
80
+
21
+
81
+/* Swap the operands in a comparison. */
22
+#define WITH_MMAP_LOCK_GUARD() \
82
+static inline TCGCond tcg_swap_cond(TCGCond c)
23
+ for (int _mmap_lock_iter __attribute__((cleanup(mmap_unlock_guard))) \
83
+{
24
+ = (mmap_lock(), 0); _mmap_lock_iter == 0; _mmap_lock_iter = 1)
84
+ return c & 6 ? (TCGCond)(c ^ 9) : c;
85
+}
86
+
25
+
87
+/* Create an "unsigned" version of a "signed" comparison. */
26
/**
88
+static inline TCGCond tcg_unsigned_cond(TCGCond c)
27
* adjust_signal_pc:
89
+{
28
* @pc: raw pc from the host signal ucontext_t.
90
+ return c & 2 ? (TCGCond)(c ^ 6) : c;
29
@@ -XXX,XX +XXX,XX @@ G_NORETURN void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
91
+}
30
#else
92
+
31
static inline void mmap_lock(void) {}
93
+/* Create a "signed" version of an "unsigned" comparison. */
32
static inline void mmap_unlock(void) {}
94
+static inline TCGCond tcg_signed_cond(TCGCond c)
33
+#define WITH_MMAP_LOCK_GUARD()
95
+{
34
96
+ return c & 4 ? (TCGCond)(c ^ 6) : c;
35
void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length);
97
+}
36
void tlb_set_dirty(CPUState *cpu, vaddr addr);
98
+
37
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
99
+/* Must a comparison be considered unsigned? */
100
+static inline bool is_unsigned_cond(TCGCond c)
101
+{
102
+ return (c & 4) != 0;
103
+}
104
+
105
+/*
106
+ * Create a "high" version of a double-word comparison.
107
+ * This removes equality from a LTE or GTE comparison.
108
+ */
109
+static inline TCGCond tcg_high_cond(TCGCond c)
110
+{
111
+ switch (c) {
112
+ case TCG_COND_GE:
113
+ case TCG_COND_LE:
114
+ case TCG_COND_GEU:
115
+ case TCG_COND_LEU:
116
+ return (TCGCond)(c ^ 8);
117
+ default:
118
+ return c;
119
+ }
120
+}
121
+
122
+#endif /* TCG_COND_H */
123
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
124
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
125
--- a/include/tcg/tcg.h
39
--- a/bsd-user/mmap.c
126
+++ b/include/tcg/tcg.h
40
+++ b/bsd-user/mmap.c
127
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@ void mmap_lock(void)
128
#include "tcg/tcg-mo.h"
42
129
#include "tcg-target.h"
43
void mmap_unlock(void)
130
#include "qemu/int128.h"
44
{
131
+#include "tcg/tcg-cond.h"
45
+ assert(mmap_lock_count > 0);
132
46
if (--mmap_lock_count == 0) {
133
/* XXX: make safe guess about sizes */
47
pthread_mutex_unlock(&mmap_mutex);
134
#define MAX_OP_PER_INSTR 266
48
}
135
@@ -XXX,XX +XXX,XX @@ typedef TCGv_ptr TCGv_env;
49
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
136
/* Used to align parameters. See the comment before tcgv_i32_temp. */
50
index XXXXXXX..XXXXXXX 100644
137
#define TCG_CALL_DUMMY_ARG ((TCGArg)0)
51
--- a/linux-user/mmap.c
138
52
+++ b/linux-user/mmap.c
139
-/* Conditions. Note that these are laid out for easy manipulation by
53
@@ -XXX,XX +XXX,XX @@ void mmap_lock(void)
140
- the functions below:
54
141
- bit 0 is used for inverting;
55
void mmap_unlock(void)
142
- bit 1 is signed,
56
{
143
- bit 2 is unsigned,
57
+ assert(mmap_lock_count > 0);
144
- bit 3 is used with bit 0 for swapping signed/unsigned. */
58
if (--mmap_lock_count == 0) {
145
-typedef enum {
59
pthread_mutex_unlock(&mmap_mutex);
146
- /* non-signed */
60
}
147
- TCG_COND_NEVER = 0 | 0 | 0 | 0,
148
- TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
149
- TCG_COND_EQ = 8 | 0 | 0 | 0,
150
- TCG_COND_NE = 8 | 0 | 0 | 1,
151
- /* signed */
152
- TCG_COND_LT = 0 | 0 | 2 | 0,
153
- TCG_COND_GE = 0 | 0 | 2 | 1,
154
- TCG_COND_LE = 8 | 0 | 2 | 0,
155
- TCG_COND_GT = 8 | 0 | 2 | 1,
156
- /* unsigned */
157
- TCG_COND_LTU = 0 | 4 | 0 | 0,
158
- TCG_COND_GEU = 0 | 4 | 0 | 1,
159
- TCG_COND_LEU = 8 | 4 | 0 | 0,
160
- TCG_COND_GTU = 8 | 4 | 0 | 1,
161
-} TCGCond;
162
-
163
-/* Invert the sense of the comparison. */
164
-static inline TCGCond tcg_invert_cond(TCGCond c)
165
-{
166
- return (TCGCond)(c ^ 1);
167
-}
168
-
169
-/* Swap the operands in a comparison. */
170
-static inline TCGCond tcg_swap_cond(TCGCond c)
171
-{
172
- return c & 6 ? (TCGCond)(c ^ 9) : c;
173
-}
174
-
175
-/* Create an "unsigned" version of a "signed" comparison. */
176
-static inline TCGCond tcg_unsigned_cond(TCGCond c)
177
-{
178
- return c & 2 ? (TCGCond)(c ^ 6) : c;
179
-}
180
-
181
-/* Create a "signed" version of an "unsigned" comparison. */
182
-static inline TCGCond tcg_signed_cond(TCGCond c)
183
-{
184
- return c & 4 ? (TCGCond)(c ^ 6) : c;
185
-}
186
-
187
-/* Must a comparison be considered unsigned? */
188
-static inline bool is_unsigned_cond(TCGCond c)
189
-{
190
- return (c & 4) != 0;
191
-}
192
-
193
-/* Create a "high" version of a double-word comparison.
194
- This removes equality from a LTE or GTE comparison. */
195
-static inline TCGCond tcg_high_cond(TCGCond c)
196
-{
197
- switch (c) {
198
- case TCG_COND_GE:
199
- case TCG_COND_LE:
200
- case TCG_COND_GEU:
201
- case TCG_COND_LEU:
202
- return (TCGCond)(c ^ 8);
203
- default:
204
- return c;
205
- }
206
-}
207
-
208
typedef enum TCGTempVal {
209
TEMP_VAL_DEAD,
210
TEMP_VAL_REG,
211
--
61
--
212
2.25.1
62
2.34.1
213
214
diff view generated by jsdifflib
1
As noted by qemu-plugins.h, plugins can neither read nor write
1
In the initial commit, cdfac37be0d, the sense of the test is incorrect,
2
guest registers.
2
as the -1/0 return was confusing. In bef6f008b981, we mechanically
3
invert all callers while changing to false/true return, preserving the
4
incorrectness of the test.
3
5
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Now that the return sense is sane, it's easy to see that if !write,
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
then the page is not modifiable (i.e. most likely read-only, with
8
PROT_NONE handled via SIGSEGV).
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
12
---
8
accel/tcg/plugin-helpers.h | 4 ++--
13
accel/tcg/ldst_atomicity.c.inc | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
10
15
11
diff --git a/accel/tcg/plugin-helpers.h b/accel/tcg/plugin-helpers.h
16
diff --git a/accel/tcg/ldst_atomicity.c.inc b/accel/tcg/ldst_atomicity.c.inc
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/plugin-helpers.h
18
--- a/accel/tcg/ldst_atomicity.c.inc
14
+++ b/accel/tcg/plugin-helpers.h
19
+++ b/accel/tcg/ldst_atomicity.c.inc
15
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static uint64_t load_atomic8_or_exit(CPUArchState *env, uintptr_t ra, void *pv)
16
#ifdef CONFIG_PLUGIN
21
* another process, because the fallback start_exclusive solution
17
-DEF_HELPER_2(plugin_vcpu_udata_cb, void, i32, ptr)
22
* provides no protection across processes.
18
-DEF_HELPER_4(plugin_vcpu_mem_cb, void, i32, i32, i64, ptr)
23
*/
19
+DEF_HELPER_FLAGS_2(plugin_vcpu_udata_cb, TCG_CALL_NO_RWG, void, i32, ptr)
24
- if (page_check_range(h2g(pv), 8, PAGE_WRITE_ORG)) {
20
+DEF_HELPER_FLAGS_4(plugin_vcpu_mem_cb, TCG_CALL_NO_RWG, void, i32, i32, i64, ptr)
25
+ if (!page_check_range(h2g(pv), 8, PAGE_WRITE_ORG)) {
26
uint64_t *p = __builtin_assume_aligned(pv, 8);
27
return *p;
28
}
29
@@ -XXX,XX +XXX,XX @@ static Int128 load_atomic16_or_exit(CPUArchState *env, uintptr_t ra, void *pv)
30
* another process, because the fallback start_exclusive solution
31
* provides no protection across processes.
32
*/
33
- if (page_check_range(h2g(p), 16, PAGE_WRITE_ORG)) {
34
+ if (!page_check_range(h2g(p), 16, PAGE_WRITE_ORG)) {
35
return *p;
36
}
21
#endif
37
#endif
22
--
38
--
23
2.25.1
39
2.34.1
24
25
diff view generated by jsdifflib
Deleted patch
1
This will give us both flags and typemask for use later.
2
1
3
We also fix a dumping bug, wherein calls generated for plugins
4
fail tcg_find_helper and print (null) instead of either a name
5
or the raw function pointer.
6
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
tcg/tcg-internal.h | 14 ++++++++++++-
12
tcg/tcg.c | 49 ++++++++++++++++++++--------------------------
13
2 files changed, 34 insertions(+), 29 deletions(-)
14
15
diff --git a/tcg/tcg-internal.h b/tcg/tcg-internal.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/tcg/tcg-internal.h
18
+++ b/tcg/tcg-internal.h
19
@@ -XXX,XX +XXX,XX @@
20
21
#define TCG_HIGHWATER 1024
22
23
+typedef struct TCGHelperInfo {
24
+ void *func;
25
+ const char *name;
26
+ unsigned flags;
27
+ unsigned typemask;
28
+} TCGHelperInfo;
29
+
30
extern TCGContext tcg_init_ctx;
31
extern TCGContext **tcg_ctxs;
32
extern unsigned int tcg_cur_ctxs;
33
@@ -XXX,XX +XXX,XX @@ bool tcg_region_alloc(TCGContext *s);
34
void tcg_region_initial_alloc(TCGContext *s);
35
void tcg_region_prologue_set(TCGContext *s);
36
37
+static inline const TCGHelperInfo *tcg_call_info(TCGOp *op)
38
+{
39
+ return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
40
+}
41
+
42
static inline unsigned tcg_call_flags(TCGOp *op)
43
{
44
- return op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
45
+ return tcg_call_info(op)->flags;
46
}
47
48
#endif /* TCG_INTERNAL_H */
49
diff --git a/tcg/tcg.c b/tcg/tcg.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/tcg/tcg.c
52
+++ b/tcg/tcg.c
53
@@ -XXX,XX +XXX,XX @@ void tcg_pool_reset(TCGContext *s)
54
s->pool_current = NULL;
55
}
56
57
-typedef struct TCGHelperInfo {
58
- void *func;
59
- const char *name;
60
- unsigned flags;
61
- unsigned typemask;
62
-} TCGHelperInfo;
63
-
64
#include "exec/helper-proto.h"
65
66
static const TCGHelperInfo all_helpers[] = {
67
@@ -XXX,XX +XXX,XX @@ bool tcg_op_supported(TCGOpcode op)
68
void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
69
{
70
int i, real_args, nb_rets, pi;
71
- unsigned typemask, flags;
72
- TCGHelperInfo *info;
73
+ unsigned typemask;
74
+ const TCGHelperInfo *info;
75
TCGOp *op;
76
77
info = g_hash_table_lookup(helper_table, (gpointer)func);
78
- flags = info->flags;
79
typemask = info->typemask;
80
81
#ifdef CONFIG_PLUGIN
82
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
83
real_args++;
84
}
85
op->args[pi++] = (uintptr_t)func;
86
- op->args[pi++] = flags;
87
+ op->args[pi++] = (uintptr_t)info;
88
TCGOP_CALLI(op) = real_args;
89
90
/* Make sure the fields didn't overflow. */
91
@@ -XXX,XX +XXX,XX @@ static char *tcg_get_arg_str(TCGContext *s, char *buf,
92
return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(arg));
93
}
94
95
-/* Find helper name. */
96
-static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val)
97
-{
98
- const char *ret = NULL;
99
- if (helper_table) {
100
- TCGHelperInfo *info = g_hash_table_lookup(helper_table, (gpointer)val);
101
- if (info) {
102
- ret = info->name;
103
- }
104
- }
105
- return ret;
106
-}
107
-
108
static const char * const cond_name[] =
109
{
110
[TCG_COND_NEVER] = "never",
111
@@ -XXX,XX +XXX,XX @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
112
col += qemu_log(" " TARGET_FMT_lx, a);
113
}
114
} else if (c == INDEX_op_call) {
115
+ const TCGHelperInfo *info = tcg_call_info(op);
116
+ void *func;
117
+
118
/* variable number of arguments */
119
nb_oargs = TCGOP_CALLO(op);
120
nb_iargs = TCGOP_CALLI(op);
121
nb_cargs = def->nb_cargs;
122
123
- /* function name, flags, out args */
124
- col += qemu_log(" %s %s,$0x%x,$%d", def->name,
125
- tcg_find_helper(s, op->args[nb_oargs + nb_iargs]),
126
- tcg_call_flags(op), nb_oargs);
127
+ col += qemu_log(" %s ", def->name);
128
+
129
+ /*
130
+ * Print the function name from TCGHelperInfo, if available.
131
+ * Note that plugins have a template function for the info,
132
+ * but the actual function pointer comes from the plugin.
133
+ */
134
+ func = (void *)(uintptr_t)op->args[nb_oargs + nb_iargs];
135
+ if (func == info->func) {
136
+ col += qemu_log("%s", info->name);
137
+ } else {
138
+ col += qemu_log("plugin(%p)", func);
139
+ }
140
+
141
+ col += qemu_log("$0x%x,$%d", info->flags, nb_oargs);
142
for (i = 0; i < nb_oargs; i++) {
143
col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf),
144
op->args[i]));
145
--
146
2.25.1
147
148
diff view generated by jsdifflib
Deleted patch
1
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
tcg/tcg-internal.h | 5 +++++
6
tcg/tcg.c | 5 ++---
7
2 files changed, 7 insertions(+), 3 deletions(-)
8
1
9
diff --git a/tcg/tcg-internal.h b/tcg/tcg-internal.h
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/tcg-internal.h
12
+++ b/tcg/tcg-internal.h
13
@@ -XXX,XX +XXX,XX @@ bool tcg_region_alloc(TCGContext *s);
14
void tcg_region_initial_alloc(TCGContext *s);
15
void tcg_region_prologue_set(TCGContext *s);
16
17
+static inline void *tcg_call_func(TCGOp *op)
18
+{
19
+ return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op)];
20
+}
21
+
22
static inline const TCGHelperInfo *tcg_call_info(TCGOp *op)
23
{
24
return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
25
diff --git a/tcg/tcg.c b/tcg/tcg.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tcg/tcg.c
28
+++ b/tcg/tcg.c
29
@@ -XXX,XX +XXX,XX @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
30
}
31
} else if (c == INDEX_op_call) {
32
const TCGHelperInfo *info = tcg_call_info(op);
33
- void *func;
34
+ void *func = tcg_call_func(op);
35
36
/* variable number of arguments */
37
nb_oargs = TCGOP_CALLO(op);
38
@@ -XXX,XX +XXX,XX @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
39
* Note that plugins have a template function for the info,
40
* but the actual function pointer comes from the plugin.
41
*/
42
- func = (void *)(uintptr_t)op->args[nb_oargs + nb_iargs];
43
if (func == info->func) {
44
col += qemu_log("%s", info->name);
45
} else {
46
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
47
int allocate_args;
48
TCGRegSet allocated_regs;
49
50
- func_addr = (tcg_insn_unit *)(intptr_t)op->args[nb_oargs + nb_iargs];
51
+ func_addr = tcg_call_func(op);
52
flags = tcg_call_flags(op);
53
54
nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
55
--
56
2.25.1
57
58
diff view generated by jsdifflib
Deleted patch
1
Add libffi as a build requirement for TCI.
2
Add libffi to the dockerfiles to satisfy that requirement.
3
1
4
Construct an ffi_cif structure for each unique typemask.
5
Record the result in a separate hash table for later lookup;
6
this allows helper_table to stay const.
7
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
12
tcg/tcg.c | 58 +++++++++++++++++++
13
tcg/meson.build | 8 ++-
14
tests/docker/dockerfiles/alpine.docker | 1 +
15
tests/docker/dockerfiles/centos8.docker | 1 +
16
tests/docker/dockerfiles/debian10.docker | 1 +
17
.../dockerfiles/fedora-i386-cross.docker | 1 +
18
.../dockerfiles/fedora-win32-cross.docker | 1 +
19
.../dockerfiles/fedora-win64-cross.docker | 1 +
20
tests/docker/dockerfiles/fedora.docker | 1 +
21
tests/docker/dockerfiles/ubuntu.docker | 1 +
22
tests/docker/dockerfiles/ubuntu1804.docker | 1 +
23
tests/docker/dockerfiles/ubuntu2004.docker | 1 +
24
12 files changed, 75 insertions(+), 1 deletion(-)
25
26
diff --git a/tcg/tcg.c b/tcg/tcg.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/tcg/tcg.c
29
+++ b/tcg/tcg.c
30
@@ -XXX,XX +XXX,XX @@
31
#include "exec/log.h"
32
#include "tcg-internal.h"
33
34
+#ifdef CONFIG_TCG_INTERPRETER
35
+#include <ffi.h>
36
+#endif
37
+
38
/* Forward declarations for functions declared in tcg-target.c.inc and
39
used here. */
40
static void tcg_target_init(TCGContext *s);
41
@@ -XXX,XX +XXX,XX @@ static const TCGHelperInfo all_helpers[] = {
42
};
43
static GHashTable *helper_table;
44
45
+#ifdef CONFIG_TCG_INTERPRETER
46
+static GHashTable *ffi_table;
47
+
48
+static ffi_type * const typecode_to_ffi[8] = {
49
+ [dh_typecode_void] = &ffi_type_void,
50
+ [dh_typecode_i32] = &ffi_type_uint32,
51
+ [dh_typecode_s32] = &ffi_type_sint32,
52
+ [dh_typecode_i64] = &ffi_type_uint64,
53
+ [dh_typecode_s64] = &ffi_type_sint64,
54
+ [dh_typecode_ptr] = &ffi_type_pointer,
55
+};
56
+#endif
57
+
58
static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
59
static void process_op_defs(TCGContext *s);
60
static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
61
@@ -XXX,XX +XXX,XX @@ static void tcg_context_init(unsigned max_cpus)
62
(gpointer)&all_helpers[i]);
63
}
64
65
+#ifdef CONFIG_TCG_INTERPRETER
66
+ /* g_direct_hash/equal for direct comparisons on uint32_t. */
67
+ ffi_table = g_hash_table_new(NULL, NULL);
68
+ for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
69
+ struct {
70
+ ffi_cif cif;
71
+ ffi_type *args[];
72
+ } *ca;
73
+ uint32_t typemask = all_helpers[i].typemask;
74
+ gpointer hash = (gpointer)(uintptr_t)typemask;
75
+ ffi_status status;
76
+ int nargs;
77
+
78
+ if (g_hash_table_lookup(ffi_table, hash)) {
79
+ continue;
80
+ }
81
+
82
+ /* Ignoring the return type, find the last non-zero field. */
83
+ nargs = 32 - clz32(typemask >> 3);
84
+ nargs = DIV_ROUND_UP(nargs, 3);
85
+
86
+ ca = g_malloc0(sizeof(*ca) + nargs * sizeof(ffi_type *));
87
+ ca->cif.rtype = typecode_to_ffi[typemask & 7];
88
+ ca->cif.nargs = nargs;
89
+
90
+ if (nargs != 0) {
91
+ ca->cif.arg_types = ca->args;
92
+ for (i = 0; i < nargs; ++i) {
93
+ int typecode = extract32(typemask, (i + 1) * 3, 3);
94
+ ca->args[i] = typecode_to_ffi[typecode];
95
+ }
96
+ }
97
+
98
+ status = ffi_prep_cif(&ca->cif, FFI_DEFAULT_ABI, nargs,
99
+ ca->cif.rtype, ca->cif.arg_types);
100
+ assert(status == FFI_OK);
101
+
102
+ g_hash_table_insert(ffi_table, hash, (gpointer)&ca->cif);
103
+ }
104
+#endif
105
+
106
tcg_target_init(s);
107
process_op_defs(s);
108
109
diff --git a/tcg/meson.build b/tcg/meson.build
110
index XXXXXXX..XXXXXXX 100644
111
--- a/tcg/meson.build
112
+++ b/tcg/meson.build
113
@@ -XXX,XX +XXX,XX @@ tcg_ss.add(files(
114
'tcg-op-gvec.c',
115
'tcg-op-vec.c',
116
))
117
-tcg_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tci.c'))
118
+
119
+if get_option('tcg_interpreter')
120
+ libffi = dependency('libffi', version: '>=3.0', required: true,
121
+ method: 'pkg-config', kwargs: static_kwargs)
122
+ specific_ss.add(libffi)
123
+ specific_ss.add(files('tci.c'))
124
+endif
125
126
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
127
diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker
128
index XXXXXXX..XXXXXXX 100644
129
--- a/tests/docker/dockerfiles/alpine.docker
130
+++ b/tests/docker/dockerfiles/alpine.docker
131
@@ -XXX,XX +XXX,XX @@ ENV PACKAGES \
132
    libaio-dev \
133
    libbpf-dev \
134
    libcap-ng-dev \
135
+    libffi-dev \
136
    libjpeg-turbo-dev \
137
    libnfs-dev \
138
    libpng-dev \
139
diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerfiles/centos8.docker
140
index XXXXXXX..XXXXXXX 100644
141
--- a/tests/docker/dockerfiles/centos8.docker
142
+++ b/tests/docker/dockerfiles/centos8.docker
143
@@ -XXX,XX +XXX,XX @@ ENV PACKAGES \
144
libbpf-devel \
145
libepoxy-devel \
146
libfdt-devel \
147
+ libffi-devel \
148
libgcrypt-devel \
149
lzo-devel \
150
make \
151
diff --git a/tests/docker/dockerfiles/debian10.docker b/tests/docker/dockerfiles/debian10.docker
152
index XXXXXXX..XXXXXXX 100644
153
--- a/tests/docker/dockerfiles/debian10.docker
154
+++ b/tests/docker/dockerfiles/debian10.docker
155
@@ -XXX,XX +XXX,XX @@ RUN apt update && \
156
gdb-multiarch \
157
gettext \
158
git \
159
+ libffi-dev \
160
libncurses5-dev \
161
ninja-build \
162
pkg-config \
163
diff --git a/tests/docker/dockerfiles/fedora-i386-cross.docker b/tests/docker/dockerfiles/fedora-i386-cross.docker
164
index XXXXXXX..XXXXXXX 100644
165
--- a/tests/docker/dockerfiles/fedora-i386-cross.docker
166
+++ b/tests/docker/dockerfiles/fedora-i386-cross.docker
167
@@ -XXX,XX +XXX,XX @@ ENV PACKAGES \
168
findutils \
169
gcc \
170
git \
171
+ libffi-devel.i686 \
172
libtasn1-devel.i686 \
173
libzstd-devel.i686 \
174
make \
175
diff --git a/tests/docker/dockerfiles/fedora-win32-cross.docker b/tests/docker/dockerfiles/fedora-win32-cross.docker
176
index XXXXXXX..XXXXXXX 100644
177
--- a/tests/docker/dockerfiles/fedora-win32-cross.docker
178
+++ b/tests/docker/dockerfiles/fedora-win32-cross.docker
179
@@ -XXX,XX +XXX,XX @@ ENV PACKAGES \
180
mingw32-gmp \
181
mingw32-gnutls \
182
mingw32-gtk3 \
183
+ mingw32-libffi \
184
mingw32-libjpeg-turbo \
185
mingw32-libpng \
186
mingw32-libtasn1 \
187
diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker
188
index XXXXXXX..XXXXXXX 100644
189
--- a/tests/docker/dockerfiles/fedora-win64-cross.docker
190
+++ b/tests/docker/dockerfiles/fedora-win64-cross.docker
191
@@ -XXX,XX +XXX,XX @@ ENV PACKAGES \
192
mingw64-glib2 \
193
mingw64-gmp \
194
mingw64-gtk3 \
195
+ mingw64-libffi \
196
mingw64-libjpeg-turbo \
197
mingw64-libpng \
198
mingw64-libtasn1 \
199
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
200
index XXXXXXX..XXXXXXX 100644
201
--- a/tests/docker/dockerfiles/fedora.docker
202
+++ b/tests/docker/dockerfiles/fedora.docker
203
@@ -XXX,XX +XXX,XX @@ ENV PACKAGES \
204
libepoxy-devel \
205
libfdt-devel \
206
libbpf-devel \
207
+ libffi-devel \
208
libiscsi-devel \
209
libjpeg-devel \
210
libpmem-devel \
211
diff --git a/tests/docker/dockerfiles/ubuntu.docker b/tests/docker/dockerfiles/ubuntu.docker
212
index XXXXXXX..XXXXXXX 100644
213
--- a/tests/docker/dockerfiles/ubuntu.docker
214
+++ b/tests/docker/dockerfiles/ubuntu.docker
215
@@ -XXX,XX +XXX,XX @@ ENV PACKAGES \
216
libdrm-dev \
217
libepoxy-dev \
218
libfdt-dev \
219
+ libffi-dev \
220
libgbm-dev \
221
libgnutls28-dev \
222
libgtk-3-dev \
223
diff --git a/tests/docker/dockerfiles/ubuntu1804.docker b/tests/docker/dockerfiles/ubuntu1804.docker
224
index XXXXXXX..XXXXXXX 100644
225
--- a/tests/docker/dockerfiles/ubuntu1804.docker
226
+++ b/tests/docker/dockerfiles/ubuntu1804.docker
227
@@ -XXX,XX +XXX,XX @@ ENV PACKAGES \
228
libdrm-dev \
229
libepoxy-dev \
230
libfdt-dev \
231
+ libffi-dev \
232
libgbm-dev \
233
libgtk-3-dev \
234
libibverbs-dev \
235
diff --git a/tests/docker/dockerfiles/ubuntu2004.docker b/tests/docker/dockerfiles/ubuntu2004.docker
236
index XXXXXXX..XXXXXXX 100644
237
--- a/tests/docker/dockerfiles/ubuntu2004.docker
238
+++ b/tests/docker/dockerfiles/ubuntu2004.docker
239
@@ -XXX,XX +XXX,XX @@ ENV PACKAGES flex bison \
240
libdrm-dev \
241
libepoxy-dev \
242
libfdt-dev \
243
+ libffi-dev \
244
libgbm-dev \
245
libgtk-3-dev \
246
libibverbs-dev \
247
--
248
2.25.1
249
250
diff view generated by jsdifflib
Deleted patch
1
The current setting is much too pessimistic. Indicating only
2
the one or two registers that are actually assigned after a
3
call should avoid unnecessary movement between the register
4
array and the stack array.
5
1
6
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
tcg/tci/tcg-target.c.inc | 10 ++++++++--
11
1 file changed, 8 insertions(+), 2 deletions(-)
12
13
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tcg/tci/tcg-target.c.inc
16
+++ b/tcg/tci/tcg-target.c.inc
17
@@ -XXX,XX +XXX,XX @@ static void tcg_target_init(TCGContext *s)
18
tcg_target_available_regs[TCG_TYPE_I32] = BIT(TCG_TARGET_NB_REGS) - 1;
19
/* Registers available for 64 bit operations. */
20
tcg_target_available_regs[TCG_TYPE_I64] = BIT(TCG_TARGET_NB_REGS) - 1;
21
- /* TODO: Which registers should be set here? */
22
- tcg_target_call_clobber_regs = BIT(TCG_TARGET_NB_REGS) - 1;
23
+ /*
24
+ * The interpreter "registers" are in the local stack frame and
25
+ * cannot be clobbered by the called helper functions. However,
26
+ * the interpreter assumes a 64-bit return value and assigns to
27
+ * the return value registers.
28
+ */
29
+ tcg_target_call_clobber_regs =
30
+ MAKE_64BIT_MASK(TCG_REG_R0, 64 / TCG_TARGET_REG_BITS);
31
32
s->reserved_regs = 0;
33
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
34
--
35
2.25.1
36
37
diff view generated by jsdifflib
1
This removes all of the problems with unaligned accesses
1
For user-only, the probe for page writability may race with another
2
to the bytecode stream.
2
thread's mprotect. Take the mmap_lock around the operation. This
3
is still faster than the start/end_exclusive fallback.
3
4
4
With an 8-bit opcode at the bottom, we have 24 bits remaining,
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
which are generally split into 6 4-bit slots. This fits well
6
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
7
have 6 register operands.
8
9
We have, in previous patches, rearranged things such that there
10
are no operations with a label which have more than one other
11
operand. Which leaves us with a 20-bit field in which to encode
12
a label, giving us a maximum TB size of 512k -- easily large.
13
14
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
15
The former puts the immediate in the upper 20 bits of the insn,
16
like we do for the label displacement. The later uses a label
17
to reference an entry in the constant pool. Thus, in the worst
18
case we still have a single memory reference for any constant,
19
but now the constants are out-of-line of the bytecode and can
20
be shared between different moves saving space.
21
22
Change INDEX_op_call to use a label to reference a pair of
23
pointers in the constant pool. This removes the only slightly
24
dodgy link with the layout of struct TCGHelperInfo.
25
26
The re-encode cannot be done in pieces.
27
28
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
29
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
30
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
31
---
7
---
32
include/tcg/tcg-opc.h | 4 +-
8
accel/tcg/ldst_atomicity.c.inc | 32 ++++++++++++++++++--------------
33
tcg/tci/tcg-target.h | 3 +-
9
1 file changed, 18 insertions(+), 14 deletions(-)
34
tcg/tci.c | 539 +++++++++++++++------------------------
35
tcg/tci/tcg-target.c.inc | 379 ++++++++++++---------------
36
tcg/tci/README | 20 +-
37
5 files changed, 383 insertions(+), 562 deletions(-)
38
10
39
diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
11
diff --git a/accel/tcg/ldst_atomicity.c.inc b/accel/tcg/ldst_atomicity.c.inc
40
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
41
--- a/include/tcg/tcg-opc.h
13
--- a/accel/tcg/ldst_atomicity.c.inc
42
+++ b/include/tcg/tcg-opc.h
14
+++ b/accel/tcg/ldst_atomicity.c.inc
43
@@ -XXX,XX +XXX,XX @@ DEF(last_generic, 0, 0, 0, TCG_OPF_NOT_PRESENT)
15
@@ -XXX,XX +XXX,XX @@ static uint64_t load_atomic8_or_exit(CPUArchState *env, uintptr_t ra, void *pv)
44
16
* another process, because the fallback start_exclusive solution
45
#ifdef TCG_TARGET_INTERPRETER
17
* provides no protection across processes.
46
/* These opcodes are only for use between the tci generator and interpreter. */
18
*/
47
-DEF(tci_movi_i32, 1, 0, 1, TCG_OPF_NOT_PRESENT)
19
- if (!page_check_range(h2g(pv), 8, PAGE_WRITE_ORG)) {
48
-DEF(tci_movi_i64, 1, 0, 1, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT)
20
- uint64_t *p = __builtin_assume_aligned(pv, 8);
49
+DEF(tci_movi, 1, 0, 1, TCG_OPF_NOT_PRESENT)
21
- return *p;
50
+DEF(tci_movl, 1, 0, 1, TCG_OPF_NOT_PRESENT)
22
+ WITH_MMAP_LOCK_GUARD() {
23
+ if (!page_check_range(h2g(pv), 8, PAGE_WRITE_ORG)) {
24
+ uint64_t *p = __builtin_assume_aligned(pv, 8);
25
+ return *p;
26
+ }
27
}
51
#endif
28
#endif
52
29
53
#undef TLADDR_ARGS
30
@@ -XXX,XX +XXX,XX @@ static Int128 load_atomic16_or_exit(CPUArchState *env, uintptr_t ra, void *pv)
54
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
31
return atomic16_read_ro(p);
55
index XXXXXXX..XXXXXXX 100644
32
}
56
--- a/tcg/tci/tcg-target.h
33
57
+++ b/tcg/tci/tcg-target.h
34
-#ifdef CONFIG_USER_ONLY
58
@@ -XXX,XX +XXX,XX @@
35
/*
59
#define TCG_TARGET_H
36
* We can only use cmpxchg to emulate a load if the page is writable.
60
37
* If the page is not writable, then assume the value is immutable
61
#define TCG_TARGET_INTERPRETER 1
38
* and requires no locking. This ignores the case of MAP_SHARED with
62
-#define TCG_TARGET_INSN_UNIT_SIZE 1
39
* another process, because the fallback start_exclusive solution
63
+#define TCG_TARGET_INSN_UNIT_SIZE 4
40
* provides no protection across processes.
64
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
41
+ *
65
#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
42
+ * In system mode all guest pages are writable. For user mode,
66
43
+ * we must take mmap_lock so that the query remains valid until
67
@@ -XXX,XX +XXX,XX @@ typedef enum {
44
+ * the write is complete -- tests/tcg/multiarch/munmap-pthread.c
68
#define TCG_TARGET_STACK_ALIGN 8
45
+ * is an example that can race.
69
46
*/
70
#define HAVE_TCG_QEMU_TB_EXEC
47
- if (!page_check_range(h2g(p), 16, PAGE_WRITE_ORG)) {
71
+#define TCG_TARGET_NEED_POOL_LABELS
48
- return *p;
72
49
- }
73
/* We could notice __i386__ or __s390x__ and reduce the barriers depending
50
+ WITH_MMAP_LOCK_GUARD() {
74
on the host. But if you want performance, you use the normal backend.
51
+#ifdef CONFIG_USER_ONLY
75
diff --git a/tcg/tci.c b/tcg/tci.c
52
+ if (!page_check_range(h2g(p), 16, PAGE_WRITE_ORG)) {
76
index XXXXXXX..XXXXXXX 100644
53
+ return *p;
77
--- a/tcg/tci.c
54
+ }
78
+++ b/tcg/tci.c
55
#endif
79
@@ -XXX,XX +XXX,XX @@ static uint64_t tci_uint64(uint32_t high, uint32_t low)
80
return ((uint64_t)high << 32) + low;
81
}
82
83
-/* Read constant byte from bytecode. */
84
-static uint8_t tci_read_b(const uint8_t **tb_ptr)
85
-{
86
- return *(tb_ptr[0]++);
87
-}
88
-
56
-
89
-/* Read register number from bytecode. */
57
- /*
90
-static TCGReg tci_read_r(const uint8_t **tb_ptr)
58
- * In system mode all guest pages are writable, and for user-only
91
-{
59
- * we have just checked writability. Try cmpxchg.
92
- uint8_t regno = tci_read_b(tb_ptr);
60
- */
93
- tci_assert(regno < TCG_TARGET_NB_REGS);
61
- if (HAVE_ATOMIC128_RW) {
94
- return regno;
62
- return atomic16_read_rw(p);
95
-}
63
+ if (HAVE_ATOMIC128_RW) {
96
-
64
+ return atomic16_read_rw(p);
97
-/* Read constant (native size) from bytecode. */
98
-static tcg_target_ulong tci_read_i(const uint8_t **tb_ptr)
99
-{
100
- tcg_target_ulong value = *(const tcg_target_ulong *)(*tb_ptr);
101
- *tb_ptr += sizeof(value);
102
- return value;
103
-}
104
-
105
-/* Read unsigned constant (32 bit) from bytecode. */
106
-static uint32_t tci_read_i32(const uint8_t **tb_ptr)
107
-{
108
- uint32_t value = *(const uint32_t *)(*tb_ptr);
109
- *tb_ptr += sizeof(value);
110
- return value;
111
-}
112
-
113
-/* Read signed constant (32 bit) from bytecode. */
114
-static int32_t tci_read_s32(const uint8_t **tb_ptr)
115
-{
116
- int32_t value = *(const int32_t *)(*tb_ptr);
117
- *tb_ptr += sizeof(value);
118
- return value;
119
-}
120
-
121
-static tcg_target_ulong tci_read_label(const uint8_t **tb_ptr)
122
-{
123
- return tci_read_i(tb_ptr);
124
-}
125
-
126
/*
127
* Load sets of arguments all at once. The naming convention is:
128
* tci_args_<arguments>
129
@@ -XXX,XX +XXX,XX @@ static tcg_target_ulong tci_read_label(const uint8_t **tb_ptr)
130
* s = signed ldst offset
131
*/
132
133
-static void check_size(const uint8_t *start, const uint8_t **tb_ptr)
134
+static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
135
{
136
- const uint8_t *old_code_ptr = start - 2;
137
- uint8_t op_size = old_code_ptr[1];
138
- tci_assert(*tb_ptr == old_code_ptr + op_size);
139
+ int diff = sextract32(insn, 12, 20);
140
+ *l0 = diff ? (void *)tb_ptr + diff : NULL;
141
}
142
143
-static void tci_args_l(const uint8_t **tb_ptr, void **l0)
144
+static void tci_args_nl(uint32_t insn, const void *tb_ptr,
145
+ uint8_t *n0, void **l1)
146
{
147
- const uint8_t *start = *tb_ptr;
148
-
149
- *l0 = (void *)tci_read_label(tb_ptr);
150
-
151
- check_size(start, tb_ptr);
152
+ *n0 = extract32(insn, 8, 4);
153
+ *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
154
}
155
156
-static void tci_args_nll(const uint8_t **tb_ptr, uint8_t *n0,
157
- void **l1, void **l2)
158
+static void tci_args_rl(uint32_t insn, const void *tb_ptr,
159
+ TCGReg *r0, void **l1)
160
{
161
- const uint8_t *start = *tb_ptr;
162
-
163
- *n0 = tci_read_b(tb_ptr);
164
- *l1 = (void *)tci_read_label(tb_ptr);
165
- *l2 = (void *)tci_read_label(tb_ptr);
166
-
167
- check_size(start, tb_ptr);
168
+ *r0 = extract32(insn, 8, 4);
169
+ *l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
170
}
171
172
-static void tci_args_rl(const uint8_t **tb_ptr, TCGReg *r0, void **l1)
173
+static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1)
174
{
175
- const uint8_t *start = *tb_ptr;
176
-
177
- *r0 = tci_read_r(tb_ptr);
178
- *l1 = (void *)tci_read_label(tb_ptr);
179
-
180
- check_size(start, tb_ptr);
181
+ *r0 = extract32(insn, 8, 4);
182
+ *r1 = extract32(insn, 12, 4);
183
}
184
185
-static void tci_args_rr(const uint8_t **tb_ptr,
186
- TCGReg *r0, TCGReg *r1)
187
+static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1)
188
{
189
- const uint8_t *start = *tb_ptr;
190
-
191
- *r0 = tci_read_r(tb_ptr);
192
- *r1 = tci_read_r(tb_ptr);
193
-
194
- check_size(start, tb_ptr);
195
+ *r0 = extract32(insn, 8, 4);
196
+ *i1 = sextract32(insn, 12, 20);
197
}
198
199
-static void tci_args_ri(const uint8_t **tb_ptr,
200
- TCGReg *r0, tcg_target_ulong *i1)
201
+static void tci_args_rrm(uint32_t insn, TCGReg *r0,
202
+ TCGReg *r1, TCGMemOpIdx *m2)
203
{
204
- const uint8_t *start = *tb_ptr;
205
-
206
- *r0 = tci_read_r(tb_ptr);
207
- *i1 = tci_read_i32(tb_ptr);
208
-
209
- check_size(start, tb_ptr);
210
+ *r0 = extract32(insn, 8, 4);
211
+ *r1 = extract32(insn, 12, 4);
212
+ *m2 = extract32(insn, 20, 12);
213
}
214
215
-#if TCG_TARGET_REG_BITS == 64
216
-static void tci_args_rI(const uint8_t **tb_ptr,
217
- TCGReg *r0, tcg_target_ulong *i1)
218
+static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2)
219
{
220
- const uint8_t *start = *tb_ptr;
221
-
222
- *r0 = tci_read_r(tb_ptr);
223
- *i1 = tci_read_i(tb_ptr);
224
-
225
- check_size(start, tb_ptr);
226
-}
227
-#endif
228
-
229
-static void tci_args_rrm(const uint8_t **tb_ptr,
230
- TCGReg *r0, TCGReg *r1, TCGMemOpIdx *m2)
231
-{
232
- const uint8_t *start = *tb_ptr;
233
-
234
- *r0 = tci_read_r(tb_ptr);
235
- *r1 = tci_read_r(tb_ptr);
236
- *m2 = tci_read_i32(tb_ptr);
237
-
238
- check_size(start, tb_ptr);
239
+ *r0 = extract32(insn, 8, 4);
240
+ *r1 = extract32(insn, 12, 4);
241
+ *r2 = extract32(insn, 16, 4);
242
}
243
244
-static void tci_args_rrr(const uint8_t **tb_ptr,
245
- TCGReg *r0, TCGReg *r1, TCGReg *r2)
246
+static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
247
{
248
- const uint8_t *start = *tb_ptr;
249
-
250
- *r0 = tci_read_r(tb_ptr);
251
- *r1 = tci_read_r(tb_ptr);
252
- *r2 = tci_read_r(tb_ptr);
253
-
254
- check_size(start, tb_ptr);
255
+ *r0 = extract32(insn, 8, 4);
256
+ *r1 = extract32(insn, 12, 4);
257
+ *i2 = sextract32(insn, 16, 16);
258
}
259
260
-static void tci_args_rrs(const uint8_t **tb_ptr,
261
- TCGReg *r0, TCGReg *r1, int32_t *i2)
262
-{
263
- const uint8_t *start = *tb_ptr;
264
-
265
- *r0 = tci_read_r(tb_ptr);
266
- *r1 = tci_read_r(tb_ptr);
267
- *i2 = tci_read_s32(tb_ptr);
268
-
269
- check_size(start, tb_ptr);
270
-}
271
-
272
-static void tci_args_rrrc(const uint8_t **tb_ptr,
273
+static void tci_args_rrrc(uint32_t insn,
274
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
275
{
276
- const uint8_t *start = *tb_ptr;
277
-
278
- *r0 = tci_read_r(tb_ptr);
279
- *r1 = tci_read_r(tb_ptr);
280
- *r2 = tci_read_r(tb_ptr);
281
- *c3 = tci_read_b(tb_ptr);
282
-
283
- check_size(start, tb_ptr);
284
+ *r0 = extract32(insn, 8, 4);
285
+ *r1 = extract32(insn, 12, 4);
286
+ *r2 = extract32(insn, 16, 4);
287
+ *c3 = extract32(insn, 20, 4);
288
}
289
290
-static void tci_args_rrrm(const uint8_t **tb_ptr,
291
+static void tci_args_rrrm(uint32_t insn,
292
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGMemOpIdx *m3)
293
{
294
- const uint8_t *start = *tb_ptr;
295
-
296
- *r0 = tci_read_r(tb_ptr);
297
- *r1 = tci_read_r(tb_ptr);
298
- *r2 = tci_read_r(tb_ptr);
299
- *m3 = tci_read_i32(tb_ptr);
300
-
301
- check_size(start, tb_ptr);
302
+ *r0 = extract32(insn, 8, 4);
303
+ *r1 = extract32(insn, 12, 4);
304
+ *r2 = extract32(insn, 16, 4);
305
+ *m3 = extract32(insn, 20, 12);
306
}
307
308
-static void tci_args_rrrbb(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
309
+static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
310
TCGReg *r2, uint8_t *i3, uint8_t *i4)
311
{
312
- const uint8_t *start = *tb_ptr;
313
-
314
- *r0 = tci_read_r(tb_ptr);
315
- *r1 = tci_read_r(tb_ptr);
316
- *r2 = tci_read_r(tb_ptr);
317
- *i3 = tci_read_b(tb_ptr);
318
- *i4 = tci_read_b(tb_ptr);
319
-
320
- check_size(start, tb_ptr);
321
+ *r0 = extract32(insn, 8, 4);
322
+ *r1 = extract32(insn, 12, 4);
323
+ *r2 = extract32(insn, 16, 4);
324
+ *i3 = extract32(insn, 20, 6);
325
+ *i4 = extract32(insn, 26, 6);
326
}
327
328
-static void tci_args_rrrrm(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
329
- TCGReg *r2, TCGReg *r3, TCGMemOpIdx *m4)
330
+static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
331
+ TCGReg *r2, TCGReg *r3, TCGReg *r4)
332
{
333
- const uint8_t *start = *tb_ptr;
334
-
335
- *r0 = tci_read_r(tb_ptr);
336
- *r1 = tci_read_r(tb_ptr);
337
- *r2 = tci_read_r(tb_ptr);
338
- *r3 = tci_read_r(tb_ptr);
339
- *m4 = tci_read_i32(tb_ptr);
340
-
341
- check_size(start, tb_ptr);
342
+ *r0 = extract32(insn, 8, 4);
343
+ *r1 = extract32(insn, 12, 4);
344
+ *r2 = extract32(insn, 16, 4);
345
+ *r3 = extract32(insn, 20, 4);
346
+ *r4 = extract32(insn, 24, 4);
347
}
348
349
#if TCG_TARGET_REG_BITS == 32
350
-static void tci_args_rrrr(const uint8_t **tb_ptr,
351
+static void tci_args_rrrr(uint32_t insn,
352
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
353
{
354
- const uint8_t *start = *tb_ptr;
355
-
356
- *r0 = tci_read_r(tb_ptr);
357
- *r1 = tci_read_r(tb_ptr);
358
- *r2 = tci_read_r(tb_ptr);
359
- *r3 = tci_read_r(tb_ptr);
360
-
361
- check_size(start, tb_ptr);
362
+ *r0 = extract32(insn, 8, 4);
363
+ *r1 = extract32(insn, 12, 4);
364
+ *r2 = extract32(insn, 16, 4);
365
+ *r3 = extract32(insn, 20, 4);
366
}
367
368
-static void tci_args_rrrrrc(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
369
+static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
370
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
371
{
372
- const uint8_t *start = *tb_ptr;
373
-
374
- *r0 = tci_read_r(tb_ptr);
375
- *r1 = tci_read_r(tb_ptr);
376
- *r2 = tci_read_r(tb_ptr);
377
- *r3 = tci_read_r(tb_ptr);
378
- *r4 = tci_read_r(tb_ptr);
379
- *c5 = tci_read_b(tb_ptr);
380
-
381
- check_size(start, tb_ptr);
382
+ *r0 = extract32(insn, 8, 4);
383
+ *r1 = extract32(insn, 12, 4);
384
+ *r2 = extract32(insn, 16, 4);
385
+ *r3 = extract32(insn, 20, 4);
386
+ *r4 = extract32(insn, 24, 4);
387
+ *c5 = extract32(insn, 28, 4);
388
}
389
390
-static void tci_args_rrrrrr(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
391
+static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
392
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
393
{
394
- const uint8_t *start = *tb_ptr;
395
-
396
- *r0 = tci_read_r(tb_ptr);
397
- *r1 = tci_read_r(tb_ptr);
398
- *r2 = tci_read_r(tb_ptr);
399
- *r3 = tci_read_r(tb_ptr);
400
- *r4 = tci_read_r(tb_ptr);
401
- *r5 = tci_read_r(tb_ptr);
402
-
403
- check_size(start, tb_ptr);
404
+ *r0 = extract32(insn, 8, 4);
405
+ *r1 = extract32(insn, 12, 4);
406
+ *r2 = extract32(insn, 16, 4);
407
+ *r3 = extract32(insn, 20, 4);
408
+ *r4 = extract32(insn, 24, 4);
409
+ *r5 = extract32(insn, 28, 4);
410
}
411
#endif
412
413
@@ -XXX,XX +XXX,XX @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
414
uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
415
const void *v_tb_ptr)
416
{
417
- const uint8_t *tb_ptr = v_tb_ptr;
418
+ const uint32_t *tb_ptr = v_tb_ptr;
419
tcg_target_ulong regs[TCG_TARGET_NB_REGS];
420
uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
421
/ sizeof(uint64_t)];
422
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
423
tci_assert(tb_ptr);
424
425
for (;;) {
426
- TCGOpcode opc = tb_ptr[0];
427
- TCGReg r0, r1, r2, r3;
428
+ uint32_t insn;
429
+ TCGOpcode opc;
430
+ TCGReg r0, r1, r2, r3, r4;
431
tcg_target_ulong t1;
432
TCGCond condition;
433
target_ulong taddr;
434
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
435
uint32_t tmp32;
436
uint64_t tmp64;
437
#if TCG_TARGET_REG_BITS == 32
438
- TCGReg r4, r5;
439
+ TCGReg r5;
440
uint64_t T1, T2;
441
#endif
442
TCGMemOpIdx oi;
443
int32_t ofs;
444
- void *ptr, *cif;
445
+ void *ptr;
446
447
- /* Skip opcode and size entry. */
448
- tb_ptr += 2;
449
+ insn = *tb_ptr++;
450
+ opc = extract32(insn, 0, 8);
451
452
switch (opc) {
453
case INDEX_op_call:
454
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
455
}
456
}
457
458
- tci_args_nll(&tb_ptr, &len, &ptr, &cif);
459
+ tci_args_nl(insn, tb_ptr, &len, &ptr);
460
461
/* Helper functions may need to access the "return address" */
462
tci_tb_ptr = (uintptr_t)tb_ptr;
463
464
- ffi_call(cif, ptr, stack, call_slots);
465
+ {
466
+ void **pptr = ptr;
467
+ ffi_call(pptr[1], pptr[0], stack, call_slots);
468
+ }
469
470
/* Any result winds up "left-aligned" in the stack[0] slot. */
471
switch (len) {
472
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
473
break;
474
475
case INDEX_op_br:
476
- tci_args_l(&tb_ptr, &ptr);
477
+ tci_args_l(insn, tb_ptr, &ptr);
478
tb_ptr = ptr;
479
continue;
480
case INDEX_op_setcond_i32:
481
- tci_args_rrrc(&tb_ptr, &r0, &r1, &r2, &condition);
482
+ tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
483
regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
484
break;
485
#if TCG_TARGET_REG_BITS == 32
486
case INDEX_op_setcond2_i32:
487
- tci_args_rrrrrc(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &condition);
488
+ tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
489
T1 = tci_uint64(regs[r2], regs[r1]);
490
T2 = tci_uint64(regs[r4], regs[r3]);
491
regs[r0] = tci_compare64(T1, T2, condition);
492
break;
493
#elif TCG_TARGET_REG_BITS == 64
494
case INDEX_op_setcond_i64:
495
- tci_args_rrrc(&tb_ptr, &r0, &r1, &r2, &condition);
496
+ tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
497
regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
498
break;
499
#endif
500
CASE_32_64(mov)
501
- tci_args_rr(&tb_ptr, &r0, &r1);
502
+ tci_args_rr(insn, &r0, &r1);
503
regs[r0] = regs[r1];
504
break;
505
- case INDEX_op_tci_movi_i32:
506
- tci_args_ri(&tb_ptr, &r0, &t1);
507
+ case INDEX_op_tci_movi:
508
+ tci_args_ri(insn, &r0, &t1);
509
regs[r0] = t1;
510
break;
511
+ case INDEX_op_tci_movl:
512
+ tci_args_rl(insn, tb_ptr, &r0, &ptr);
513
+ regs[r0] = *(tcg_target_ulong *)ptr;
514
+ break;
515
516
/* Load/store operations (32 bit). */
517
518
CASE_32_64(ld8u)
519
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
520
+ tci_args_rrs(insn, &r0, &r1, &ofs);
521
ptr = (void *)(regs[r1] + ofs);
522
regs[r0] = *(uint8_t *)ptr;
523
break;
524
CASE_32_64(ld8s)
525
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
526
+ tci_args_rrs(insn, &r0, &r1, &ofs);
527
ptr = (void *)(regs[r1] + ofs);
528
regs[r0] = *(int8_t *)ptr;
529
break;
530
CASE_32_64(ld16u)
531
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
532
+ tci_args_rrs(insn, &r0, &r1, &ofs);
533
ptr = (void *)(regs[r1] + ofs);
534
regs[r0] = *(uint16_t *)ptr;
535
break;
536
CASE_32_64(ld16s)
537
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
538
+ tci_args_rrs(insn, &r0, &r1, &ofs);
539
ptr = (void *)(regs[r1] + ofs);
540
regs[r0] = *(int16_t *)ptr;
541
break;
542
case INDEX_op_ld_i32:
543
CASE_64(ld32u)
544
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
545
+ tci_args_rrs(insn, &r0, &r1, &ofs);
546
ptr = (void *)(regs[r1] + ofs);
547
regs[r0] = *(uint32_t *)ptr;
548
break;
549
CASE_32_64(st8)
550
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
551
+ tci_args_rrs(insn, &r0, &r1, &ofs);
552
ptr = (void *)(regs[r1] + ofs);
553
*(uint8_t *)ptr = regs[r0];
554
break;
555
CASE_32_64(st16)
556
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
557
+ tci_args_rrs(insn, &r0, &r1, &ofs);
558
ptr = (void *)(regs[r1] + ofs);
559
*(uint16_t *)ptr = regs[r0];
560
break;
561
case INDEX_op_st_i32:
562
CASE_64(st32)
563
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
564
+ tci_args_rrs(insn, &r0, &r1, &ofs);
565
ptr = (void *)(regs[r1] + ofs);
566
*(uint32_t *)ptr = regs[r0];
567
break;
568
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
569
/* Arithmetic operations (mixed 32/64 bit). */
570
571
CASE_32_64(add)
572
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
573
+ tci_args_rrr(insn, &r0, &r1, &r2);
574
regs[r0] = regs[r1] + regs[r2];
575
break;
576
CASE_32_64(sub)
577
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
578
+ tci_args_rrr(insn, &r0, &r1, &r2);
579
regs[r0] = regs[r1] - regs[r2];
580
break;
581
CASE_32_64(mul)
582
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
583
+ tci_args_rrr(insn, &r0, &r1, &r2);
584
regs[r0] = regs[r1] * regs[r2];
585
break;
586
CASE_32_64(and)
587
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
588
+ tci_args_rrr(insn, &r0, &r1, &r2);
589
regs[r0] = regs[r1] & regs[r2];
590
break;
591
CASE_32_64(or)
592
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
593
+ tci_args_rrr(insn, &r0, &r1, &r2);
594
regs[r0] = regs[r1] | regs[r2];
595
break;
596
CASE_32_64(xor)
597
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
598
+ tci_args_rrr(insn, &r0, &r1, &r2);
599
regs[r0] = regs[r1] ^ regs[r2];
600
break;
601
602
/* Arithmetic operations (32 bit). */
603
604
case INDEX_op_div_i32:
605
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
606
+ tci_args_rrr(insn, &r0, &r1, &r2);
607
regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2];
608
break;
609
case INDEX_op_divu_i32:
610
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
611
+ tci_args_rrr(insn, &r0, &r1, &r2);
612
regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2];
613
break;
614
case INDEX_op_rem_i32:
615
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
616
+ tci_args_rrr(insn, &r0, &r1, &r2);
617
regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2];
618
break;
619
case INDEX_op_remu_i32:
620
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
621
+ tci_args_rrr(insn, &r0, &r1, &r2);
622
regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
623
break;
624
625
/* Shift/rotate operations (32 bit). */
626
627
case INDEX_op_shl_i32:
628
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
629
+ tci_args_rrr(insn, &r0, &r1, &r2);
630
regs[r0] = (uint32_t)regs[r1] << (regs[r2] & 31);
631
break;
632
case INDEX_op_shr_i32:
633
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
634
+ tci_args_rrr(insn, &r0, &r1, &r2);
635
regs[r0] = (uint32_t)regs[r1] >> (regs[r2] & 31);
636
break;
637
case INDEX_op_sar_i32:
638
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
639
+ tci_args_rrr(insn, &r0, &r1, &r2);
640
regs[r0] = (int32_t)regs[r1] >> (regs[r2] & 31);
641
break;
642
#if TCG_TARGET_HAS_rot_i32
643
case INDEX_op_rotl_i32:
644
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
645
+ tci_args_rrr(insn, &r0, &r1, &r2);
646
regs[r0] = rol32(regs[r1], regs[r2] & 31);
647
break;
648
case INDEX_op_rotr_i32:
649
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
650
+ tci_args_rrr(insn, &r0, &r1, &r2);
651
regs[r0] = ror32(regs[r1], regs[r2] & 31);
652
break;
653
#endif
654
#if TCG_TARGET_HAS_deposit_i32
655
case INDEX_op_deposit_i32:
656
- tci_args_rrrbb(&tb_ptr, &r0, &r1, &r2, &pos, &len);
657
+ tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
658
regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
659
break;
660
#endif
661
case INDEX_op_brcond_i32:
662
- tci_args_rl(&tb_ptr, &r0, &ptr);
663
+ tci_args_rl(insn, tb_ptr, &r0, &ptr);
664
if ((uint32_t)regs[r0]) {
665
tb_ptr = ptr;
666
}
667
break;
668
#if TCG_TARGET_REG_BITS == 32
669
case INDEX_op_add2_i32:
670
- tci_args_rrrrrr(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &r5);
671
+ tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
672
T1 = tci_uint64(regs[r3], regs[r2]);
673
T2 = tci_uint64(regs[r5], regs[r4]);
674
tci_write_reg64(regs, r1, r0, T1 + T2);
675
break;
676
case INDEX_op_sub2_i32:
677
- tci_args_rrrrrr(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &r5);
678
+ tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
679
T1 = tci_uint64(regs[r3], regs[r2]);
680
T2 = tci_uint64(regs[r5], regs[r4]);
681
tci_write_reg64(regs, r1, r0, T1 - T2);
682
break;
683
case INDEX_op_mulu2_i32:
684
- tci_args_rrrr(&tb_ptr, &r0, &r1, &r2, &r3);
685
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
686
tci_write_reg64(regs, r1, r0, (uint64_t)regs[r2] * regs[r3]);
687
break;
688
#endif /* TCG_TARGET_REG_BITS == 32 */
689
#if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
690
CASE_32_64(ext8s)
691
- tci_args_rr(&tb_ptr, &r0, &r1);
692
+ tci_args_rr(insn, &r0, &r1);
693
regs[r0] = (int8_t)regs[r1];
694
break;
695
#endif
696
#if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64
697
CASE_32_64(ext16s)
698
- tci_args_rr(&tb_ptr, &r0, &r1);
699
+ tci_args_rr(insn, &r0, &r1);
700
regs[r0] = (int16_t)regs[r1];
701
break;
702
#endif
703
#if TCG_TARGET_HAS_ext8u_i32 || TCG_TARGET_HAS_ext8u_i64
704
CASE_32_64(ext8u)
705
- tci_args_rr(&tb_ptr, &r0, &r1);
706
+ tci_args_rr(insn, &r0, &r1);
707
regs[r0] = (uint8_t)regs[r1];
708
break;
709
#endif
710
#if TCG_TARGET_HAS_ext16u_i32 || TCG_TARGET_HAS_ext16u_i64
711
CASE_32_64(ext16u)
712
- tci_args_rr(&tb_ptr, &r0, &r1);
713
+ tci_args_rr(insn, &r0, &r1);
714
regs[r0] = (uint16_t)regs[r1];
715
break;
716
#endif
717
#if TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
718
CASE_32_64(bswap16)
719
- tci_args_rr(&tb_ptr, &r0, &r1);
720
+ tci_args_rr(insn, &r0, &r1);
721
regs[r0] = bswap16(regs[r1]);
722
break;
723
#endif
724
#if TCG_TARGET_HAS_bswap32_i32 || TCG_TARGET_HAS_bswap32_i64
725
CASE_32_64(bswap32)
726
- tci_args_rr(&tb_ptr, &r0, &r1);
727
+ tci_args_rr(insn, &r0, &r1);
728
regs[r0] = bswap32(regs[r1]);
729
break;
730
#endif
731
#if TCG_TARGET_HAS_not_i32 || TCG_TARGET_HAS_not_i64
732
CASE_32_64(not)
733
- tci_args_rr(&tb_ptr, &r0, &r1);
734
+ tci_args_rr(insn, &r0, &r1);
735
regs[r0] = ~regs[r1];
736
break;
737
#endif
738
#if TCG_TARGET_HAS_neg_i32 || TCG_TARGET_HAS_neg_i64
739
CASE_32_64(neg)
740
- tci_args_rr(&tb_ptr, &r0, &r1);
741
+ tci_args_rr(insn, &r0, &r1);
742
regs[r0] = -regs[r1];
743
break;
744
#endif
745
#if TCG_TARGET_REG_BITS == 64
746
- case INDEX_op_tci_movi_i64:
747
- tci_args_rI(&tb_ptr, &r0, &t1);
748
- regs[r0] = t1;
749
- break;
750
-
751
/* Load/store operations (64 bit). */
752
753
case INDEX_op_ld32s_i64:
754
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
755
+ tci_args_rrs(insn, &r0, &r1, &ofs);
756
ptr = (void *)(regs[r1] + ofs);
757
regs[r0] = *(int32_t *)ptr;
758
break;
759
case INDEX_op_ld_i64:
760
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
761
+ tci_args_rrs(insn, &r0, &r1, &ofs);
762
ptr = (void *)(regs[r1] + ofs);
763
regs[r0] = *(uint64_t *)ptr;
764
break;
765
case INDEX_op_st_i64:
766
- tci_args_rrs(&tb_ptr, &r0, &r1, &ofs);
767
+ tci_args_rrs(insn, &r0, &r1, &ofs);
768
ptr = (void *)(regs[r1] + ofs);
769
*(uint64_t *)ptr = regs[r0];
770
break;
771
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
772
/* Arithmetic operations (64 bit). */
773
774
case INDEX_op_div_i64:
775
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
776
+ tci_args_rrr(insn, &r0, &r1, &r2);
777
regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
778
break;
779
case INDEX_op_divu_i64:
780
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
781
+ tci_args_rrr(insn, &r0, &r1, &r2);
782
regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
783
break;
784
case INDEX_op_rem_i64:
785
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
786
+ tci_args_rrr(insn, &r0, &r1, &r2);
787
regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
788
break;
789
case INDEX_op_remu_i64:
790
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
791
+ tci_args_rrr(insn, &r0, &r1, &r2);
792
regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
793
break;
794
795
/* Shift/rotate operations (64 bit). */
796
797
case INDEX_op_shl_i64:
798
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
799
+ tci_args_rrr(insn, &r0, &r1, &r2);
800
regs[r0] = regs[r1] << (regs[r2] & 63);
801
break;
802
case INDEX_op_shr_i64:
803
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
804
+ tci_args_rrr(insn, &r0, &r1, &r2);
805
regs[r0] = regs[r1] >> (regs[r2] & 63);
806
break;
807
case INDEX_op_sar_i64:
808
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
809
+ tci_args_rrr(insn, &r0, &r1, &r2);
810
regs[r0] = (int64_t)regs[r1] >> (regs[r2] & 63);
811
break;
812
#if TCG_TARGET_HAS_rot_i64
813
case INDEX_op_rotl_i64:
814
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
815
+ tci_args_rrr(insn, &r0, &r1, &r2);
816
regs[r0] = rol64(regs[r1], regs[r2] & 63);
817
break;
818
case INDEX_op_rotr_i64:
819
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
820
+ tci_args_rrr(insn, &r0, &r1, &r2);
821
regs[r0] = ror64(regs[r1], regs[r2] & 63);
822
break;
823
#endif
824
#if TCG_TARGET_HAS_deposit_i64
825
case INDEX_op_deposit_i64:
826
- tci_args_rrrbb(&tb_ptr, &r0, &r1, &r2, &pos, &len);
827
+ tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
828
regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
829
break;
830
#endif
831
case INDEX_op_brcond_i64:
832
- tci_args_rl(&tb_ptr, &r0, &ptr);
833
+ tci_args_rl(insn, tb_ptr, &r0, &ptr);
834
if (regs[r0]) {
835
tb_ptr = ptr;
836
}
837
break;
838
case INDEX_op_ext32s_i64:
839
case INDEX_op_ext_i32_i64:
840
- tci_args_rr(&tb_ptr, &r0, &r1);
841
+ tci_args_rr(insn, &r0, &r1);
842
regs[r0] = (int32_t)regs[r1];
843
break;
844
case INDEX_op_ext32u_i64:
845
case INDEX_op_extu_i32_i64:
846
- tci_args_rr(&tb_ptr, &r0, &r1);
847
+ tci_args_rr(insn, &r0, &r1);
848
regs[r0] = (uint32_t)regs[r1];
849
break;
850
#if TCG_TARGET_HAS_bswap64_i64
851
case INDEX_op_bswap64_i64:
852
- tci_args_rr(&tb_ptr, &r0, &r1);
853
+ tci_args_rr(insn, &r0, &r1);
854
regs[r0] = bswap64(regs[r1]);
855
break;
856
#endif
857
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
858
/* QEMU specific operations. */
859
860
case INDEX_op_exit_tb:
861
- tci_args_l(&tb_ptr, &ptr);
862
+ tci_args_l(insn, tb_ptr, &ptr);
863
return (uintptr_t)ptr;
864
865
case INDEX_op_goto_tb:
866
- tci_args_l(&tb_ptr, &ptr);
867
+ tci_args_l(insn, tb_ptr, &ptr);
868
tb_ptr = *(void **)ptr;
869
break;
870
871
case INDEX_op_qemu_ld_i32:
872
if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
873
- tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
874
+ tci_args_rrm(insn, &r0, &r1, &oi);
875
taddr = regs[r1];
876
} else {
877
- tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
878
+ tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
879
taddr = tci_uint64(regs[r2], regs[r1]);
880
}
881
switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
882
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
883
884
case INDEX_op_qemu_ld_i64:
885
if (TCG_TARGET_REG_BITS == 64) {
886
- tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
887
+ tci_args_rrm(insn, &r0, &r1, &oi);
888
taddr = regs[r1];
889
} else if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
890
- tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
891
+ tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
892
taddr = regs[r2];
893
} else {
894
- tci_args_rrrrm(&tb_ptr, &r0, &r1, &r2, &r3, &oi);
895
+ tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
896
taddr = tci_uint64(regs[r3], regs[r2]);
897
+ oi = regs[r4];
898
}
899
switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
900
case MO_UB:
901
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
902
903
case INDEX_op_qemu_st_i32:
904
if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
905
- tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
906
+ tci_args_rrm(insn, &r0, &r1, &oi);
907
taddr = regs[r1];
908
} else {
909
- tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
910
+ tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
911
taddr = tci_uint64(regs[r2], regs[r1]);
912
}
913
tmp32 = regs[r0];
914
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
915
916
case INDEX_op_qemu_st_i64:
917
if (TCG_TARGET_REG_BITS == 64) {
918
- tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
919
+ tci_args_rrm(insn, &r0, &r1, &oi);
920
taddr = regs[r1];
921
tmp64 = regs[r0];
922
} else {
923
if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
924
- tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
925
+ tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
926
taddr = regs[r2];
927
} else {
928
- tci_args_rrrrm(&tb_ptr, &r0, &r1, &r2, &r3, &oi);
929
+ tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
930
taddr = tci_uint64(regs[r3], regs[r2]);
931
+ oi = regs[r4];
932
}
933
tmp64 = tci_uint64(regs[r1], regs[r0]);
934
}
935
@@ -XXX,XX +XXX,XX @@ static const char *str_c(TCGCond c)
936
/* Disassemble TCI bytecode. */
937
int print_insn_tci(bfd_vma addr, disassemble_info *info)
938
{
939
- uint8_t buf[256];
940
- int length, status;
941
+ const uint32_t *tb_ptr = (const void *)(uintptr_t)addr;
942
const TCGOpDef *def;
943
const char *op_name;
944
+ uint32_t insn;
945
TCGOpcode op;
946
- TCGReg r0, r1, r2, r3;
947
+ TCGReg r0, r1, r2, r3, r4;
948
#if TCG_TARGET_REG_BITS == 32
949
- TCGReg r4, r5;
950
+ TCGReg r5;
951
#endif
952
tcg_target_ulong i1;
953
int32_t s2;
954
TCGCond c;
955
TCGMemOpIdx oi;
956
uint8_t pos, len;
957
- void *ptr, *cif;
958
- const uint8_t *tb_ptr;
959
+ void *ptr;
960
961
- status = info->read_memory_func(addr, buf, 2, info);
962
- if (status != 0) {
963
- info->memory_error_func(status, addr, info);
964
- return -1;
965
- }
966
- op = buf[0];
967
- length = buf[1];
968
+ /* TCI is always the host, so we don't need to load indirect. */
969
+ insn = *tb_ptr++;
970
971
- if (length < 2) {
972
- info->fprintf_func(info->stream, "invalid length %d", length);
973
- return 1;
974
- }
975
-
976
- status = info->read_memory_func(addr + 2, buf + 2, length - 2, info);
977
- if (status != 0) {
978
- info->memory_error_func(status, addr + 2, info);
979
- return -1;
980
- }
981
+ info->fprintf_func(info->stream, "%08x ", insn);
982
983
+ op = extract32(insn, 0, 8);
984
def = &tcg_op_defs[op];
985
op_name = def->name;
986
- tb_ptr = buf + 2;
987
988
switch (op) {
989
case INDEX_op_br:
990
case INDEX_op_exit_tb:
991
case INDEX_op_goto_tb:
992
- tci_args_l(&tb_ptr, &ptr);
993
+ tci_args_l(insn, tb_ptr, &ptr);
994
info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
995
break;
996
997
case INDEX_op_call:
998
- tci_args_nll(&tb_ptr, &len, &ptr, &cif);
999
- info->fprintf_func(info->stream, "%-12s %d, %p, %p",
1000
- op_name, len, ptr, cif);
1001
+ tci_args_nl(insn, tb_ptr, &len, &ptr);
1002
+ info->fprintf_func(info->stream, "%-12s %d, %p", op_name, len, ptr);
1003
break;
1004
1005
case INDEX_op_brcond_i32:
1006
case INDEX_op_brcond_i64:
1007
- tci_args_rl(&tb_ptr, &r0, &ptr);
1008
+ tci_args_rl(insn, tb_ptr, &r0, &ptr);
1009
info->fprintf_func(info->stream, "%-12s %s, 0, ne, %p",
1010
op_name, str_r(r0), ptr);
1011
break;
1012
1013
case INDEX_op_setcond_i32:
1014
case INDEX_op_setcond_i64:
1015
- tci_args_rrrc(&tb_ptr, &r0, &r1, &r2, &c);
1016
+ tci_args_rrrc(insn, &r0, &r1, &r2, &c);
1017
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1018
op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
1019
break;
1020
1021
- case INDEX_op_tci_movi_i32:
1022
- tci_args_ri(&tb_ptr, &r0, &i1);
1023
+ case INDEX_op_tci_movi:
1024
+ tci_args_ri(insn, &r0, &i1);
1025
info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx,
1026
op_name, str_r(r0), i1);
1027
break;
1028
1029
-#if TCG_TARGET_REG_BITS == 64
1030
- case INDEX_op_tci_movi_i64:
1031
- tci_args_rI(&tb_ptr, &r0, &i1);
1032
- info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx,
1033
- op_name, str_r(r0), i1);
1034
+ case INDEX_op_tci_movl:
1035
+ tci_args_rl(insn, tb_ptr, &r0, &ptr);
1036
+ info->fprintf_func(info->stream, "%-12s %s, %p",
1037
+ op_name, str_r(r0), ptr);
1038
break;
1039
-#endif
1040
1041
case INDEX_op_ld8u_i32:
1042
case INDEX_op_ld8u_i64:
1043
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
1044
case INDEX_op_st32_i64:
1045
case INDEX_op_st_i32:
1046
case INDEX_op_st_i64:
1047
- tci_args_rrs(&tb_ptr, &r0, &r1, &s2);
1048
+ tci_args_rrs(insn, &r0, &r1, &s2);
1049
info->fprintf_func(info->stream, "%-12s %s, %s, %d",
1050
op_name, str_r(r0), str_r(r1), s2);
1051
break;
1052
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
1053
case INDEX_op_not_i64:
1054
case INDEX_op_neg_i32:
1055
case INDEX_op_neg_i64:
1056
- tci_args_rr(&tb_ptr, &r0, &r1);
1057
+ tci_args_rr(insn, &r0, &r1);
1058
info->fprintf_func(info->stream, "%-12s %s, %s",
1059
op_name, str_r(r0), str_r(r1));
1060
break;
1061
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
1062
case INDEX_op_rotl_i64:
1063
case INDEX_op_rotr_i32:
1064
case INDEX_op_rotr_i64:
1065
- tci_args_rrr(&tb_ptr, &r0, &r1, &r2);
1066
+ tci_args_rrr(insn, &r0, &r1, &r2);
1067
info->fprintf_func(info->stream, "%-12s %s, %s, %s",
1068
op_name, str_r(r0), str_r(r1), str_r(r2));
1069
break;
1070
1071
case INDEX_op_deposit_i32:
1072
case INDEX_op_deposit_i64:
1073
- tci_args_rrrbb(&tb_ptr, &r0, &r1, &r2, &pos, &len);
1074
+ tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
1075
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %d, %d",
1076
op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
1077
break;
1078
1079
#if TCG_TARGET_REG_BITS == 32
1080
case INDEX_op_setcond2_i32:
1081
- tci_args_rrrrrc(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &c);
1082
+ tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
1083
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
1084
op_name, str_r(r0), str_r(r1), str_r(r2),
1085
str_r(r3), str_r(r4), str_c(c));
1086
break;
1087
1088
case INDEX_op_mulu2_i32:
1089
- tci_args_rrrr(&tb_ptr, &r0, &r1, &r2, &r3);
1090
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
1091
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
1092
op_name, str_r(r0), str_r(r1),
1093
str_r(r2), str_r(r3));
1094
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
1095
1096
case INDEX_op_add2_i32:
1097
case INDEX_op_sub2_i32:
1098
- tci_args_rrrrrr(&tb_ptr, &r0, &r1, &r2, &r3, &r4, &r5);
1099
+ tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
1100
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
1101
op_name, str_r(r0), str_r(r1), str_r(r2),
1102
str_r(r3), str_r(r4), str_r(r5));
1103
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
1104
len += DIV_ROUND_UP(TARGET_LONG_BITS, TCG_TARGET_REG_BITS);
1105
switch (len) {
1106
case 2:
1107
- tci_args_rrm(&tb_ptr, &r0, &r1, &oi);
1108
+ tci_args_rrm(insn, &r0, &r1, &oi);
1109
info->fprintf_func(info->stream, "%-12s %s, %s, %x",
1110
op_name, str_r(r0), str_r(r1), oi);
1111
break;
1112
case 3:
1113
- tci_args_rrrm(&tb_ptr, &r0, &r1, &r2, &oi);
1114
+ tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
1115
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %x",
1116
op_name, str_r(r0), str_r(r1), str_r(r2), oi);
1117
break;
1118
case 4:
1119
- tci_args_rrrrm(&tb_ptr, &r0, &r1, &r2, &r3, &oi);
1120
- info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %x",
1121
+ tci_args_rrrrr(insn, &r0, &r1, &r2, &r3, &r4);
1122
+ info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s",
1123
op_name, str_r(r0), str_r(r1),
1124
- str_r(r2), str_r(r3), oi);
1125
+ str_r(r2), str_r(r3), str_r(r4));
1126
break;
1127
default:
1128
g_assert_not_reached();
1129
}
1130
break;
1131
1132
+ case 0:
1133
+ /* tcg_out_nop_fill uses zeros */
1134
+ if (insn == 0) {
1135
+ info->fprintf_func(info->stream, "align");
1136
+ break;
1137
+ }
65
+ }
1138
+ /* fall through */
1139
+
1140
default:
1141
info->fprintf_func(info->stream, "illegal opcode %d", op);
1142
break;
1143
}
66
}
1144
67
1145
- return length;
68
/* Ultimate fallback: re-execute in serial context. */
1146
+ return sizeof(insn);
1147
}
1148
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
1149
index XXXXXXX..XXXXXXX 100644
1150
--- a/tcg/tci/tcg-target.c.inc
1151
+++ b/tcg/tci/tcg-target.c.inc
1152
@@ -XXX,XX +XXX,XX @@
1153
* THE SOFTWARE.
1154
*/
1155
1156
-/* TODO list:
1157
- * - See TODO comments in code.
1158
- */
1159
-
1160
-/* Marker for missing code. */
1161
-#define TODO() \
1162
- do { \
1163
- fprintf(stderr, "TODO %s:%u: %s()\n", \
1164
- __FILE__, __LINE__, __func__); \
1165
- tcg_abort(); \
1166
- } while (0)
1167
-
1168
-/* Bitfield n...m (in 32 bit value). */
1169
-#define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
1170
+#include "../tcg-pool.c.inc"
1171
1172
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
1173
{
1174
@@ -XXX,XX +XXX,XX @@ static const char *const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
1175
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
1176
intptr_t value, intptr_t addend)
1177
{
1178
- /* tcg_out_reloc always uses the same type, addend. */
1179
- tcg_debug_assert(type == sizeof(tcg_target_long));
1180
+ intptr_t diff = value - (intptr_t)(code_ptr + 1);
1181
+
1182
tcg_debug_assert(addend == 0);
1183
- tcg_debug_assert(value != 0);
1184
- if (TCG_TARGET_REG_BITS == 32) {
1185
- tcg_patch32(code_ptr, value);
1186
- } else {
1187
- tcg_patch64(code_ptr, value);
1188
- }
1189
- return true;
1190
-}
1191
-
1192
-/* Write value (native size). */
1193
-static void tcg_out_i(TCGContext *s, tcg_target_ulong v)
1194
-{
1195
- if (TCG_TARGET_REG_BITS == 32) {
1196
- tcg_out32(s, v);
1197
- } else {
1198
- tcg_out64(s, v);
1199
- }
1200
-}
1201
-
1202
-/* Write opcode. */
1203
-static void tcg_out_op_t(TCGContext *s, TCGOpcode op)
1204
-{
1205
- tcg_out8(s, op);
1206
- tcg_out8(s, 0);
1207
-}
1208
-
1209
-/* Write register. */
1210
-static void tcg_out_r(TCGContext *s, TCGArg t0)
1211
-{
1212
- tcg_debug_assert(t0 < TCG_TARGET_NB_REGS);
1213
- tcg_out8(s, t0);
1214
-}
1215
-
1216
-/* Write label. */
1217
-static void tci_out_label(TCGContext *s, TCGLabel *label)
1218
-{
1219
- if (label->has_value) {
1220
- tcg_out_i(s, label->u.value);
1221
- tcg_debug_assert(label->u.value);
1222
- } else {
1223
- tcg_out_reloc(s, s->code_ptr, sizeof(tcg_target_ulong), label, 0);
1224
- s->code_ptr += sizeof(tcg_target_ulong);
1225
+ tcg_debug_assert(type == 20);
1226
+
1227
+ if (diff == sextract32(diff, 0, type)) {
1228
+ tcg_patch32(code_ptr, deposit32(*code_ptr, 32 - type, type, diff));
1229
+ return true;
1230
}
1231
+ return false;
1232
}
1233
1234
static void stack_bounds_check(TCGReg base, target_long offset)
1235
@@ -XXX,XX +XXX,XX @@ static void stack_bounds_check(TCGReg base, target_long offset)
1236
1237
static void tcg_out_op_l(TCGContext *s, TCGOpcode op, TCGLabel *l0)
1238
{
1239
- uint8_t *old_code_ptr = s->code_ptr;
1240
+ tcg_insn_unit insn = 0;
1241
1242
- tcg_out_op_t(s, op);
1243
- tci_out_label(s, l0);
1244
-
1245
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1246
+ tcg_out_reloc(s, s->code_ptr, 20, l0, 0);
1247
+ insn = deposit32(insn, 0, 8, op);
1248
+ tcg_out32(s, insn);
1249
}
1250
1251
static void tcg_out_op_p(TCGContext *s, TCGOpcode op, void *p0)
1252
{
1253
- uint8_t *old_code_ptr = s->code_ptr;
1254
+ tcg_insn_unit insn = 0;
1255
+ intptr_t diff;
1256
1257
- tcg_out_op_t(s, op);
1258
- tcg_out_i(s, (uintptr_t)p0);
1259
-
1260
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1261
+ /* Special case for exit_tb: map null -> 0. */
1262
+ if (p0 == NULL) {
1263
+ diff = 0;
1264
+ } else {
1265
+ diff = p0 - (void *)(s->code_ptr + 1);
1266
+ tcg_debug_assert(diff != 0);
1267
+ if (diff != sextract32(diff, 0, 20)) {
1268
+ tcg_raise_tb_overflow(s);
1269
+ }
1270
+ }
1271
+ insn = deposit32(insn, 0, 8, op);
1272
+ insn = deposit32(insn, 12, 20, diff);
1273
+ tcg_out32(s, insn);
1274
}
1275
1276
static void tcg_out_op_v(TCGContext *s, TCGOpcode op)
1277
{
1278
- uint8_t *old_code_ptr = s->code_ptr;
1279
-
1280
- tcg_out_op_t(s, op);
1281
-
1282
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1283
+ tcg_out32(s, (uint8_t)op);
1284
}
1285
1286
static void tcg_out_op_ri(TCGContext *s, TCGOpcode op, TCGReg r0, int32_t i1)
1287
{
1288
- uint8_t *old_code_ptr = s->code_ptr;
1289
+ tcg_insn_unit insn = 0;
1290
1291
- tcg_out_op_t(s, op);
1292
- tcg_out_r(s, r0);
1293
- tcg_out32(s, i1);
1294
-
1295
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1296
+ tcg_debug_assert(i1 == sextract32(i1, 0, 20));
1297
+ insn = deposit32(insn, 0, 8, op);
1298
+ insn = deposit32(insn, 8, 4, r0);
1299
+ insn = deposit32(insn, 12, 20, i1);
1300
+ tcg_out32(s, insn);
1301
}
1302
1303
-#if TCG_TARGET_REG_BITS == 64
1304
-static void tcg_out_op_rI(TCGContext *s, TCGOpcode op,
1305
- TCGReg r0, uint64_t i1)
1306
-{
1307
- uint8_t *old_code_ptr = s->code_ptr;
1308
-
1309
- tcg_out_op_t(s, op);
1310
- tcg_out_r(s, r0);
1311
- tcg_out64(s, i1);
1312
-
1313
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1314
-}
1315
-#endif
1316
-
1317
static void tcg_out_op_rl(TCGContext *s, TCGOpcode op, TCGReg r0, TCGLabel *l1)
1318
{
1319
- uint8_t *old_code_ptr = s->code_ptr;
1320
+ tcg_insn_unit insn = 0;
1321
1322
- tcg_out_op_t(s, op);
1323
- tcg_out_r(s, r0);
1324
- tci_out_label(s, l1);
1325
-
1326
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1327
+ tcg_out_reloc(s, s->code_ptr, 20, l1, 0);
1328
+ insn = deposit32(insn, 0, 8, op);
1329
+ insn = deposit32(insn, 8, 4, r0);
1330
+ tcg_out32(s, insn);
1331
}
1332
1333
static void tcg_out_op_rr(TCGContext *s, TCGOpcode op, TCGReg r0, TCGReg r1)
1334
{
1335
- uint8_t *old_code_ptr = s->code_ptr;
1336
+ tcg_insn_unit insn = 0;
1337
1338
- tcg_out_op_t(s, op);
1339
- tcg_out_r(s, r0);
1340
- tcg_out_r(s, r1);
1341
-
1342
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1343
+ insn = deposit32(insn, 0, 8, op);
1344
+ insn = deposit32(insn, 8, 4, r0);
1345
+ insn = deposit32(insn, 12, 4, r1);
1346
+ tcg_out32(s, insn);
1347
}
1348
1349
static void tcg_out_op_rrm(TCGContext *s, TCGOpcode op,
1350
TCGReg r0, TCGReg r1, TCGArg m2)
1351
{
1352
- uint8_t *old_code_ptr = s->code_ptr;
1353
+ tcg_insn_unit insn = 0;
1354
1355
- tcg_out_op_t(s, op);
1356
- tcg_out_r(s, r0);
1357
- tcg_out_r(s, r1);
1358
- tcg_out32(s, m2);
1359
-
1360
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1361
+ tcg_debug_assert(m2 == extract32(m2, 0, 12));
1362
+ insn = deposit32(insn, 0, 8, op);
1363
+ insn = deposit32(insn, 8, 4, r0);
1364
+ insn = deposit32(insn, 12, 4, r1);
1365
+ insn = deposit32(insn, 20, 12, m2);
1366
+ tcg_out32(s, insn);
1367
}
1368
1369
static void tcg_out_op_rrr(TCGContext *s, TCGOpcode op,
1370
TCGReg r0, TCGReg r1, TCGReg r2)
1371
{
1372
- uint8_t *old_code_ptr = s->code_ptr;
1373
+ tcg_insn_unit insn = 0;
1374
1375
- tcg_out_op_t(s, op);
1376
- tcg_out_r(s, r0);
1377
- tcg_out_r(s, r1);
1378
- tcg_out_r(s, r2);
1379
-
1380
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1381
+ insn = deposit32(insn, 0, 8, op);
1382
+ insn = deposit32(insn, 8, 4, r0);
1383
+ insn = deposit32(insn, 12, 4, r1);
1384
+ insn = deposit32(insn, 16, 4, r2);
1385
+ tcg_out32(s, insn);
1386
}
1387
1388
static void tcg_out_op_rrs(TCGContext *s, TCGOpcode op,
1389
TCGReg r0, TCGReg r1, intptr_t i2)
1390
{
1391
- uint8_t *old_code_ptr = s->code_ptr;
1392
+ tcg_insn_unit insn = 0;
1393
1394
- tcg_out_op_t(s, op);
1395
- tcg_out_r(s, r0);
1396
- tcg_out_r(s, r1);
1397
- tcg_debug_assert(i2 == (int32_t)i2);
1398
- tcg_out32(s, i2);
1399
-
1400
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1401
+ tcg_debug_assert(i2 == sextract32(i2, 0, 16));
1402
+ insn = deposit32(insn, 0, 8, op);
1403
+ insn = deposit32(insn, 8, 4, r0);
1404
+ insn = deposit32(insn, 12, 4, r1);
1405
+ insn = deposit32(insn, 16, 16, i2);
1406
+ tcg_out32(s, insn);
1407
}
1408
1409
static void tcg_out_op_rrrc(TCGContext *s, TCGOpcode op,
1410
TCGReg r0, TCGReg r1, TCGReg r2, TCGCond c3)
1411
{
1412
- uint8_t *old_code_ptr = s->code_ptr;
1413
+ tcg_insn_unit insn = 0;
1414
1415
- tcg_out_op_t(s, op);
1416
- tcg_out_r(s, r0);
1417
- tcg_out_r(s, r1);
1418
- tcg_out_r(s, r2);
1419
- tcg_out8(s, c3);
1420
-
1421
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1422
+ insn = deposit32(insn, 0, 8, op);
1423
+ insn = deposit32(insn, 8, 4, r0);
1424
+ insn = deposit32(insn, 12, 4, r1);
1425
+ insn = deposit32(insn, 16, 4, r2);
1426
+ insn = deposit32(insn, 20, 4, c3);
1427
+ tcg_out32(s, insn);
1428
}
1429
1430
static void tcg_out_op_rrrm(TCGContext *s, TCGOpcode op,
1431
TCGReg r0, TCGReg r1, TCGReg r2, TCGArg m3)
1432
{
1433
- uint8_t *old_code_ptr = s->code_ptr;
1434
+ tcg_insn_unit insn = 0;
1435
1436
- tcg_out_op_t(s, op);
1437
- tcg_out_r(s, r0);
1438
- tcg_out_r(s, r1);
1439
- tcg_out_r(s, r2);
1440
- tcg_out32(s, m3);
1441
-
1442
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1443
+ tcg_debug_assert(m3 == extract32(m3, 0, 12));
1444
+ insn = deposit32(insn, 0, 8, op);
1445
+ insn = deposit32(insn, 8, 4, r0);
1446
+ insn = deposit32(insn, 12, 4, r1);
1447
+ insn = deposit32(insn, 16, 4, r2);
1448
+ insn = deposit32(insn, 20, 12, m3);
1449
+ tcg_out32(s, insn);
1450
}
1451
1452
static void tcg_out_op_rrrbb(TCGContext *s, TCGOpcode op, TCGReg r0,
1453
TCGReg r1, TCGReg r2, uint8_t b3, uint8_t b4)
1454
{
1455
- uint8_t *old_code_ptr = s->code_ptr;
1456
+ tcg_insn_unit insn = 0;
1457
1458
- tcg_out_op_t(s, op);
1459
- tcg_out_r(s, r0);
1460
- tcg_out_r(s, r1);
1461
- tcg_out_r(s, r2);
1462
- tcg_out8(s, b3);
1463
- tcg_out8(s, b4);
1464
-
1465
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1466
+ tcg_debug_assert(b3 == extract32(b3, 0, 6));
1467
+ tcg_debug_assert(b4 == extract32(b4, 0, 6));
1468
+ insn = deposit32(insn, 0, 8, op);
1469
+ insn = deposit32(insn, 8, 4, r0);
1470
+ insn = deposit32(insn, 12, 4, r1);
1471
+ insn = deposit32(insn, 16, 4, r2);
1472
+ insn = deposit32(insn, 20, 6, b3);
1473
+ insn = deposit32(insn, 26, 6, b4);
1474
+ tcg_out32(s, insn);
1475
}
1476
1477
-static void tcg_out_op_rrrrm(TCGContext *s, TCGOpcode op, TCGReg r0,
1478
- TCGReg r1, TCGReg r2, TCGReg r3, TCGArg m4)
1479
+static void tcg_out_op_rrrrr(TCGContext *s, TCGOpcode op, TCGReg r0,
1480
+ TCGReg r1, TCGReg r2, TCGReg r3, TCGReg r4)
1481
{
1482
- uint8_t *old_code_ptr = s->code_ptr;
1483
+ tcg_insn_unit insn = 0;
1484
1485
- tcg_out_op_t(s, op);
1486
- tcg_out_r(s, r0);
1487
- tcg_out_r(s, r1);
1488
- tcg_out_r(s, r2);
1489
- tcg_out_r(s, r3);
1490
- tcg_out32(s, m4);
1491
-
1492
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1493
+ insn = deposit32(insn, 0, 8, op);
1494
+ insn = deposit32(insn, 8, 4, r0);
1495
+ insn = deposit32(insn, 12, 4, r1);
1496
+ insn = deposit32(insn, 16, 4, r2);
1497
+ insn = deposit32(insn, 20, 4, r3);
1498
+ insn = deposit32(insn, 24, 4, r4);
1499
+ tcg_out32(s, insn);
1500
}
1501
1502
#if TCG_TARGET_REG_BITS == 32
1503
static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
1504
TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3)
1505
{
1506
- uint8_t *old_code_ptr = s->code_ptr;
1507
+ tcg_insn_unit insn = 0;
1508
1509
- tcg_out_op_t(s, op);
1510
- tcg_out_r(s, r0);
1511
- tcg_out_r(s, r1);
1512
- tcg_out_r(s, r2);
1513
- tcg_out_r(s, r3);
1514
-
1515
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1516
+ insn = deposit32(insn, 0, 8, op);
1517
+ insn = deposit32(insn, 8, 4, r0);
1518
+ insn = deposit32(insn, 12, 4, r1);
1519
+ insn = deposit32(insn, 16, 4, r2);
1520
+ insn = deposit32(insn, 20, 4, r3);
1521
+ tcg_out32(s, insn);
1522
}
1523
1524
static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
1525
TCGReg r0, TCGReg r1, TCGReg r2,
1526
TCGReg r3, TCGReg r4, TCGCond c5)
1527
{
1528
- uint8_t *old_code_ptr = s->code_ptr;
1529
+ tcg_insn_unit insn = 0;
1530
1531
- tcg_out_op_t(s, op);
1532
- tcg_out_r(s, r0);
1533
- tcg_out_r(s, r1);
1534
- tcg_out_r(s, r2);
1535
- tcg_out_r(s, r3);
1536
- tcg_out_r(s, r4);
1537
- tcg_out8(s, c5);
1538
-
1539
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1540
+ insn = deposit32(insn, 0, 8, op);
1541
+ insn = deposit32(insn, 8, 4, r0);
1542
+ insn = deposit32(insn, 12, 4, r1);
1543
+ insn = deposit32(insn, 16, 4, r2);
1544
+ insn = deposit32(insn, 20, 4, r3);
1545
+ insn = deposit32(insn, 24, 4, r4);
1546
+ insn = deposit32(insn, 28, 4, c5);
1547
+ tcg_out32(s, insn);
1548
}
1549
1550
static void tcg_out_op_rrrrrr(TCGContext *s, TCGOpcode op,
1551
TCGReg r0, TCGReg r1, TCGReg r2,
1552
TCGReg r3, TCGReg r4, TCGReg r5)
1553
{
1554
- uint8_t *old_code_ptr = s->code_ptr;
1555
+ tcg_insn_unit insn = 0;
1556
1557
- tcg_out_op_t(s, op);
1558
- tcg_out_r(s, r0);
1559
- tcg_out_r(s, r1);
1560
- tcg_out_r(s, r2);
1561
- tcg_out_r(s, r3);
1562
- tcg_out_r(s, r4);
1563
- tcg_out_r(s, r5);
1564
-
1565
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1566
+ insn = deposit32(insn, 0, 8, op);
1567
+ insn = deposit32(insn, 8, 4, r0);
1568
+ insn = deposit32(insn, 12, 4, r1);
1569
+ insn = deposit32(insn, 16, 4, r2);
1570
+ insn = deposit32(insn, 20, 4, r3);
1571
+ insn = deposit32(insn, 24, 4, r4);
1572
+ insn = deposit32(insn, 28, 4, r5);
1573
+ tcg_out32(s, insn);
1574
}
1575
#endif
1576
1577
+static void tcg_out_ldst(TCGContext *s, TCGOpcode op, TCGReg val,
1578
+ TCGReg base, intptr_t offset)
1579
+{
1580
+ stack_bounds_check(base, offset);
1581
+ if (offset != sextract32(offset, 0, 16)) {
1582
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, offset);
1583
+ tcg_out_op_rrr(s, (TCG_TARGET_REG_BITS == 32
1584
+ ? INDEX_op_add_i32 : INDEX_op_add_i64),
1585
+ TCG_REG_TMP, TCG_REG_TMP, base);
1586
+ base = TCG_REG_TMP;
1587
+ offset = 0;
1588
+ }
1589
+ tcg_out_op_rrs(s, op, val, base, offset);
1590
+}
1591
+
1592
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg val, TCGReg base,
1593
intptr_t offset)
1594
{
1595
- stack_bounds_check(base, offset);
1596
switch (type) {
1597
case TCG_TYPE_I32:
1598
- tcg_out_op_rrs(s, INDEX_op_ld_i32, val, base, offset);
1599
+ tcg_out_ldst(s, INDEX_op_ld_i32, val, base, offset);
1600
break;
1601
#if TCG_TARGET_REG_BITS == 64
1602
case TCG_TYPE_I64:
1603
- tcg_out_op_rrs(s, INDEX_op_ld_i64, val, base, offset);
1604
+ tcg_out_ldst(s, INDEX_op_ld_i64, val, base, offset);
1605
break;
1606
#endif
1607
default:
1608
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type,
1609
{
1610
switch (type) {
1611
case TCG_TYPE_I32:
1612
- tcg_out_op_ri(s, INDEX_op_tci_movi_i32, ret, arg);
1613
- break;
1614
#if TCG_TARGET_REG_BITS == 64
1615
+ arg = (int32_t)arg;
1616
+ /* fall through */
1617
case TCG_TYPE_I64:
1618
- tcg_out_op_rI(s, INDEX_op_tci_movi_i64, ret, arg);
1619
- break;
1620
#endif
1621
+ break;
1622
default:
1623
g_assert_not_reached();
1624
}
1625
+
1626
+ if (arg == sextract32(arg, 0, 20)) {
1627
+ tcg_out_op_ri(s, INDEX_op_tci_movi, ret, arg);
1628
+ } else {
1629
+ tcg_insn_unit insn = 0;
1630
+
1631
+ new_pool_label(s, arg, 20, s->code_ptr, 0);
1632
+ insn = deposit32(insn, 0, 8, INDEX_op_tci_movl);
1633
+ insn = deposit32(insn, 8, 4, ret);
1634
+ tcg_out32(s, insn);
1635
+ }
1636
}
1637
1638
static void tcg_out_call(TCGContext *s, const tcg_insn_unit *func,
1639
ffi_cif *cif)
1640
{
1641
- uint8_t *old_code_ptr = s->code_ptr;
1642
+ tcg_insn_unit insn = 0;
1643
uint8_t which;
1644
1645
if (cif->rtype == &ffi_type_void) {
1646
@@ -XXX,XX +XXX,XX @@ static void tcg_out_call(TCGContext *s, const tcg_insn_unit *func,
1647
tcg_debug_assert(cif->rtype->size == 8);
1648
which = 2;
1649
}
1650
- tcg_out_op_t(s, INDEX_op_call);
1651
- tcg_out8(s, which);
1652
- tcg_out_i(s, (uintptr_t)func);
1653
- tcg_out_i(s, (uintptr_t)cif);
1654
-
1655
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
1656
+ new_pool_l2(s, 20, s->code_ptr, 0, (uintptr_t)func, (uintptr_t)cif);
1657
+ insn = deposit32(insn, 0, 8, INDEX_op_call);
1658
+ insn = deposit32(insn, 8, 4, which);
1659
+ tcg_out32(s, insn);
1660
}
1661
1662
#if TCG_TARGET_REG_BITS == 64
1663
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
1664
case INDEX_op_st_i32:
1665
CASE_64(st32)
1666
CASE_64(st)
1667
- stack_bounds_check(args[1], args[2]);
1668
- tcg_out_op_rrs(s, opc, args[0], args[1], args[2]);
1669
+ tcg_out_ldst(s, opc, args[0], args[1], args[2]);
1670
break;
1671
1672
CASE_32_64(add)
1673
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
1674
} else if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
1675
tcg_out_op_rrrm(s, opc, args[0], args[1], args[2], args[3]);
1676
} else {
1677
- tcg_out_op_rrrrm(s, opc, args[0], args[1],
1678
- args[2], args[3], args[4]);
1679
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[4]);
1680
+ tcg_out_op_rrrrr(s, opc, args[0], args[1],
1681
+ args[2], args[3], TCG_REG_TMP);
1682
}
1683
break;
1684
1685
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
1686
return ct & TCG_CT_CONST;
1687
}
1688
1689
+static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
1690
+{
1691
+ memset(p, 0, sizeof(*p) * count);
1692
+}
1693
+
1694
static void tcg_target_init(TCGContext *s)
1695
{
1696
#if defined(CONFIG_DEBUG_TCG_INTERPRETER)
1697
diff --git a/tcg/tci/README b/tcg/tci/README
1698
index XXXXXXX..XXXXXXX 100644
1699
--- a/tcg/tci/README
1700
+++ b/tcg/tci/README
1701
@@ -XXX,XX +XXX,XX @@ This is what TCI (Tiny Code Interpreter) does.
1702
Like each TCG host frontend, TCI implements the code generator in
1703
tcg-target.c.inc, tcg-target.h. Both files are in directory tcg/tci.
1704
1705
-The additional file tcg/tci.c adds the interpreter.
1706
+The additional file tcg/tci.c adds the interpreter and disassembler.
1707
1708
-The bytecode consists of opcodes (same numeric values as those used by
1709
-TCG), command length and arguments of variable size and number.
1710
+The bytecode consists of opcodes (with only a few exceptions, with
1711
+the same same numeric values and semantics as used by TCG), and up
1712
+to six arguments packed into a 32-bit integer. See comments in tci.c
1713
+for details on the encoding.
1714
1715
3) Usage
1716
1717
@@ -XXX,XX +XXX,XX @@ suggest using this option. Setting it automatically would need
1718
additional code in configure which must be fixed when new native TCG
1719
implementations are added.
1720
1721
-System emulation should work on any 32 or 64 bit host.
1722
-User mode emulation might work. Maybe a new linker script (*.ld)
1723
-is needed. Byte order might be wrong (on big endian hosts)
1724
-and need fixes in configure.
1725
-
1726
For hosts with native TCG, the interpreter TCI can be enabled by
1727
1728
configure --enable-tcg-interpreter
1729
@@ -XXX,XX +XXX,XX @@ u1 = linux-user-test works
1730
in the interpreter. These opcodes raise a runtime exception, so it is
1731
possible to see where code must be added.
1732
1733
-* The pseudo code is not optimized and still ugly. For hosts with special
1734
- alignment requirements, it needs some fixes (maybe aligned bytecode
1735
- would also improve speed for hosts which support byte alignment).
1736
-
1737
-* A better disassembler for the pseudo code would be nice (a very primitive
1738
- disassembler is included in tcg-target.c.inc).
1739
-
1740
* It might be useful to have a runtime option which selects the native TCG
1741
or TCI, so QEMU would have to include two TCGs. Today, selecting TCI
1742
is a configure option, so you need two compilations of QEMU.
1743
--
69
--
1744
2.25.1
70
2.34.1
1745
1746
diff view generated by jsdifflib
1
We should not be aligning the offset in temp_allocate_frame,
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
2
because the odd offset produces an aligned address in the end.
2
3
Instead, pass the logical offset into tcg_set_frame and add
3
i386 and s390x implementations of op_add2 require an earlyclobber,
4
the stack bias last.
4
which is currently missing. This breaks VCKSM in s390x guests. E.g., on
5
x86_64 the following op:
6
7
add2_i32 tmp2,tmp3,tmp2,tmp3,tmp3,tmp2 dead: 0 2 3 4 5 pref=none,0xffff
8
9
is translated to:
10
11
addl %ebx, %r12d
12
adcl %r12d, %ebx
13
14
Introduce a new C_N1_O1_I4 constraint, and make sure that earlyclobber
15
of aliased outputs is honored.
5
16
6
Cc: qemu-stable@nongnu.org
17
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Fixes: 82790a870992 ("tcg: Add markup for output requires new register")
19
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-Id: <20230719221310.1968845-7-iii@linux.ibm.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
22
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
23
---
10
tcg/tcg.c | 9 +++------
24
tcg/i386/tcg-target-con-set.h | 5 ++++-
11
tcg/sparc/tcg-target.c.inc | 16 ++++++++++------
25
tcg/s390x/tcg-target-con-set.h | 8 +++++---
12
2 files changed, 13 insertions(+), 12 deletions(-)
26
tcg/tcg.c | 8 +++++++-
27
tcg/i386/tcg-target.c.inc | 2 +-
28
tcg/s390x/tcg-target.c.inc | 4 ++--
29
5 files changed, 19 insertions(+), 8 deletions(-)
13
30
31
diff --git a/tcg/i386/tcg-target-con-set.h b/tcg/i386/tcg-target-con-set.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tcg/i386/tcg-target-con-set.h
34
+++ b/tcg/i386/tcg-target-con-set.h
35
@@ -XXX,XX +XXX,XX @@
36
*
37
* C_N1_Im(...) defines a constraint set with 1 output and <m> inputs,
38
* except that the output must use a new register.
39
+ *
40
+ * C_Nn_Om_Ik(...) defines a constraint set with <n + m> outputs and <k>
41
+ * inputs, except that the first <n> outputs must use new registers.
42
*/
43
C_O0_I1(r)
44
C_O0_I2(L, L)
45
@@ -XXX,XX +XXX,XX @@ C_O2_I1(r, r, L)
46
C_O2_I2(a, d, a, r)
47
C_O2_I2(r, r, L, L)
48
C_O2_I3(a, d, 0, 1, r)
49
-C_O2_I4(r, r, 0, 1, re, re)
50
+C_N1_O1_I4(r, r, 0, 1, re, re)
51
diff --git a/tcg/s390x/tcg-target-con-set.h b/tcg/s390x/tcg-target-con-set.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tcg/s390x/tcg-target-con-set.h
54
+++ b/tcg/s390x/tcg-target-con-set.h
55
@@ -XXX,XX +XXX,XX @@
56
* C_On_Im(...) defines a constraint set with <n> outputs and <m> inputs.
57
* Each operand should be a sequence of constraint letters as defined by
58
* tcg-target-con-str.h; the constraint combination is inclusive or.
59
+ *
60
+ * C_Nn_Om_Ik(...) defines a constraint set with <n + m> outputs and <k>
61
+ * inputs, except that the first <n> outputs must use new registers.
62
*/
63
C_O0_I1(r)
64
C_O0_I2(r, r)
65
@@ -XXX,XX +XXX,XX @@ C_O2_I1(o, m, r)
66
C_O2_I2(o, m, 0, r)
67
C_O2_I2(o, m, r, r)
68
C_O2_I3(o, m, 0, 1, r)
69
-C_O2_I4(r, r, 0, 1, rA, r)
70
-C_O2_I4(r, r, 0, 1, ri, r)
71
-C_O2_I4(r, r, 0, 1, r, r)
72
+C_N1_O1_I4(r, r, 0, 1, ri, r)
73
+C_N1_O1_I4(r, r, 0, 1, rA, r)
14
diff --git a/tcg/tcg.c b/tcg/tcg.c
74
diff --git a/tcg/tcg.c b/tcg/tcg.c
15
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/tcg.c
76
--- a/tcg/tcg.c
17
+++ b/tcg/tcg.c
77
+++ b/tcg/tcg.c
18
@@ -XXX,XX +XXX,XX @@ static void check_regs(TCGContext *s)
78
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movext3(TCGContext *s, const TCGMovExtend *i1,
19
79
#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2),
20
static void temp_allocate_frame(TCGContext *s, TCGTemp *ts)
80
#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3),
21
{
81
#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4),
22
-#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
82
+#define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_n1_o1_i4_, O1, O2, I1, I2, I3, I4),
23
- /* Sparc64 stack is accessed with offset of 2047 */
83
24
- s->current_frame_offset = (s->current_frame_offset +
84
typedef enum {
25
- (tcg_target_long)sizeof(tcg_target_long) - 1) &
85
#include "tcg-target-con-set.h"
26
- ~(sizeof(tcg_target_long) - 1);
86
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode);
27
-#endif
87
#undef C_O2_I2
28
if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
88
#undef C_O2_I3
29
s->frame_end) {
89
#undef C_O2_I4
30
tcg_abort();
90
+#undef C_N1_O1_I4
31
}
91
32
ts->mem_offset = s->current_frame_offset;
92
/* Put all of the constraint sets into an array, indexed by the enum. */
33
+#if defined(__sparc__)
93
34
+ ts->mem_offset += TCG_TARGET_STACK_BIAS;
94
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode);
35
+#endif
95
#define C_O2_I2(O1, O2, I1, I2) { .args_ct_str = { #O1, #O2, #I1, #I2 } },
36
ts->mem_base = s->frame_temp;
96
#define C_O2_I3(O1, O2, I1, I2, I3) { .args_ct_str = { #O1, #O2, #I1, #I2, #I3 } },
37
ts->mem_allocated = 1;
97
#define C_O2_I4(O1, O2, I1, I2, I3, I4) { .args_ct_str = { #O1, #O2, #I1, #I2, #I3, #I4 } },
38
s->current_frame_offset += sizeof(tcg_target_long);
98
+#define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) { .args_ct_str = { "&" #O1, #O2, #I1, #I2, #I3, #I4 } },
39
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
99
100
static const TCGTargetOpDef constraint_sets[] = {
101
#include "tcg-target-con-set.h"
102
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef constraint_sets[] = {
103
#undef C_O2_I2
104
#undef C_O2_I3
105
#undef C_O2_I4
106
+#undef C_N1_O1_I4
107
108
/* Expand the enumerator to be returned from tcg_target_op_def(). */
109
110
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef constraint_sets[] = {
111
#define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2)
112
#define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3)
113
#define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, I4)
114
+#define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_n1_o1_i4_, O1, O2, I1, I2, I3, I4)
115
116
#include "tcg-target.c.inc"
117
118
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
119
* dead after the instruction, we must allocate a new
120
* register and move it.
121
*/
122
- if (temp_readonly(ts) || !IS_DEAD_ARG(i)) {
123
+ if (temp_readonly(ts) || !IS_DEAD_ARG(i)
124
+ || def->args_ct[arg_ct->alias_index].newreg) {
125
allocate_new_reg = true;
126
} else if (ts->val_type == TEMP_VAL_REG) {
127
/*
128
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
40
index XXXXXXX..XXXXXXX 100644
129
index XXXXXXX..XXXXXXX 100644
41
--- a/tcg/sparc/tcg-target.c.inc
130
--- a/tcg/i386/tcg-target.c.inc
42
+++ b/tcg/sparc/tcg-target.c.inc
131
+++ b/tcg/i386/tcg-target.c.inc
43
@@ -XXX,XX +XXX,XX @@ static void tcg_target_qemu_prologue(TCGContext *s)
132
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
44
{
133
case INDEX_op_add2_i64:
45
int tmp_buf_size, frame_size;
134
case INDEX_op_sub2_i32:
46
135
case INDEX_op_sub2_i64:
47
- /* The TCG temp buffer is at the top of the frame, immediately
136
- return C_O2_I4(r, r, 0, 1, re, re);
48
- below the frame pointer. */
137
+ return C_N1_O1_I4(r, r, 0, 1, re, re);
49
+ /*
138
50
+ * The TCG temp buffer is at the top of the frame, immediately
139
case INDEX_op_ctz_i32:
51
+ * below the frame pointer. Use the logical (aligned) offset here;
140
case INDEX_op_ctz_i64:
52
+ * the stack bias is applied in temp_allocate_frame().
141
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
53
+ */
142
index XXXXXXX..XXXXXXX 100644
54
tmp_buf_size = CPU_TEMP_BUF_NLONGS * (int)sizeof(long);
143
--- a/tcg/s390x/tcg-target.c.inc
55
- tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_STACK_BIAS - tmp_buf_size,
144
+++ b/tcg/s390x/tcg-target.c.inc
56
- tmp_buf_size);
145
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
57
+ tcg_set_frame(s, TCG_REG_I6, -tmp_buf_size, tmp_buf_size);
146
58
147
case INDEX_op_add2_i32:
59
- /* TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
148
case INDEX_op_sub2_i32:
60
- otherwise the minimal frame usable by callees. */
149
- return C_O2_I4(r, r, 0, 1, ri, r);
61
+ /*
150
+ return C_N1_O1_I4(r, r, 0, 1, ri, r);
62
+ * TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
151
63
+ * otherwise the minimal frame usable by callees.
152
case INDEX_op_add2_i64:
64
+ */
153
case INDEX_op_sub2_i64:
65
frame_size = TCG_TARGET_CALL_STACK_OFFSET - TCG_TARGET_STACK_BIAS;
154
- return C_O2_I4(r, r, 0, 1, rA, r);
66
frame_size += TCG_STATIC_CALL_ARGS_SIZE + tmp_buf_size;
155
+ return C_N1_O1_I4(r, r, 0, 1, rA, r);
67
frame_size += TCG_TARGET_STACK_ALIGN - 1;
156
157
case INDEX_op_st_vec:
158
return C_O0_I2(v, r);
68
--
159
--
69
2.25.1
160
2.34.1
70
71
diff view generated by jsdifflib
1
We had a single ATOMIC_MMU_LOOKUP macro that probed for
1
From: Anton Johansson <anjo@rev.ng>
2
read+write on all atomic ops. This is incorrect for
3
plain atomic load and atomic store.
4
2
5
For user-only, we rely on the host page permissions.
3
In replacing target_ulong with vaddr and TARGET_FMT_lx with VADDR_PRIx,
4
the zero-padding of TARGET_FMT_lx got lost. Readd 16-wide zero-padding
5
for logging consistency.
6
6
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/390
7
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Anton Johansson <anjo@rev.ng>
9
Message-Id: <20230713120746.26897-1-anjo@rev.ng>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
12
---
11
accel/tcg/atomic_template.h | 24 +++++-----
13
accel/tcg/cputlb.c | 20 ++++++++++----------
12
accel/tcg/cputlb.c | 95 ++++++++++++++++++++++++++-----------
14
1 file changed, 10 insertions(+), 10 deletions(-)
13
accel/tcg/user-exec.c | 8 ++--
14
3 files changed, 83 insertions(+), 44 deletions(-)
15
15
16
diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/accel/tcg/atomic_template.h
19
+++ b/accel/tcg/atomic_template.h
20
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
21
ABI_TYPE cmpv, ABI_TYPE newv EXTRA_ARGS)
22
{
23
ATOMIC_MMU_DECLS;
24
- DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
25
+ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP_RW;
26
DATA_TYPE ret;
27
uint16_t info = trace_mem_build_info(SHIFT, false, 0, false,
28
ATOMIC_MMU_IDX);
29
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
30
ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
31
{
32
ATOMIC_MMU_DECLS;
33
- DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
34
+ DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP_R;
35
uint16_t info = trace_mem_build_info(SHIFT, false, 0, false,
36
ATOMIC_MMU_IDX);
37
38
@@ -XXX,XX +XXX,XX @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
39
ABI_TYPE val EXTRA_ARGS)
40
{
41
ATOMIC_MMU_DECLS;
42
- DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
43
+ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP_W;
44
uint16_t info = trace_mem_build_info(SHIFT, false, 0, true,
45
ATOMIC_MMU_IDX);
46
47
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
48
ABI_TYPE val EXTRA_ARGS)
49
{
50
ATOMIC_MMU_DECLS;
51
- DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
52
+ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP_RW;
53
DATA_TYPE ret;
54
uint16_t info = trace_mem_build_info(SHIFT, false, 0, false,
55
ATOMIC_MMU_IDX);
56
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
57
ABI_TYPE val EXTRA_ARGS) \
58
{ \
59
ATOMIC_MMU_DECLS; \
60
- DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
61
+ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP_RW; \
62
DATA_TYPE ret; \
63
uint16_t info = trace_mem_build_info(SHIFT, false, 0, false, \
64
ATOMIC_MMU_IDX); \
65
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
66
ABI_TYPE xval EXTRA_ARGS) \
67
{ \
68
ATOMIC_MMU_DECLS; \
69
- XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
70
+ XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP_RW; \
71
XDATA_TYPE cmp, old, new, val = xval; \
72
uint16_t info = trace_mem_build_info(SHIFT, false, 0, false, \
73
ATOMIC_MMU_IDX); \
74
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
75
ABI_TYPE cmpv, ABI_TYPE newv EXTRA_ARGS)
76
{
77
ATOMIC_MMU_DECLS;
78
- DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
79
+ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP_RW;
80
DATA_TYPE ret;
81
uint16_t info = trace_mem_build_info(SHIFT, false, MO_BSWAP, false,
82
ATOMIC_MMU_IDX);
83
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
84
ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
85
{
86
ATOMIC_MMU_DECLS;
87
- DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
88
+ DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP_R;
89
uint16_t info = trace_mem_build_info(SHIFT, false, MO_BSWAP, false,
90
ATOMIC_MMU_IDX);
91
92
@@ -XXX,XX +XXX,XX @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
93
ABI_TYPE val EXTRA_ARGS)
94
{
95
ATOMIC_MMU_DECLS;
96
- DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
97
+ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP_W;
98
uint16_t info = trace_mem_build_info(SHIFT, false, MO_BSWAP, true,
99
ATOMIC_MMU_IDX);
100
101
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
102
ABI_TYPE val EXTRA_ARGS)
103
{
104
ATOMIC_MMU_DECLS;
105
- DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
106
+ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP_RW;
107
ABI_TYPE ret;
108
uint16_t info = trace_mem_build_info(SHIFT, false, MO_BSWAP, false,
109
ATOMIC_MMU_IDX);
110
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
111
ABI_TYPE val EXTRA_ARGS) \
112
{ \
113
ATOMIC_MMU_DECLS; \
114
- DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
115
+ DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP_RW; \
116
DATA_TYPE ret; \
117
uint16_t info = trace_mem_build_info(SHIFT, false, MO_BSWAP, \
118
false, ATOMIC_MMU_IDX); \
119
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
120
ABI_TYPE xval EXTRA_ARGS) \
121
{ \
122
ATOMIC_MMU_DECLS; \
123
- XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
124
+ XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP_RW; \
125
XDATA_TYPE ldo, ldn, old, new, val = xval; \
126
uint16_t info = trace_mem_build_info(SHIFT, false, MO_BSWAP, \
127
false, ATOMIC_MMU_IDX); \
128
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
16
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
129
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
130
--- a/accel/tcg/cputlb.c
18
--- a/accel/tcg/cputlb.c
131
+++ b/accel/tcg/cputlb.c
19
+++ b/accel/tcg/cputlb.c
132
@@ -XXX,XX +XXX,XX @@ bool tlb_plugin_lookup(CPUState *cpu, target_ulong addr, int mmu_idx,
20
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_locked(CPUArchState *env, int midx, vaddr page)
133
21
134
#endif
22
/* Check if we need to flush due to large pages. */
135
23
if ((page & lp_mask) == lp_addr) {
136
-/* Probe for a read-modify-write atomic operation. Do not allow unaligned
24
- tlb_debug("forcing full flush midx %d (%"
137
- * operations, or io operations to proceed. Return the host address. */
25
- VADDR_PRIx "/%" VADDR_PRIx ")\n",
138
+/*
26
+ tlb_debug("forcing full flush midx %d (%016"
139
+ * Probe for an atomic operation. Do not allow unaligned operations,
27
+ VADDR_PRIx "/%016" VADDR_PRIx ")\n",
140
+ * or io operations to proceed. Return the host address.
28
midx, lp_addr, lp_mask);
141
+ *
29
tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
142
+ * @prot may be PAGE_READ, PAGE_WRITE, or PAGE_READ|PAGE_WRITE.
30
} else {
143
+ */
31
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_by_mmuidx_async_0(CPUState *cpu,
144
static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
32
145
- TCGMemOpIdx oi, uintptr_t retaddr)
33
assert_cpu_is_self(cpu);
146
+ TCGMemOpIdx oi, int size, int prot,
34
147
+ uintptr_t retaddr)
35
- tlb_debug("page addr: %" VADDR_PRIx " mmu_map:0x%x\n", addr, idxmap);
36
+ tlb_debug("page addr: %016" VADDR_PRIx " mmu_map:0x%x\n", addr, idxmap);
37
38
qemu_spin_lock(&env_tlb(env)->c.lock);
39
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
40
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_by_mmuidx_async_2(CPUState *cpu,
41
42
void tlb_flush_page_by_mmuidx(CPUState *cpu, vaddr addr, uint16_t idxmap)
148
{
43
{
149
size_t mmu_idx = get_mmuidx(oi);
44
- tlb_debug("addr: %" VADDR_PRIx " mmu_idx:%" PRIx16 "\n", addr, idxmap);
150
- uintptr_t index = tlb_index(env, mmu_idx, addr);
45
+ tlb_debug("addr: %016" VADDR_PRIx " mmu_idx:%" PRIx16 "\n", addr, idxmap);
151
- CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
46
152
- target_ulong tlb_addr = tlb_addr_write(tlbe);
47
/* This should already be page aligned */
153
MemOp mop = get_memop(oi);
48
addr &= TARGET_PAGE_MASK;
154
int a_bits = get_alignment_bits(mop);
49
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page(CPUState *cpu, vaddr addr)
155
- int s_bits = mop & MO_SIZE;
50
void tlb_flush_page_by_mmuidx_all_cpus(CPUState *src_cpu, vaddr addr,
156
+ uintptr_t index;
51
uint16_t idxmap)
157
+ CPUTLBEntry *tlbe;
52
{
158
+ target_ulong tlb_addr;
53
- tlb_debug("addr: %" VADDR_PRIx " mmu_idx:%"PRIx16"\n", addr, idxmap);
159
void *hostaddr;
54
+ tlb_debug("addr: %016" VADDR_PRIx " mmu_idx:%"PRIx16"\n", addr, idxmap);
160
55
161
/* Adjust the given return address. */
56
/* This should already be page aligned */
162
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
57
addr &= TARGET_PAGE_MASK;
163
}
58
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
164
59
vaddr addr,
165
/* Enforce qemu required alignment. */
60
uint16_t idxmap)
166
- if (unlikely(addr & ((1 << s_bits) - 1))) {
61
{
167
+ if (unlikely(addr & (size - 1))) {
62
- tlb_debug("addr: %" VADDR_PRIx " mmu_idx:%"PRIx16"\n", addr, idxmap);
168
/* We get here if guest alignment was not requested,
63
+ tlb_debug("addr: %016" VADDR_PRIx " mmu_idx:%"PRIx16"\n", addr, idxmap);
169
or was not enforced by cpu_unaligned_access above.
64
170
We might widen the access and emulate, but for now
65
/* This should already be page aligned */
171
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
66
addr &= TARGET_PAGE_MASK;
172
goto stop_the_world;
67
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_range_locked(CPUArchState *env, int midx,
173
}
68
*/
174
69
if (mask < f->mask || len > f->mask) {
175
+ index = tlb_index(env, mmu_idx, addr);
70
tlb_debug("forcing full flush midx %d ("
176
+ tlbe = tlb_entry(env, mmu_idx, addr);
71
- "%" VADDR_PRIx "/%" VADDR_PRIx "+%" VADDR_PRIx ")\n",
177
+
72
+ "%016" VADDR_PRIx "/%016" VADDR_PRIx "+%016" VADDR_PRIx ")\n",
178
/* Check TLB entry and enforce page permissions. */
73
midx, addr, mask, len);
179
- if (!tlb_hit(tlb_addr, addr)) {
74
tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
180
- if (!VICTIM_TLB_HIT(addr_write, addr)) {
75
return;
181
- tlb_fill(env_cpu(env), addr, 1 << s_bits, MMU_DATA_STORE,
76
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_range_locked(CPUArchState *env, int midx,
182
- mmu_idx, retaddr);
77
*/
183
- index = tlb_index(env, mmu_idx, addr);
78
if (((addr + len - 1) & d->large_page_mask) == d->large_page_addr) {
184
- tlbe = tlb_entry(env, mmu_idx, addr);
79
tlb_debug("forcing full flush midx %d ("
185
+ if (prot & PAGE_WRITE) {
80
- "%" VADDR_PRIx "/%" VADDR_PRIx ")\n",
186
+ tlb_addr = tlb_addr_write(tlbe);
81
+ "%016" VADDR_PRIx "/%016" VADDR_PRIx ")\n",
187
+ if (!tlb_hit(tlb_addr, addr)) {
82
midx, d->large_page_addr, d->large_page_mask);
188
+ if (!VICTIM_TLB_HIT(addr_write, addr)) {
83
tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
189
+ tlb_fill(env_cpu(env), addr, size,
84
return;
190
+ MMU_DATA_STORE, mmu_idx, retaddr);
85
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_range_by_mmuidx_async_0(CPUState *cpu,
191
+ index = tlb_index(env, mmu_idx, addr);
86
192
+ tlbe = tlb_entry(env, mmu_idx, addr);
87
assert_cpu_is_self(cpu);
193
+ }
88
194
+ tlb_addr = tlb_addr_write(tlbe) & ~TLB_INVALID_MASK;
89
- tlb_debug("range: %" VADDR_PRIx "/%u+%" VADDR_PRIx " mmu_map:0x%x\n",
195
+ }
90
+ tlb_debug("range: %016" VADDR_PRIx "/%u+%016" VADDR_PRIx " mmu_map:0x%x\n",
196
+
91
d.addr, d.bits, d.len, d.idxmap);
197
+ /* Let the guest notice RMW on a write-only page. */
92
198
+ if ((prot & PAGE_READ) &&
93
qemu_spin_lock(&env_tlb(env)->c.lock);
199
+ unlikely(tlbe->addr_read != (tlb_addr & ~TLB_NOTDIRTY))) {
94
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
200
+ tlb_fill(env_cpu(env), addr, size,
95
&xlat, &sz, full->attrs, &prot);
201
+ MMU_DATA_LOAD, mmu_idx, retaddr);
96
assert(sz >= TARGET_PAGE_SIZE);
202
+ /*
97
203
+ * Since we don't support reads and writes to different addresses,
98
- tlb_debug("vaddr=%" VADDR_PRIx " paddr=0x" HWADDR_FMT_plx
204
+ * and we do have the proper page loaded for write, this shouldn't
99
+ tlb_debug("vaddr=%016" VADDR_PRIx " paddr=0x" HWADDR_FMT_plx
205
+ * ever return. But just in case, handle via stop-the-world.
100
" prot=%x idx=%d\n",
206
+ */
101
addr, full->phys_addr, prot, mmu_idx);
207
+ goto stop_the_world;
102
208
+ }
209
+ } else /* if (prot & PAGE_READ) */ {
210
+ tlb_addr = tlbe->addr_read;
211
+ if (!tlb_hit(tlb_addr, addr)) {
212
+ if (!VICTIM_TLB_HIT(addr_write, addr)) {
213
+ tlb_fill(env_cpu(env), addr, size,
214
+ MMU_DATA_LOAD, mmu_idx, retaddr);
215
+ index = tlb_index(env, mmu_idx, addr);
216
+ tlbe = tlb_entry(env, mmu_idx, addr);
217
+ }
218
+ tlb_addr = tlbe->addr_read & ~TLB_INVALID_MASK;
219
}
220
- tlb_addr = tlb_addr_write(tlbe) & ~TLB_INVALID_MASK;
221
}
222
223
/* Notice an IO access or a needs-MMU-lookup access */
224
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
225
goto stop_the_world;
226
}
227
228
- /* Let the guest notice RMW on a write-only page. */
229
- if (unlikely(tlbe->addr_read != (tlb_addr & ~TLB_NOTDIRTY))) {
230
- tlb_fill(env_cpu(env), addr, 1 << s_bits, MMU_DATA_LOAD,
231
- mmu_idx, retaddr);
232
- /* Since we don't support reads and writes to different addresses,
233
- and we do have the proper page loaded for write, this shouldn't
234
- ever return. But just in case, handle via stop-the-world. */
235
- goto stop_the_world;
236
- }
237
-
238
hostaddr = (void *)((uintptr_t)addr + tlbe->addend);
239
240
if (unlikely(tlb_addr & TLB_NOTDIRTY)) {
241
- notdirty_write(env_cpu(env), addr, 1 << s_bits,
242
+ notdirty_write(env_cpu(env), addr, size,
243
&env_tlb(env)->d[mmu_idx].iotlb[index], retaddr);
244
}
245
246
@@ -XXX,XX +XXX,XX @@ void cpu_stq_le_data(CPUArchState *env, target_ulong ptr, uint64_t val)
247
#define ATOMIC_NAME(X) \
248
HELPER(glue(glue(glue(atomic_ ## X, SUFFIX), END), _mmu))
249
#define ATOMIC_MMU_DECLS
250
-#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, oi, retaddr)
251
+#define ATOMIC_MMU_LOOKUP_RW \
252
+ atomic_mmu_lookup(env, addr, oi, DATA_SIZE, PAGE_READ | PAGE_WRITE, retaddr)
253
+#define ATOMIC_MMU_LOOKUP_R \
254
+ atomic_mmu_lookup(env, addr, oi, DATA_SIZE, PAGE_READ, retaddr)
255
+#define ATOMIC_MMU_LOOKUP_W \
256
+ atomic_mmu_lookup(env, addr, oi, DATA_SIZE, PAGE_WRITE, retaddr)
257
#define ATOMIC_MMU_CLEANUP
258
#define ATOMIC_MMU_IDX get_mmuidx(oi)
259
260
@@ -XXX,XX +XXX,XX @@ void cpu_stq_le_data(CPUArchState *env, target_ulong ptr, uint64_t val)
261
262
#undef EXTRA_ARGS
263
#undef ATOMIC_NAME
264
-#undef ATOMIC_MMU_LOOKUP
265
+#undef ATOMIC_MMU_LOOKUP_RW
266
+#undef ATOMIC_MMU_LOOKUP_R
267
+#undef ATOMIC_MMU_LOOKUP_W
268
+
269
#define EXTRA_ARGS , TCGMemOpIdx oi
270
#define ATOMIC_NAME(X) HELPER(glue(glue(atomic_ ## X, SUFFIX), END))
271
-#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, oi, GETPC())
272
+#define ATOMIC_MMU_LOOKUP_RW \
273
+ atomic_mmu_lookup(env, addr, oi, DATA_SIZE, PAGE_READ | PAGE_WRITE, GETPC())
274
+#define ATOMIC_MMU_LOOKUP_R \
275
+ atomic_mmu_lookup(env, addr, oi, DATA_SIZE, PAGE_READ, GETPC())
276
+#define ATOMIC_MMU_LOOKUP_W \
277
+ atomic_mmu_lookup(env, addr, oi, DATA_SIZE, PAGE_WRITE, GETPC())
278
279
#define DATA_SIZE 1
280
#include "atomic_template.h"
281
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
282
index XXXXXXX..XXXXXXX 100644
283
--- a/accel/tcg/user-exec.c
284
+++ b/accel/tcg/user-exec.c
285
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
286
287
/* Macro to call the above, with local variables from the use context. */
288
#define ATOMIC_MMU_DECLS do {} while (0)
289
-#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, DATA_SIZE, GETPC())
290
+#define ATOMIC_MMU_LOOKUP_RW atomic_mmu_lookup(env, addr, DATA_SIZE, GETPC())
291
+#define ATOMIC_MMU_LOOKUP_R ATOMIC_MMU_LOOKUP_RW
292
+#define ATOMIC_MMU_LOOKUP_W ATOMIC_MMU_LOOKUP_RW
293
#define ATOMIC_MMU_CLEANUP do { clear_helper_retaddr(); } while (0)
294
#define ATOMIC_MMU_IDX MMU_USER_IDX
295
296
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
297
298
#undef EXTRA_ARGS
299
#undef ATOMIC_NAME
300
-#undef ATOMIC_MMU_LOOKUP
301
+#undef ATOMIC_MMU_LOOKUP_RW
302
303
#define EXTRA_ARGS , TCGMemOpIdx oi, uintptr_t retaddr
304
#define ATOMIC_NAME(X) \
305
HELPER(glue(glue(glue(atomic_ ## X, SUFFIX), END), _mmu))
306
-#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, DATA_SIZE, retaddr)
307
+#define ATOMIC_MMU_LOOKUP_RW atomic_mmu_lookup(env, addr, DATA_SIZE, retaddr)
308
309
#define DATA_SIZE 16
310
#include "atomic_template.h"
311
--
103
--
312
2.25.1
104
2.34.1
313
314
diff view generated by jsdifflib
1
As the only call-clobbered regs for TCI, these should
1
From: Luca Bonissi <qemu@bonslack.org>
2
receive the least priority.
3
2
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
These should match 'start' as target_ulong, not target_long.
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
5
On 32bit targets, the parameter was sign-extended to uint64_t,
6
so only the first mmap within the upper 2GB memory can succeed.
7
8
Signed-off-by: Luca Bonissi <qemu@bonslack.org>
9
Message-Id: <327460e2-0ebd-9edb-426b-1df80d16c32a@bonslack.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
12
---
8
tcg/tci/tcg-target.c.inc | 4 ++--
13
accel/tcg/user-exec.c | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
10
15
11
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
16
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/tci/tcg-target.c.inc
18
--- a/accel/tcg/user-exec.c
14
+++ b/tcg/tci/tcg-target.c.inc
19
+++ b/accel/tcg/user-exec.c
15
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
20
@@ -XXX,XX +XXX,XX @@ typedef struct PageFlagsNode {
21
22
static IntervalTreeRoot pageflags_root;
23
24
-static PageFlagsNode *pageflags_find(target_ulong start, target_long last)
25
+static PageFlagsNode *pageflags_find(target_ulong start, target_ulong last)
26
{
27
IntervalTreeNode *n;
28
29
@@ -XXX,XX +XXX,XX @@ static PageFlagsNode *pageflags_find(target_ulong start, target_long last)
16
}
30
}
17
31
18
static const int tcg_target_reg_alloc_order[] = {
32
static PageFlagsNode *pageflags_next(PageFlagsNode *p, target_ulong start,
19
- TCG_REG_R0,
33
- target_long last)
20
- TCG_REG_R1,
34
+ target_ulong last)
21
TCG_REG_R2,
35
{
22
TCG_REG_R3,
36
IntervalTreeNode *n;
23
TCG_REG_R4,
37
24
@@ -XXX,XX +XXX,XX @@ static const int tcg_target_reg_alloc_order[] = {
25
TCG_REG_R13,
26
TCG_REG_R14,
27
TCG_REG_R15,
28
+ TCG_REG_R1,
29
+ TCG_REG_R0,
30
};
31
32
#if MAX_OPC_PARAM_IARGS != 6
33
--
38
--
34
2.25.1
39
2.34.1
35
36
diff view generated by jsdifflib
Deleted patch
1
This requires adjusting where arguments are stored.
2
Place them on the stack at left-aligned positions.
3
Adjust the stack frame to be at entirely positive offsets.
4
1
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
include/tcg/tcg.h | 1 +
10
tcg/tci/tcg-target.h | 2 +-
11
tcg/tcg.c | 64 +++++++++++++-----
12
tcg/tci.c | 142 ++++++++++++++++++++++-----------------
13
tcg/tci/tcg-target.c.inc | 50 +++++++-------
14
5 files changed, 153 insertions(+), 106 deletions(-)
15
16
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/tcg/tcg.h
19
+++ b/include/tcg/tcg.h
20
@@ -XXX,XX +XXX,XX @@
21
#define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS))
22
23
#define CPU_TEMP_BUF_NLONGS 128
24
+#define TCG_STATIC_FRAME_SIZE (CPU_TEMP_BUF_NLONGS * sizeof(long))
25
26
/* Default target word size to pointer size. */
27
#ifndef TCG_TARGET_REG_BITS
28
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/tcg/tci/tcg-target.h
31
+++ b/tcg/tci/tcg-target.h
32
@@ -XXX,XX +XXX,XX @@ typedef enum {
33
34
/* Used for function call generation. */
35
#define TCG_TARGET_CALL_STACK_OFFSET 0
36
-#define TCG_TARGET_STACK_ALIGN 16
37
+#define TCG_TARGET_STACK_ALIGN 8
38
39
#define HAVE_TCG_QEMU_TB_EXEC
40
41
diff --git a/tcg/tcg.c b/tcg/tcg.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/tcg/tcg.c
44
+++ b/tcg/tcg.c
45
@@ -XXX,XX +XXX,XX @@ static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
46
intptr_t arg2);
47
static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
48
TCGReg base, intptr_t ofs);
49
+#ifdef CONFIG_TCG_INTERPRETER
50
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target,
51
+ ffi_cif *cif);
52
+#else
53
static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target);
54
+#endif
55
static bool tcg_target_const_match(int64_t val, TCGType type, int ct);
56
#ifdef TCG_TARGET_NEED_LDST_LABELS
57
static int tcg_out_ldst_finalize(TCGContext *s);
58
@@ -XXX,XX +XXX,XX @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
59
for (i = 0; i < nargs; i++) {
60
int argtype = extract32(typemask, (i + 1) * 3, 3);
61
bool is_64bit = (argtype & ~1) == dh_typecode_i64;
62
+ bool want_align = false;
63
+
64
+#if defined(CONFIG_TCG_INTERPRETER)
65
+ /*
66
+ * Align all arguments, so that they land in predictable places
67
+ * for passing off to ffi_call.
68
+ */
69
+ want_align = true;
70
+#elif defined(TCG_TARGET_CALL_ALIGN_ARGS)
71
+ /* Some targets want aligned 64 bit args */
72
+ want_align = is_64bit;
73
+#endif
74
+
75
+ if (TCG_TARGET_REG_BITS < 64 && want_align && (real_args & 1)) {
76
+ op->args[pi++] = TCG_CALL_DUMMY_ARG;
77
+ real_args++;
78
+ }
79
80
if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
81
-#ifdef TCG_TARGET_CALL_ALIGN_ARGS
82
- /* some targets want aligned 64 bit args */
83
- if (real_args & 1) {
84
- op->args[pi++] = TCG_CALL_DUMMY_ARG;
85
- real_args++;
86
- }
87
-#endif
88
- /* If stack grows up, then we will be placing successive
89
- arguments at lower addresses, which means we need to
90
- reverse the order compared to how we would normally
91
- treat either big or little-endian. For those arguments
92
- that will wind up in registers, this still works for
93
- HPPA (the only current STACK_GROWSUP target) since the
94
- argument registers are *also* allocated in decreasing
95
- order. If another such target is added, this logic may
96
- have to get more complicated to differentiate between
97
- stack arguments and register arguments. */
98
+ /*
99
+ * If stack grows up, then we will be placing successive
100
+ * arguments at lower addresses, which means we need to
101
+ * reverse the order compared to how we would normally
102
+ * treat either big or little-endian. For those arguments
103
+ * that will wind up in registers, this still works for
104
+ * HPPA (the only current STACK_GROWSUP target) since the
105
+ * argument registers are *also* allocated in decreasing
106
+ * order. If another such target is added, this logic may
107
+ * have to get more complicated to differentiate between
108
+ * stack arguments and register arguments.
109
+ */
110
#if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
111
op->args[pi++] = temp_arg(args[i] + 1);
112
op->args[pi++] = temp_arg(args[i]);
113
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
114
const int nb_oargs = TCGOP_CALLO(op);
115
const int nb_iargs = TCGOP_CALLI(op);
116
const TCGLifeData arg_life = op->life;
117
+ const TCGHelperInfo *info;
118
int flags, nb_regs, i;
119
TCGReg reg;
120
TCGArg arg;
121
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
122
TCGRegSet allocated_regs;
123
124
func_addr = tcg_call_func(op);
125
- flags = tcg_call_flags(op);
126
+ info = tcg_call_info(op);
127
+ flags = info->flags;
128
129
nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
130
if (nb_regs > nb_iargs) {
131
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
132
save_globals(s, allocated_regs);
133
}
134
135
+#ifdef CONFIG_TCG_INTERPRETER
136
+ {
137
+ gpointer hash = (gpointer)(uintptr_t)info->typemask;
138
+ ffi_cif *cif = g_hash_table_lookup(ffi_table, hash);
139
+ assert(cif != NULL);
140
+ tcg_out_call(s, func_addr, cif);
141
+ }
142
+#else
143
tcg_out_call(s, func_addr);
144
+#endif
145
146
/* assign output registers and emit moves if needed */
147
for(i = 0; i < nb_oargs; i++) {
148
diff --git a/tcg/tci.c b/tcg/tci.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/tcg/tci.c
151
+++ b/tcg/tci.c
152
@@ -XXX,XX +XXX,XX @@
153
*/
154
155
#include "qemu/osdep.h"
156
+#include "qemu-common.h"
157
+#include "tcg/tcg.h" /* MAX_OPC_PARAM_IARGS */
158
+#include "exec/cpu_ldst.h"
159
+#include "tcg/tcg-op.h"
160
+#include "qemu/compiler.h"
161
+#include <ffi.h>
162
163
-/* Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
164
- * Without assertions, the interpreter runs much faster. */
165
+
166
+/*
167
+ * Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
168
+ * Without assertions, the interpreter runs much faster.
169
+ */
170
#if defined(CONFIG_DEBUG_TCG)
171
# define tci_assert(cond) assert(cond)
172
#else
173
# define tci_assert(cond) ((void)(cond))
174
#endif
175
176
-#include "qemu-common.h"
177
-#include "tcg/tcg.h" /* MAX_OPC_PARAM_IARGS */
178
-#include "exec/cpu_ldst.h"
179
-#include "tcg/tcg-op.h"
180
-#include "qemu/compiler.h"
181
-
182
-#if MAX_OPC_PARAM_IARGS != 6
183
-# error Fix needed, number of supported input arguments changed!
184
-#endif
185
-#if TCG_TARGET_REG_BITS == 32
186
-typedef uint64_t (*helper_function)(tcg_target_ulong, tcg_target_ulong,
187
- tcg_target_ulong, tcg_target_ulong,
188
- tcg_target_ulong, tcg_target_ulong,
189
- tcg_target_ulong, tcg_target_ulong,
190
- tcg_target_ulong, tcg_target_ulong,
191
- tcg_target_ulong, tcg_target_ulong);
192
-#else
193
-typedef uint64_t (*helper_function)(tcg_target_ulong, tcg_target_ulong,
194
- tcg_target_ulong, tcg_target_ulong,
195
- tcg_target_ulong, tcg_target_ulong);
196
-#endif
197
-
198
__thread uintptr_t tci_tb_ptr;
199
200
-static tcg_target_ulong tci_read_reg(const tcg_target_ulong *regs, TCGReg index)
201
-{
202
- tci_assert(index < TCG_TARGET_NB_REGS);
203
- return regs[index];
204
-}
205
-
206
static void
207
tci_write_reg(tcg_target_ulong *regs, TCGReg index, tcg_target_ulong value)
208
{
209
@@ -XXX,XX +XXX,XX @@ static tcg_target_ulong tci_read_label(const uint8_t **tb_ptr)
210
* I = immediate (tcg_target_ulong)
211
* l = label or pointer
212
* m = immediate (TCGMemOpIdx)
213
+ * n = immediate (call return length)
214
* r = register
215
* s = signed ldst offset
216
*/
217
@@ -XXX,XX +XXX,XX @@ static void tci_args_l(const uint8_t **tb_ptr, void **l0)
218
check_size(start, tb_ptr);
219
}
220
221
+static void tci_args_nll(const uint8_t **tb_ptr, uint8_t *n0,
222
+ void **l1, void **l2)
223
+{
224
+ const uint8_t *start = *tb_ptr;
225
+
226
+ *n0 = tci_read_b(tb_ptr);
227
+ *l1 = (void *)tci_read_label(tb_ptr);
228
+ *l2 = (void *)tci_read_label(tb_ptr);
229
+
230
+ check_size(start, tb_ptr);
231
+}
232
+
233
static void tci_args_rr(const uint8_t **tb_ptr,
234
TCGReg *r0, TCGReg *r1)
235
{
236
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
237
{
238
const uint8_t *tb_ptr = v_tb_ptr;
239
tcg_target_ulong regs[TCG_TARGET_NB_REGS];
240
- long tcg_temps[CPU_TEMP_BUF_NLONGS];
241
- uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
242
+ uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
243
+ / sizeof(uint64_t)];
244
+ void *call_slots[TCG_STATIC_CALL_ARGS_SIZE / sizeof(uint64_t)];
245
246
regs[TCG_AREG0] = (tcg_target_ulong)env;
247
- regs[TCG_REG_CALL_STACK] = sp_value;
248
+ regs[TCG_REG_CALL_STACK] = (uintptr_t)stack;
249
+ /* Other call_slots entries initialized at first use (see below). */
250
+ call_slots[0] = NULL;
251
tci_assert(tb_ptr);
252
253
for (;;) {
254
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
255
#endif
256
TCGMemOpIdx oi;
257
int32_t ofs;
258
- void *ptr;
259
+ void *ptr, *cif;
260
261
/* Skip opcode and size entry. */
262
tb_ptr += 2;
263
264
switch (opc) {
265
case INDEX_op_call:
266
- tci_args_l(&tb_ptr, &ptr);
267
+ /*
268
+ * Set up the ffi_avalue array once, delayed until now
269
+ * because many TB's do not make any calls. In tcg_gen_callN,
270
+ * we arranged for every real argument to be "left-aligned"
271
+ * in each 64-bit slot.
272
+ */
273
+ if (unlikely(call_slots[0] == NULL)) {
274
+ for (int i = 0; i < ARRAY_SIZE(call_slots); ++i) {
275
+ call_slots[i] = &stack[i];
276
+ }
277
+ }
278
+
279
+ tci_args_nll(&tb_ptr, &len, &ptr, &cif);
280
+
281
+ /* Helper functions may need to access the "return address" */
282
tci_tb_ptr = (uintptr_t)tb_ptr;
283
-#if TCG_TARGET_REG_BITS == 32
284
- tmp64 = ((helper_function)ptr)(tci_read_reg(regs, TCG_REG_R0),
285
- tci_read_reg(regs, TCG_REG_R1),
286
- tci_read_reg(regs, TCG_REG_R2),
287
- tci_read_reg(regs, TCG_REG_R3),
288
- tci_read_reg(regs, TCG_REG_R4),
289
- tci_read_reg(regs, TCG_REG_R5),
290
- tci_read_reg(regs, TCG_REG_R6),
291
- tci_read_reg(regs, TCG_REG_R7),
292
- tci_read_reg(regs, TCG_REG_R8),
293
- tci_read_reg(regs, TCG_REG_R9),
294
- tci_read_reg(regs, TCG_REG_R10),
295
- tci_read_reg(regs, TCG_REG_R11));
296
- tci_write_reg(regs, TCG_REG_R0, tmp64);
297
- tci_write_reg(regs, TCG_REG_R1, tmp64 >> 32);
298
-#else
299
- tmp64 = ((helper_function)ptr)(tci_read_reg(regs, TCG_REG_R0),
300
- tci_read_reg(regs, TCG_REG_R1),
301
- tci_read_reg(regs, TCG_REG_R2),
302
- tci_read_reg(regs, TCG_REG_R3),
303
- tci_read_reg(regs, TCG_REG_R4),
304
- tci_read_reg(regs, TCG_REG_R5));
305
- tci_write_reg(regs, TCG_REG_R0, tmp64);
306
-#endif
307
+
308
+ ffi_call(cif, ptr, stack, call_slots);
309
+
310
+ /* Any result winds up "left-aligned" in the stack[0] slot. */
311
+ switch (len) {
312
+ case 0: /* void */
313
+ break;
314
+ case 1: /* uint32_t */
315
+ /*
316
+ * Note that libffi has an odd special case in that it will
317
+ * always widen an integral result to ffi_arg.
318
+ */
319
+ if (sizeof(ffi_arg) == 4) {
320
+ regs[TCG_REG_R0] = *(uint32_t *)stack;
321
+ break;
322
+ }
323
+ /* fall through */
324
+ case 2: /* uint64_t */
325
+ if (TCG_TARGET_REG_BITS == 32) {
326
+ tci_write_reg64(regs, TCG_REG_R1, TCG_REG_R0, stack[0]);
327
+ } else {
328
+ regs[TCG_REG_R0] = stack[0];
329
+ }
330
+ break;
331
+ default:
332
+ g_assert_not_reached();
333
+ }
334
break;
335
+
336
case INDEX_op_br:
337
tci_args_l(&tb_ptr, &ptr);
338
tb_ptr = ptr;
339
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
340
TCGCond c;
341
TCGMemOpIdx oi;
342
uint8_t pos, len;
343
- void *ptr;
344
+ void *ptr, *cif;
345
const uint8_t *tb_ptr;
346
347
status = info->read_memory_func(addr, buf, 2, info);
348
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
349
350
switch (op) {
351
case INDEX_op_br:
352
- case INDEX_op_call:
353
case INDEX_op_exit_tb:
354
case INDEX_op_goto_tb:
355
tci_args_l(&tb_ptr, &ptr);
356
info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
357
break;
358
359
+ case INDEX_op_call:
360
+ tci_args_nll(&tb_ptr, &len, &ptr, &cif);
361
+ info->fprintf_func(info->stream, "%-12s %d, %p, %p",
362
+ op_name, len, ptr, cif);
363
+ break;
364
+
365
case INDEX_op_brcond_i32:
366
case INDEX_op_brcond_i64:
367
tci_args_rrcl(&tb_ptr, &r0, &r1, &c, &ptr);
368
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
369
index XXXXXXX..XXXXXXX 100644
370
--- a/tcg/tci/tcg-target.c.inc
371
+++ b/tcg/tci/tcg-target.c.inc
372
@@ -XXX,XX +XXX,XX @@ static const int tcg_target_reg_alloc_order[] = {
373
# error Fix needed, number of supported input arguments changed!
374
#endif
375
376
-static const int tcg_target_call_iarg_regs[] = {
377
- TCG_REG_R0,
378
- TCG_REG_R1,
379
- TCG_REG_R2,
380
- TCG_REG_R3,
381
- TCG_REG_R4,
382
- TCG_REG_R5,
383
-#if TCG_TARGET_REG_BITS == 32
384
- /* 32 bit hosts need 2 * MAX_OPC_PARAM_IARGS registers. */
385
- TCG_REG_R6,
386
- TCG_REG_R7,
387
- TCG_REG_R8,
388
- TCG_REG_R9,
389
- TCG_REG_R10,
390
- TCG_REG_R11,
391
-#endif
392
-};
393
+/* No call arguments via registers. All will be stored on the "stack". */
394
+static const int tcg_target_call_iarg_regs[] = { };
395
396
static const int tcg_target_call_oarg_regs[] = {
397
TCG_REG_R0,
398
@@ -XXX,XX +XXX,XX @@ static void tci_out_label(TCGContext *s, TCGLabel *label)
399
static void stack_bounds_check(TCGReg base, target_long offset)
400
{
401
if (base == TCG_REG_CALL_STACK) {
402
- tcg_debug_assert(offset < 0);
403
- tcg_debug_assert(offset >= -(CPU_TEMP_BUF_NLONGS * sizeof(long)));
404
+ tcg_debug_assert(offset >= 0);
405
+ tcg_debug_assert(offset < (TCG_STATIC_CALL_ARGS_SIZE +
406
+ TCG_STATIC_FRAME_SIZE));
407
}
408
}
409
410
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type,
411
}
412
}
413
414
-static inline void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg)
415
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *func,
416
+ ffi_cif *cif)
417
{
418
uint8_t *old_code_ptr = s->code_ptr;
419
+ uint8_t which;
420
+
421
+ if (cif->rtype == &ffi_type_void) {
422
+ which = 0;
423
+ } else if (cif->rtype->size == 4) {
424
+ which = 1;
425
+ } else {
426
+ tcg_debug_assert(cif->rtype->size == 8);
427
+ which = 2;
428
+ }
429
tcg_out_op_t(s, INDEX_op_call);
430
- tcg_out_i(s, (uintptr_t)arg);
431
+ tcg_out8(s, which);
432
+ tcg_out_i(s, (uintptr_t)func);
433
+ tcg_out_i(s, (uintptr_t)cif);
434
+
435
old_code_ptr[1] = s->code_ptr - old_code_ptr;
436
}
437
438
@@ -XXX,XX +XXX,XX @@ static void tcg_target_init(TCGContext *s)
439
s->reserved_regs = 0;
440
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
441
442
- /* We use negative offsets from "sp" so that we can distinguish
443
- stores that might pretend to be call arguments. */
444
- tcg_set_frame(s, TCG_REG_CALL_STACK,
445
- -CPU_TEMP_BUF_NLONGS * sizeof(long),
446
- CPU_TEMP_BUF_NLONGS * sizeof(long));
447
+ /* The call arguments come first, followed by the temp storage. */
448
+ tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
449
+ TCG_STATIC_FRAME_SIZE);
450
}
451
452
/* Generate global QEMU prologue and epilogue code. */
453
--
454
2.25.1
455
456
diff view generated by jsdifflib
Deleted patch
1
We're about to adjust the offset range on host memory ops,
2
and the format of branches. Both will require a temporary.
3
1
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
tcg/tci/tcg-target.h | 1 +
9
tcg/tci/tcg-target.c.inc | 1 +
10
2 files changed, 2 insertions(+)
11
12
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/tci/tcg-target.h
15
+++ b/tcg/tci/tcg-target.h
16
@@ -XXX,XX +XXX,XX @@ typedef enum {
17
TCG_REG_R14,
18
TCG_REG_R15,
19
20
+ TCG_REG_TMP = TCG_REG_R13,
21
TCG_AREG0 = TCG_REG_R14,
22
TCG_REG_CALL_STACK = TCG_REG_R15,
23
} TCGReg;
24
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/tcg/tci/tcg-target.c.inc
27
+++ b/tcg/tci/tcg-target.c.inc
28
@@ -XXX,XX +XXX,XX @@ static void tcg_target_init(TCGContext *s)
29
MAKE_64BIT_MASK(TCG_REG_R0, 64 / TCG_TARGET_REG_BITS);
30
31
s->reserved_regs = 0;
32
+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
33
tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
34
35
/* The call arguments come first, followed by the temp storage. */
36
--
37
2.25.1
38
39
diff view generated by jsdifflib
Deleted patch
1
The encoding planned for tci does not have enough room for
2
brcond2, with 4 registers and a condition as input as well
3
as the label. Resolve the condition into TCG_REG_TMP, and
4
relax brcond to one register plus a label, considering the
5
condition to always be reg != 0.
6
1
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
tcg/tci.c | 68 ++++++++++------------------------------
12
tcg/tci/tcg-target.c.inc | 52 +++++++++++-------------------
13
2 files changed, 35 insertions(+), 85 deletions(-)
14
15
diff --git a/tcg/tci.c b/tcg/tci.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/tcg/tci.c
18
+++ b/tcg/tci.c
19
@@ -XXX,XX +XXX,XX @@ static void tci_args_nll(const uint8_t **tb_ptr, uint8_t *n0,
20
check_size(start, tb_ptr);
21
}
22
23
+static void tci_args_rl(const uint8_t **tb_ptr, TCGReg *r0, void **l1)
24
+{
25
+ const uint8_t *start = *tb_ptr;
26
+
27
+ *r0 = tci_read_r(tb_ptr);
28
+ *l1 = (void *)tci_read_label(tb_ptr);
29
+
30
+ check_size(start, tb_ptr);
31
+}
32
+
33
static void tci_args_rr(const uint8_t **tb_ptr,
34
TCGReg *r0, TCGReg *r1)
35
{
36
@@ -XXX,XX +XXX,XX @@ static void tci_args_rrs(const uint8_t **tb_ptr,
37
check_size(start, tb_ptr);
38
}
39
40
-static void tci_args_rrcl(const uint8_t **tb_ptr,
41
- TCGReg *r0, TCGReg *r1, TCGCond *c2, void **l3)
42
-{
43
- const uint8_t *start = *tb_ptr;
44
-
45
- *r0 = tci_read_r(tb_ptr);
46
- *r1 = tci_read_r(tb_ptr);
47
- *c2 = tci_read_b(tb_ptr);
48
- *l3 = (void *)tci_read_label(tb_ptr);
49
-
50
- check_size(start, tb_ptr);
51
-}
52
-
53
static void tci_args_rrrc(const uint8_t **tb_ptr,
54
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
55
{
56
@@ -XXX,XX +XXX,XX @@ static void tci_args_rrrr(const uint8_t **tb_ptr,
57
check_size(start, tb_ptr);
58
}
59
60
-static void tci_args_rrrrcl(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
61
- TCGReg *r2, TCGReg *r3, TCGCond *c4, void **l5)
62
-{
63
- const uint8_t *start = *tb_ptr;
64
-
65
- *r0 = tci_read_r(tb_ptr);
66
- *r1 = tci_read_r(tb_ptr);
67
- *r2 = tci_read_r(tb_ptr);
68
- *r3 = tci_read_r(tb_ptr);
69
- *c4 = tci_read_b(tb_ptr);
70
- *l5 = (void *)tci_read_label(tb_ptr);
71
-
72
- check_size(start, tb_ptr);
73
-}
74
-
75
static void tci_args_rrrrrc(const uint8_t **tb_ptr, TCGReg *r0, TCGReg *r1,
76
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
77
{
78
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
79
break;
80
#endif
81
case INDEX_op_brcond_i32:
82
- tci_args_rrcl(&tb_ptr, &r0, &r1, &condition, &ptr);
83
- if (tci_compare32(regs[r0], regs[r1], condition)) {
84
+ tci_args_rl(&tb_ptr, &r0, &ptr);
85
+ if ((uint32_t)regs[r0]) {
86
tb_ptr = ptr;
87
}
88
break;
89
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
90
T2 = tci_uint64(regs[r5], regs[r4]);
91
tci_write_reg64(regs, r1, r0, T1 - T2);
92
break;
93
- case INDEX_op_brcond2_i32:
94
- tci_args_rrrrcl(&tb_ptr, &r0, &r1, &r2, &r3, &condition, &ptr);
95
- T1 = tci_uint64(regs[r1], regs[r0]);
96
- T2 = tci_uint64(regs[r3], regs[r2]);
97
- if (tci_compare64(T1, T2, condition)) {
98
- tb_ptr = ptr;
99
- continue;
100
- }
101
- break;
102
case INDEX_op_mulu2_i32:
103
tci_args_rrrr(&tb_ptr, &r0, &r1, &r2, &r3);
104
tci_write_reg64(regs, r1, r0, (uint64_t)regs[r2] * regs[r3]);
105
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
106
break;
107
#endif
108
case INDEX_op_brcond_i64:
109
- tci_args_rrcl(&tb_ptr, &r0, &r1, &condition, &ptr);
110
- if (tci_compare64(regs[r0], regs[r1], condition)) {
111
+ tci_args_rl(&tb_ptr, &r0, &ptr);
112
+ if (regs[r0]) {
113
tb_ptr = ptr;
114
}
115
break;
116
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
117
118
case INDEX_op_brcond_i32:
119
case INDEX_op_brcond_i64:
120
- tci_args_rrcl(&tb_ptr, &r0, &r1, &c, &ptr);
121
- info->fprintf_func(info->stream, "%-12s %s, %s, %s, %p",
122
- op_name, str_r(r0), str_r(r1), str_c(c), ptr);
123
+ tci_args_rl(&tb_ptr, &r0, &ptr);
124
+ info->fprintf_func(info->stream, "%-12s %s, 0, ne, %p",
125
+ op_name, str_r(r0), ptr);
126
break;
127
128
case INDEX_op_setcond_i32:
129
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
130
str_r(r3), str_r(r4), str_c(c));
131
break;
132
133
- case INDEX_op_brcond2_i32:
134
- tci_args_rrrrcl(&tb_ptr, &r0, &r1, &r2, &r3, &c, &ptr);
135
- info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %p",
136
- op_name, str_r(r0), str_r(r1),
137
- str_r(r2), str_r(r3), str_c(c), ptr);
138
- break;
139
-
140
case INDEX_op_mulu2_i32:
141
tci_args_rrrr(&tb_ptr, &r0, &r1, &r2, &r3);
142
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
143
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
144
index XXXXXXX..XXXXXXX 100644
145
--- a/tcg/tci/tcg-target.c.inc
146
+++ b/tcg/tci/tcg-target.c.inc
147
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rI(TCGContext *s, TCGOpcode op,
148
}
149
#endif
150
151
+static void tcg_out_op_rl(TCGContext *s, TCGOpcode op, TCGReg r0, TCGLabel *l1)
152
+{
153
+ uint8_t *old_code_ptr = s->code_ptr;
154
+
155
+ tcg_out_op_t(s, op);
156
+ tcg_out_r(s, r0);
157
+ tci_out_label(s, l1);
158
+
159
+ old_code_ptr[1] = s->code_ptr - old_code_ptr;
160
+}
161
+
162
static void tcg_out_op_rr(TCGContext *s, TCGOpcode op, TCGReg r0, TCGReg r1)
163
{
164
uint8_t *old_code_ptr = s->code_ptr;
165
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rrs(TCGContext *s, TCGOpcode op,
166
old_code_ptr[1] = s->code_ptr - old_code_ptr;
167
}
168
169
-static void tcg_out_op_rrcl(TCGContext *s, TCGOpcode op,
170
- TCGReg r0, TCGReg r1, TCGCond c2, TCGLabel *l3)
171
-{
172
- uint8_t *old_code_ptr = s->code_ptr;
173
-
174
- tcg_out_op_t(s, op);
175
- tcg_out_r(s, r0);
176
- tcg_out_r(s, r1);
177
- tcg_out8(s, c2);
178
- tci_out_label(s, l3);
179
-
180
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
181
-}
182
-
183
static void tcg_out_op_rrrc(TCGContext *s, TCGOpcode op,
184
TCGReg r0, TCGReg r1, TCGReg r2, TCGCond c3)
185
{
186
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
187
old_code_ptr[1] = s->code_ptr - old_code_ptr;
188
}
189
190
-static void tcg_out_op_rrrrcl(TCGContext *s, TCGOpcode op,
191
- TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3,
192
- TCGCond c4, TCGLabel *l5)
193
-{
194
- uint8_t *old_code_ptr = s->code_ptr;
195
-
196
- tcg_out_op_t(s, op);
197
- tcg_out_r(s, r0);
198
- tcg_out_r(s, r1);
199
- tcg_out_r(s, r2);
200
- tcg_out_r(s, r3);
201
- tcg_out8(s, c4);
202
- tci_out_label(s, l5);
203
-
204
- old_code_ptr[1] = s->code_ptr - old_code_ptr;
205
-}
206
-
207
static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
208
TCGReg r0, TCGReg r1, TCGReg r2,
209
TCGReg r3, TCGReg r4, TCGCond c5)
210
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
211
break;
212
213
CASE_32_64(brcond)
214
- tcg_out_op_rrcl(s, opc, args[0], args[1], args[2], arg_label(args[3]));
215
+ tcg_out_op_rrrc(s, (opc == INDEX_op_brcond_i32
216
+ ? INDEX_op_setcond_i32 : INDEX_op_setcond_i64),
217
+ TCG_REG_TMP, args[0], args[1], args[2]);
218
+ tcg_out_op_rl(s, opc, TCG_REG_TMP, arg_label(args[3]));
219
break;
220
221
CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
222
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
223
args[3], args[4], args[5]);
224
break;
225
case INDEX_op_brcond2_i32:
226
- tcg_out_op_rrrrcl(s, opc, args[0], args[1], args[2],
227
- args[3], args[4], arg_label(args[5]));
228
+ tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, TCG_REG_TMP,
229
+ args[0], args[1], args[2], args[3], args[4]);
230
+ tcg_out_op_rl(s, INDEX_op_brcond_i32, TCG_REG_TMP, arg_label(args[5]));
231
break;
232
case INDEX_op_mulu2_i32:
233
tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], args[3]);
234
--
235
2.25.1
236
237
diff view generated by jsdifflib
Deleted patch
1
Inline it into its one caller, tci_write_reg64.
2
Drop the asserts that are redundant with tcg_read_r.
3
1
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
tcg/tci.c | 13 ++-----------
9
1 file changed, 2 insertions(+), 11 deletions(-)
10
11
diff --git a/tcg/tci.c b/tcg/tci.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/tci.c
14
+++ b/tcg/tci.c
15
@@ -XXX,XX +XXX,XX @@
16
17
__thread uintptr_t tci_tb_ptr;
18
19
-static void
20
-tci_write_reg(tcg_target_ulong *regs, TCGReg index, tcg_target_ulong value)
21
-{
22
- tci_assert(index < TCG_TARGET_NB_REGS);
23
- tci_assert(index != TCG_AREG0);
24
- tci_assert(index != TCG_REG_CALL_STACK);
25
- regs[index] = value;
26
-}
27
-
28
static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
29
uint32_t low_index, uint64_t value)
30
{
31
- tci_write_reg(regs, low_index, value);
32
- tci_write_reg(regs, high_index, value >> 32);
33
+ regs[low_index] = value;
34
+ regs[high_index] = value >> 32;
35
}
36
37
/* Create a 64 bit value from two 32 bit values. */
38
--
39
2.25.1
40
41
diff view generated by jsdifflib
Deleted patch
1
This operation is critical to staying within the interpretation
2
loop longer, which avoids the overhead of setup and teardown for
3
many TBs.
4
1
5
The check in tcg_prologue_init is disabled because TCI does
6
want to use NULL to indicate exit, as opposed to branching to
7
a real epilogue.
8
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
13
tcg/tci/tcg-target-con-set.h | 1 +
14
tcg/tci/tcg-target.h | 2 +-
15
tcg/tcg.c | 8 +++++++-
16
tcg/tci.c | 19 +++++++++++++++++++
17
tcg/tci/tcg-target.c.inc | 16 ++++++++++++++++
18
5 files changed, 44 insertions(+), 2 deletions(-)
19
20
diff --git a/tcg/tci/tcg-target-con-set.h b/tcg/tci/tcg-target-con-set.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tcg/tci/tcg-target-con-set.h
23
+++ b/tcg/tci/tcg-target-con-set.h
24
@@ -XXX,XX +XXX,XX @@
25
* Each operand should be a sequence of constraint letters as defined by
26
* tcg-target-con-str.h; the constraint combination is inclusive or.
27
*/
28
+C_O0_I1(r)
29
C_O0_I2(r, r)
30
C_O0_I3(r, r, r)
31
C_O0_I4(r, r, r, r)
32
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/tcg/tci/tcg-target.h
35
+++ b/tcg/tci/tcg-target.h
36
@@ -XXX,XX +XXX,XX @@
37
#define TCG_TARGET_HAS_muls2_i32 0
38
#define TCG_TARGET_HAS_muluh_i32 0
39
#define TCG_TARGET_HAS_mulsh_i32 0
40
-#define TCG_TARGET_HAS_goto_ptr 0
41
+#define TCG_TARGET_HAS_goto_ptr 1
42
#define TCG_TARGET_HAS_direct_jump 0
43
#define TCG_TARGET_HAS_qemu_st8_i32 0
44
45
diff --git a/tcg/tcg.c b/tcg/tcg.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/tcg/tcg.c
48
+++ b/tcg/tcg.c
49
@@ -XXX,XX +XXX,XX @@ void tcg_prologue_init(TCGContext *s)
50
}
51
#endif
52
53
- /* Assert that goto_ptr is implemented completely. */
54
+#ifndef CONFIG_TCG_INTERPRETER
55
+ /*
56
+ * Assert that goto_ptr is implemented completely, setting an epilogue.
57
+ * For tci, we use NULL as the signal to return from the interpreter,
58
+ * so skip this check.
59
+ */
60
if (TCG_TARGET_HAS_goto_ptr) {
61
tcg_debug_assert(tcg_code_gen_epilogue != NULL);
62
}
63
+#endif
64
}
65
66
void tcg_func_start(TCGContext *s)
67
diff --git a/tcg/tci.c b/tcg/tci.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/tcg/tci.c
70
+++ b/tcg/tci.c
71
@@ -XXX,XX +XXX,XX @@ static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
72
*l0 = diff ? (void *)tb_ptr + diff : NULL;
73
}
74
75
+static void tci_args_r(uint32_t insn, TCGReg *r0)
76
+{
77
+ *r0 = extract32(insn, 8, 4);
78
+}
79
+
80
static void tci_args_nl(uint32_t insn, const void *tb_ptr,
81
uint8_t *n0, void **l1)
82
{
83
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
84
tb_ptr = *(void **)ptr;
85
break;
86
87
+ case INDEX_op_goto_ptr:
88
+ tci_args_r(insn, &r0);
89
+ ptr = (void *)regs[r0];
90
+ if (!ptr) {
91
+ return 0;
92
+ }
93
+ tb_ptr = ptr;
94
+ break;
95
+
96
case INDEX_op_qemu_ld_i32:
97
if (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS) {
98
tci_args_rrm(insn, &r0, &r1, &oi);
99
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
100
info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
101
break;
102
103
+ case INDEX_op_goto_ptr:
104
+ tci_args_r(insn, &r0);
105
+ info->fprintf_func(info->stream, "%-12s %s", op_name, str_r(r0));
106
+ break;
107
+
108
case INDEX_op_call:
109
tci_args_nl(insn, tb_ptr, &len, &ptr);
110
info->fprintf_func(info->stream, "%-12s %d, %p", op_name, len, ptr);
111
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
112
index XXXXXXX..XXXXXXX 100644
113
--- a/tcg/tci/tcg-target.c.inc
114
+++ b/tcg/tci/tcg-target.c.inc
115
@@ -XXX,XX +XXX,XX @@
116
static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
117
{
118
switch (op) {
119
+ case INDEX_op_goto_ptr:
120
+ return C_O0_I1(r);
121
+
122
case INDEX_op_ld8u_i32:
123
case INDEX_op_ld8s_i32:
124
case INDEX_op_ld16u_i32:
125
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_p(TCGContext *s, TCGOpcode op, void *p0)
126
tcg_out32(s, insn);
127
}
128
129
+static void tcg_out_op_r(TCGContext *s, TCGOpcode op, TCGReg r0)
130
+{
131
+ tcg_insn_unit insn = 0;
132
+
133
+ insn = deposit32(insn, 0, 8, op);
134
+ insn = deposit32(insn, 8, 4, r0);
135
+ tcg_out32(s, insn);
136
+}
137
+
138
static void tcg_out_op_v(TCGContext *s, TCGOpcode op)
139
{
140
tcg_out32(s, (uint8_t)op);
141
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
142
set_jmp_reset_offset(s, args[0]);
143
break;
144
145
+ case INDEX_op_goto_ptr:
146
+ tcg_out_op_r(s, opc, args[0]);
147
+ break;
148
+
149
case INDEX_op_br:
150
tcg_out_op_l(s, opc, arg_label(args[0]));
151
break;
152
--
153
2.25.1
154
155
diff view generated by jsdifflib
Deleted patch
1
When this opcode is not available in the backend, tcg middle-end
2
will expand this as a series of 5 opcodes. So implementing this
3
saves bytecode space.
4
1
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
tcg/tci/tcg-target.h | 4 ++--
10
tcg/tci.c | 16 +++++++++++++++-
11
tcg/tci/tcg-target.c.inc | 10 +++++++---
12
3 files changed, 24 insertions(+), 6 deletions(-)
13
14
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/tci/tcg-target.h
17
+++ b/tcg/tci/tcg-target.h
18
@@ -XXX,XX +XXX,XX @@
19
#define TCG_TARGET_HAS_not_i32 1
20
#define TCG_TARGET_HAS_orc_i32 0
21
#define TCG_TARGET_HAS_rot_i32 1
22
-#define TCG_TARGET_HAS_movcond_i32 0
23
+#define TCG_TARGET_HAS_movcond_i32 1
24
#define TCG_TARGET_HAS_muls2_i32 0
25
#define TCG_TARGET_HAS_muluh_i32 0
26
#define TCG_TARGET_HAS_mulsh_i32 0
27
@@ -XXX,XX +XXX,XX @@
28
#define TCG_TARGET_HAS_not_i64 1
29
#define TCG_TARGET_HAS_orc_i64 0
30
#define TCG_TARGET_HAS_rot_i64 1
31
-#define TCG_TARGET_HAS_movcond_i64 0
32
+#define TCG_TARGET_HAS_movcond_i64 1
33
#define TCG_TARGET_HAS_muls2_i64 0
34
#define TCG_TARGET_HAS_add2_i32 0
35
#define TCG_TARGET_HAS_sub2_i32 0
36
diff --git a/tcg/tci.c b/tcg/tci.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tcg/tci.c
39
+++ b/tcg/tci.c
40
@@ -XXX,XX +XXX,XX @@ static void tci_args_rrrr(uint32_t insn,
41
*r2 = extract32(insn, 16, 4);
42
*r3 = extract32(insn, 20, 4);
43
}
44
+#endif
45
46
static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
47
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
48
@@ -XXX,XX +XXX,XX @@ static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
49
*c5 = extract32(insn, 28, 4);
50
}
51
52
+#if TCG_TARGET_REG_BITS == 32
53
static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
54
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
55
{
56
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
57
tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
58
regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
59
break;
60
+ case INDEX_op_movcond_i32:
61
+ tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
62
+ tmp32 = tci_compare32(regs[r1], regs[r2], condition);
63
+ regs[r0] = regs[tmp32 ? r3 : r4];
64
+ break;
65
#if TCG_TARGET_REG_BITS == 32
66
case INDEX_op_setcond2_i32:
67
tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
68
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
69
tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
70
regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
71
break;
72
+ case INDEX_op_movcond_i64:
73
+ tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
74
+ tmp32 = tci_compare64(regs[r1], regs[r2], condition);
75
+ regs[r0] = regs[tmp32 ? r3 : r4];
76
+ break;
77
#endif
78
CASE_32_64(mov)
79
tci_args_rr(insn, &r0, &r1);
80
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
81
op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
82
break;
83
84
-#if TCG_TARGET_REG_BITS == 32
85
+ case INDEX_op_movcond_i32:
86
+ case INDEX_op_movcond_i64:
87
case INDEX_op_setcond2_i32:
88
tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
89
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
90
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
91
str_r(r3), str_r(r4), str_c(c));
92
break;
93
94
+#if TCG_TARGET_REG_BITS == 32
95
case INDEX_op_mulu2_i32:
96
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
97
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
98
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
99
index XXXXXXX..XXXXXXX 100644
100
--- a/tcg/tci/tcg-target.c.inc
101
+++ b/tcg/tci/tcg-target.c.inc
102
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
103
return C_O0_I4(r, r, r, r);
104
case INDEX_op_mulu2_i32:
105
return C_O2_I2(r, r, r, r);
106
+#endif
107
+
108
+ case INDEX_op_movcond_i32:
109
+ case INDEX_op_movcond_i64:
110
case INDEX_op_setcond2_i32:
111
return C_O1_I4(r, r, r, r, r);
112
-#endif
113
114
case INDEX_op_qemu_ld_i32:
115
return (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
116
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
117
insn = deposit32(insn, 20, 4, r3);
118
tcg_out32(s, insn);
119
}
120
+#endif
121
122
static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
123
TCGReg r0, TCGReg r1, TCGReg r2,
124
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
125
tcg_out32(s, insn);
126
}
127
128
+#if TCG_TARGET_REG_BITS == 32
129
static void tcg_out_op_rrrrrr(TCGContext *s, TCGOpcode op,
130
TCGReg r0, TCGReg r1, TCGReg r2,
131
TCGReg r3, TCGReg r4, TCGReg r5)
132
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
133
tcg_out_op_rrrc(s, opc, args[0], args[1], args[2], args[3]);
134
break;
135
136
-#if TCG_TARGET_REG_BITS == 32
137
+ CASE_32_64(movcond)
138
case INDEX_op_setcond2_i32:
139
tcg_out_op_rrrrrc(s, opc, args[0], args[1], args[2],
140
args[3], args[4], args[5]);
141
break;
142
-#endif
143
144
CASE_32_64(ld8u)
145
CASE_32_64(ld8s)
146
--
147
2.25.1
148
149
diff view generated by jsdifflib
Deleted patch
1
These were already present in tcg-target.c.inc,
2
but not in the interpreter.
3
1
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
tcg/tci/tcg-target.h | 20 ++++++++++----------
9
tcg/tci.c | 40 ++++++++++++++++++++++++++++++++++++++++
10
2 files changed, 50 insertions(+), 10 deletions(-)
11
12
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/tci/tcg-target.h
15
+++ b/tcg/tci/tcg-target.h
16
@@ -XXX,XX +XXX,XX @@
17
#define TCG_TARGET_HAS_ext16s_i32 1
18
#define TCG_TARGET_HAS_ext8u_i32 1
19
#define TCG_TARGET_HAS_ext16u_i32 1
20
-#define TCG_TARGET_HAS_andc_i32 0
21
+#define TCG_TARGET_HAS_andc_i32 1
22
#define TCG_TARGET_HAS_deposit_i32 1
23
#define TCG_TARGET_HAS_extract_i32 0
24
#define TCG_TARGET_HAS_sextract_i32 0
25
#define TCG_TARGET_HAS_extract2_i32 0
26
-#define TCG_TARGET_HAS_eqv_i32 0
27
-#define TCG_TARGET_HAS_nand_i32 0
28
-#define TCG_TARGET_HAS_nor_i32 0
29
+#define TCG_TARGET_HAS_eqv_i32 1
30
+#define TCG_TARGET_HAS_nand_i32 1
31
+#define TCG_TARGET_HAS_nor_i32 1
32
#define TCG_TARGET_HAS_clz_i32 0
33
#define TCG_TARGET_HAS_ctz_i32 0
34
#define TCG_TARGET_HAS_ctpop_i32 0
35
#define TCG_TARGET_HAS_neg_i32 1
36
#define TCG_TARGET_HAS_not_i32 1
37
-#define TCG_TARGET_HAS_orc_i32 0
38
+#define TCG_TARGET_HAS_orc_i32 1
39
#define TCG_TARGET_HAS_rot_i32 1
40
#define TCG_TARGET_HAS_movcond_i32 1
41
#define TCG_TARGET_HAS_muls2_i32 0
42
@@ -XXX,XX +XXX,XX @@
43
#define TCG_TARGET_HAS_ext8u_i64 1
44
#define TCG_TARGET_HAS_ext16u_i64 1
45
#define TCG_TARGET_HAS_ext32u_i64 1
46
-#define TCG_TARGET_HAS_andc_i64 0
47
-#define TCG_TARGET_HAS_eqv_i64 0
48
-#define TCG_TARGET_HAS_nand_i64 0
49
-#define TCG_TARGET_HAS_nor_i64 0
50
+#define TCG_TARGET_HAS_andc_i64 1
51
+#define TCG_TARGET_HAS_eqv_i64 1
52
+#define TCG_TARGET_HAS_nand_i64 1
53
+#define TCG_TARGET_HAS_nor_i64 1
54
#define TCG_TARGET_HAS_clz_i64 0
55
#define TCG_TARGET_HAS_ctz_i64 0
56
#define TCG_TARGET_HAS_ctpop_i64 0
57
#define TCG_TARGET_HAS_neg_i64 1
58
#define TCG_TARGET_HAS_not_i64 1
59
-#define TCG_TARGET_HAS_orc_i64 0
60
+#define TCG_TARGET_HAS_orc_i64 1
61
#define TCG_TARGET_HAS_rot_i64 1
62
#define TCG_TARGET_HAS_movcond_i64 1
63
#define TCG_TARGET_HAS_muls2_i64 0
64
diff --git a/tcg/tci.c b/tcg/tci.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/tcg/tci.c
67
+++ b/tcg/tci.c
68
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
69
tci_args_rrr(insn, &r0, &r1, &r2);
70
regs[r0] = regs[r1] ^ regs[r2];
71
break;
72
+#if TCG_TARGET_HAS_andc_i32 || TCG_TARGET_HAS_andc_i64
73
+ CASE_32_64(andc)
74
+ tci_args_rrr(insn, &r0, &r1, &r2);
75
+ regs[r0] = regs[r1] & ~regs[r2];
76
+ break;
77
+#endif
78
+#if TCG_TARGET_HAS_orc_i32 || TCG_TARGET_HAS_orc_i64
79
+ CASE_32_64(orc)
80
+ tci_args_rrr(insn, &r0, &r1, &r2);
81
+ regs[r0] = regs[r1] | ~regs[r2];
82
+ break;
83
+#endif
84
+#if TCG_TARGET_HAS_eqv_i32 || TCG_TARGET_HAS_eqv_i64
85
+ CASE_32_64(eqv)
86
+ tci_args_rrr(insn, &r0, &r1, &r2);
87
+ regs[r0] = ~(regs[r1] ^ regs[r2]);
88
+ break;
89
+#endif
90
+#if TCG_TARGET_HAS_nand_i32 || TCG_TARGET_HAS_nand_i64
91
+ CASE_32_64(nand)
92
+ tci_args_rrr(insn, &r0, &r1, &r2);
93
+ regs[r0] = ~(regs[r1] & regs[r2]);
94
+ break;
95
+#endif
96
+#if TCG_TARGET_HAS_nor_i32 || TCG_TARGET_HAS_nor_i64
97
+ CASE_32_64(nor)
98
+ tci_args_rrr(insn, &r0, &r1, &r2);
99
+ regs[r0] = ~(regs[r1] | regs[r2]);
100
+ break;
101
+#endif
102
103
/* Arithmetic operations (32 bit). */
104
105
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
106
case INDEX_op_or_i64:
107
case INDEX_op_xor_i32:
108
case INDEX_op_xor_i64:
109
+ case INDEX_op_andc_i32:
110
+ case INDEX_op_andc_i64:
111
+ case INDEX_op_orc_i32:
112
+ case INDEX_op_orc_i64:
113
+ case INDEX_op_eqv_i32:
114
+ case INDEX_op_eqv_i64:
115
+ case INDEX_op_nand_i32:
116
+ case INDEX_op_nand_i64:
117
+ case INDEX_op_nor_i32:
118
+ case INDEX_op_nor_i64:
119
case INDEX_op_div_i32:
120
case INDEX_op_div_i64:
121
case INDEX_op_rem_i32:
122
--
123
2.25.1
124
125
diff view generated by jsdifflib
Deleted patch
1
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
tcg/tci/tcg-target.h | 8 ++++----
6
tcg/tci.c | 42 ++++++++++++++++++++++++++++++++++++++++
7
tcg/tci/tcg-target.c.inc | 32 ++++++++++++++++++++++++++++++
8
3 files changed, 78 insertions(+), 4 deletions(-)
9
1
10
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/tci/tcg-target.h
13
+++ b/tcg/tci/tcg-target.h
14
@@ -XXX,XX +XXX,XX @@
15
#define TCG_TARGET_HAS_ext16u_i32 1
16
#define TCG_TARGET_HAS_andc_i32 1
17
#define TCG_TARGET_HAS_deposit_i32 1
18
-#define TCG_TARGET_HAS_extract_i32 0
19
-#define TCG_TARGET_HAS_sextract_i32 0
20
+#define TCG_TARGET_HAS_extract_i32 1
21
+#define TCG_TARGET_HAS_sextract_i32 1
22
#define TCG_TARGET_HAS_extract2_i32 0
23
#define TCG_TARGET_HAS_eqv_i32 1
24
#define TCG_TARGET_HAS_nand_i32 1
25
@@ -XXX,XX +XXX,XX @@
26
#define TCG_TARGET_HAS_bswap32_i64 1
27
#define TCG_TARGET_HAS_bswap64_i64 1
28
#define TCG_TARGET_HAS_deposit_i64 1
29
-#define TCG_TARGET_HAS_extract_i64 0
30
-#define TCG_TARGET_HAS_sextract_i64 0
31
+#define TCG_TARGET_HAS_extract_i64 1
32
+#define TCG_TARGET_HAS_sextract_i64 1
33
#define TCG_TARGET_HAS_extract2_i64 0
34
#define TCG_TARGET_HAS_div_i64 1
35
#define TCG_TARGET_HAS_rem_i64 1
36
diff --git a/tcg/tci.c b/tcg/tci.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tcg/tci.c
39
+++ b/tcg/tci.c
40
@@ -XXX,XX +XXX,XX @@ static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
41
*i2 = sextract32(insn, 16, 16);
42
}
43
44
+static void tci_args_rrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
45
+ uint8_t *i2, uint8_t *i3)
46
+{
47
+ *r0 = extract32(insn, 8, 4);
48
+ *r1 = extract32(insn, 12, 4);
49
+ *i2 = extract32(insn, 16, 6);
50
+ *i3 = extract32(insn, 22, 6);
51
+}
52
+
53
static void tci_args_rrrc(uint32_t insn,
54
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
55
{
56
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
57
tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
58
regs[r0] = deposit32(regs[r1], pos, len, regs[r2]);
59
break;
60
+#endif
61
+#if TCG_TARGET_HAS_extract_i32
62
+ case INDEX_op_extract_i32:
63
+ tci_args_rrbb(insn, &r0, &r1, &pos, &len);
64
+ regs[r0] = extract32(regs[r1], pos, len);
65
+ break;
66
+#endif
67
+#if TCG_TARGET_HAS_sextract_i32
68
+ case INDEX_op_sextract_i32:
69
+ tci_args_rrbb(insn, &r0, &r1, &pos, &len);
70
+ regs[r0] = sextract32(regs[r1], pos, len);
71
+ break;
72
#endif
73
case INDEX_op_brcond_i32:
74
tci_args_rl(insn, tb_ptr, &r0, &ptr);
75
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
76
tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
77
regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
78
break;
79
+#endif
80
+#if TCG_TARGET_HAS_extract_i64
81
+ case INDEX_op_extract_i64:
82
+ tci_args_rrbb(insn, &r0, &r1, &pos, &len);
83
+ regs[r0] = extract64(regs[r1], pos, len);
84
+ break;
85
+#endif
86
+#if TCG_TARGET_HAS_sextract_i64
87
+ case INDEX_op_sextract_i64:
88
+ tci_args_rrbb(insn, &r0, &r1, &pos, &len);
89
+ regs[r0] = sextract64(regs[r1], pos, len);
90
+ break;
91
#endif
92
case INDEX_op_brcond_i64:
93
tci_args_rl(insn, tb_ptr, &r0, &ptr);
94
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
95
op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
96
break;
97
98
+ case INDEX_op_extract_i32:
99
+ case INDEX_op_extract_i64:
100
+ case INDEX_op_sextract_i32:
101
+ case INDEX_op_sextract_i64:
102
+ tci_args_rrbb(insn, &r0, &r1, &pos, &len);
103
+ info->fprintf_func(info->stream, "%-12s %s,%s,%d,%d",
104
+ op_name, str_r(r0), str_r(r1), pos, len);
105
+ break;
106
+
107
case INDEX_op_movcond_i32:
108
case INDEX_op_movcond_i64:
109
case INDEX_op_setcond2_i32:
110
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
111
index XXXXXXX..XXXXXXX 100644
112
--- a/tcg/tci/tcg-target.c.inc
113
+++ b/tcg/tci/tcg-target.c.inc
114
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
115
case INDEX_op_bswap32_i32:
116
case INDEX_op_bswap32_i64:
117
case INDEX_op_bswap64_i64:
118
+ case INDEX_op_extract_i32:
119
+ case INDEX_op_extract_i64:
120
+ case INDEX_op_sextract_i32:
121
+ case INDEX_op_sextract_i64:
122
return C_O1_I1(r, r);
123
124
case INDEX_op_st8_i32:
125
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rrs(TCGContext *s, TCGOpcode op,
126
tcg_out32(s, insn);
127
}
128
129
+static void tcg_out_op_rrbb(TCGContext *s, TCGOpcode op, TCGReg r0,
130
+ TCGReg r1, uint8_t b2, uint8_t b3)
131
+{
132
+ tcg_insn_unit insn = 0;
133
+
134
+ tcg_debug_assert(b2 == extract32(b2, 0, 6));
135
+ tcg_debug_assert(b3 == extract32(b3, 0, 6));
136
+ insn = deposit32(insn, 0, 8, op);
137
+ insn = deposit32(insn, 8, 4, r0);
138
+ insn = deposit32(insn, 12, 4, r1);
139
+ insn = deposit32(insn, 16, 6, b2);
140
+ insn = deposit32(insn, 22, 6, b3);
141
+ tcg_out32(s, insn);
142
+}
143
+
144
static void tcg_out_op_rrrc(TCGContext *s, TCGOpcode op,
145
TCGReg r0, TCGReg r1, TCGReg r2, TCGCond c3)
146
{
147
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
148
}
149
break;
150
151
+ CASE_32_64(extract) /* Optional (TCG_TARGET_HAS_extract_*). */
152
+ CASE_32_64(sextract) /* Optional (TCG_TARGET_HAS_sextract_*). */
153
+ {
154
+ TCGArg pos = args[2], len = args[3];
155
+ TCGArg max = tcg_op_defs[opc].flags & TCG_OPF_64BIT ? 64 : 32;
156
+
157
+ tcg_debug_assert(pos < max);
158
+ tcg_debug_assert(pos + len <= max);
159
+
160
+ tcg_out_op_rrbb(s, opc, args[0], args[1], pos, len);
161
+ }
162
+ break;
163
+
164
CASE_32_64(brcond)
165
tcg_out_op_rrrc(s, (opc == INDEX_op_brcond_i32
166
? INDEX_op_setcond_i32 : INDEX_op_setcond_i64),
167
--
168
2.25.1
169
170
diff view generated by jsdifflib
Deleted patch
1
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
tcg/tci/tcg-target.h | 12 +++++------
6
tcg/tci.c | 44 ++++++++++++++++++++++++++++++++++++++++
7
tcg/tci/tcg-target.c.inc | 9 ++++++++
8
3 files changed, 59 insertions(+), 6 deletions(-)
9
1
10
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/tci/tcg-target.h
13
+++ b/tcg/tci/tcg-target.h
14
@@ -XXX,XX +XXX,XX @@
15
#define TCG_TARGET_HAS_eqv_i32 1
16
#define TCG_TARGET_HAS_nand_i32 1
17
#define TCG_TARGET_HAS_nor_i32 1
18
-#define TCG_TARGET_HAS_clz_i32 0
19
-#define TCG_TARGET_HAS_ctz_i32 0
20
-#define TCG_TARGET_HAS_ctpop_i32 0
21
+#define TCG_TARGET_HAS_clz_i32 1
22
+#define TCG_TARGET_HAS_ctz_i32 1
23
+#define TCG_TARGET_HAS_ctpop_i32 1
24
#define TCG_TARGET_HAS_neg_i32 1
25
#define TCG_TARGET_HAS_not_i32 1
26
#define TCG_TARGET_HAS_orc_i32 1
27
@@ -XXX,XX +XXX,XX @@
28
#define TCG_TARGET_HAS_eqv_i64 1
29
#define TCG_TARGET_HAS_nand_i64 1
30
#define TCG_TARGET_HAS_nor_i64 1
31
-#define TCG_TARGET_HAS_clz_i64 0
32
-#define TCG_TARGET_HAS_ctz_i64 0
33
-#define TCG_TARGET_HAS_ctpop_i64 0
34
+#define TCG_TARGET_HAS_clz_i64 1
35
+#define TCG_TARGET_HAS_ctz_i64 1
36
+#define TCG_TARGET_HAS_ctpop_i64 1
37
#define TCG_TARGET_HAS_neg_i64 1
38
#define TCG_TARGET_HAS_not_i64 1
39
#define TCG_TARGET_HAS_orc_i64 1
40
diff --git a/tcg/tci.c b/tcg/tci.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/tcg/tci.c
43
+++ b/tcg/tci.c
44
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
45
tci_args_rrr(insn, &r0, &r1, &r2);
46
regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
47
break;
48
+#if TCG_TARGET_HAS_clz_i32
49
+ case INDEX_op_clz_i32:
50
+ tci_args_rrr(insn, &r0, &r1, &r2);
51
+ tmp32 = regs[r1];
52
+ regs[r0] = tmp32 ? clz32(tmp32) : regs[r2];
53
+ break;
54
+#endif
55
+#if TCG_TARGET_HAS_ctz_i32
56
+ case INDEX_op_ctz_i32:
57
+ tci_args_rrr(insn, &r0, &r1, &r2);
58
+ tmp32 = regs[r1];
59
+ regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2];
60
+ break;
61
+#endif
62
+#if TCG_TARGET_HAS_ctpop_i32
63
+ case INDEX_op_ctpop_i32:
64
+ tci_args_rr(insn, &r0, &r1);
65
+ regs[r0] = ctpop32(regs[r1]);
66
+ break;
67
+#endif
68
69
/* Shift/rotate operations (32 bit). */
70
71
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
72
tci_args_rrr(insn, &r0, &r1, &r2);
73
regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
74
break;
75
+#if TCG_TARGET_HAS_clz_i64
76
+ case INDEX_op_clz_i64:
77
+ tci_args_rrr(insn, &r0, &r1, &r2);
78
+ regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2];
79
+ break;
80
+#endif
81
+#if TCG_TARGET_HAS_ctz_i64
82
+ case INDEX_op_ctz_i64:
83
+ tci_args_rrr(insn, &r0, &r1, &r2);
84
+ regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2];
85
+ break;
86
+#endif
87
+#if TCG_TARGET_HAS_ctpop_i64
88
+ case INDEX_op_ctpop_i64:
89
+ tci_args_rr(insn, &r0, &r1);
90
+ regs[r0] = ctpop64(regs[r1]);
91
+ break;
92
+#endif
93
94
/* Shift/rotate operations (64 bit). */
95
96
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
97
case INDEX_op_not_i64:
98
case INDEX_op_neg_i32:
99
case INDEX_op_neg_i64:
100
+ case INDEX_op_ctpop_i32:
101
+ case INDEX_op_ctpop_i64:
102
tci_args_rr(insn, &r0, &r1);
103
info->fprintf_func(info->stream, "%-12s %s, %s",
104
op_name, str_r(r0), str_r(r1));
105
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
106
case INDEX_op_rotl_i64:
107
case INDEX_op_rotr_i32:
108
case INDEX_op_rotr_i64:
109
+ case INDEX_op_clz_i32:
110
+ case INDEX_op_clz_i64:
111
+ case INDEX_op_ctz_i32:
112
+ case INDEX_op_ctz_i64:
113
tci_args_rrr(insn, &r0, &r1, &r2);
114
info->fprintf_func(info->stream, "%-12s %s, %s, %s",
115
op_name, str_r(r0), str_r(r1), str_r(r2));
116
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
117
index XXXXXXX..XXXXXXX 100644
118
--- a/tcg/tci/tcg-target.c.inc
119
+++ b/tcg/tci/tcg-target.c.inc
120
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
121
case INDEX_op_extract_i64:
122
case INDEX_op_sextract_i32:
123
case INDEX_op_sextract_i64:
124
+ case INDEX_op_ctpop_i32:
125
+ case INDEX_op_ctpop_i64:
126
return C_O1_I1(r, r);
127
128
case INDEX_op_st8_i32:
129
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
130
case INDEX_op_setcond_i64:
131
case INDEX_op_deposit_i32:
132
case INDEX_op_deposit_i64:
133
+ case INDEX_op_clz_i32:
134
+ case INDEX_op_clz_i64:
135
+ case INDEX_op_ctz_i32:
136
+ case INDEX_op_ctz_i64:
137
return C_O1_I2(r, r, r);
138
139
case INDEX_op_brcond_i32:
140
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
141
CASE_32_64(divu) /* Optional (TCG_TARGET_HAS_div_*). */
142
CASE_32_64(rem) /* Optional (TCG_TARGET_HAS_div_*). */
143
CASE_32_64(remu) /* Optional (TCG_TARGET_HAS_div_*). */
144
+ CASE_32_64(clz) /* Optional (TCG_TARGET_HAS_clz_*). */
145
+ CASE_32_64(ctz) /* Optional (TCG_TARGET_HAS_ctz_*). */
146
tcg_out_op_rrr(s, opc, args[0], args[1], args[2]);
147
break;
148
149
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
150
CASE_32_64(bswap16) /* Optional (TCG_TARGET_HAS_bswap16_*). */
151
CASE_32_64(bswap32) /* Optional (TCG_TARGET_HAS_bswap32_*). */
152
CASE_64(bswap64) /* Optional (TCG_TARGET_HAS_bswap64_i64). */
153
+ CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */
154
tcg_out_op_rr(s, opc, args[0], args[1]);
155
break;
156
157
--
158
2.25.1
159
160
diff view generated by jsdifflib
Deleted patch
1
We already had mulu2_i32 for a 32-bit host; expand this to 64-bit
2
hosts as well. The muls2_i32 and the 64-bit opcodes are new.
3
1
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
tcg/tci/tcg-target.h | 8 ++++----
9
tcg/tci.c | 35 +++++++++++++++++++++++++++++------
10
tcg/tci/tcg-target.c.inc | 16 ++++++++++------
11
3 files changed, 43 insertions(+), 16 deletions(-)
12
13
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tcg/tci/tcg-target.h
16
+++ b/tcg/tci/tcg-target.h
17
@@ -XXX,XX +XXX,XX @@
18
#define TCG_TARGET_HAS_orc_i32 1
19
#define TCG_TARGET_HAS_rot_i32 1
20
#define TCG_TARGET_HAS_movcond_i32 1
21
-#define TCG_TARGET_HAS_muls2_i32 0
22
+#define TCG_TARGET_HAS_muls2_i32 1
23
#define TCG_TARGET_HAS_muluh_i32 0
24
#define TCG_TARGET_HAS_mulsh_i32 0
25
#define TCG_TARGET_HAS_goto_ptr 1
26
@@ -XXX,XX +XXX,XX @@
27
#define TCG_TARGET_HAS_orc_i64 1
28
#define TCG_TARGET_HAS_rot_i64 1
29
#define TCG_TARGET_HAS_movcond_i64 1
30
-#define TCG_TARGET_HAS_muls2_i64 0
31
+#define TCG_TARGET_HAS_muls2_i64 1
32
#define TCG_TARGET_HAS_add2_i32 0
33
#define TCG_TARGET_HAS_sub2_i32 0
34
-#define TCG_TARGET_HAS_mulu2_i32 0
35
+#define TCG_TARGET_HAS_mulu2_i32 1
36
#define TCG_TARGET_HAS_add2_i64 0
37
#define TCG_TARGET_HAS_sub2_i64 0
38
-#define TCG_TARGET_HAS_mulu2_i64 0
39
+#define TCG_TARGET_HAS_mulu2_i64 1
40
#define TCG_TARGET_HAS_muluh_i64 0
41
#define TCG_TARGET_HAS_mulsh_i64 0
42
#else
43
diff --git a/tcg/tci.c b/tcg/tci.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/tcg/tci.c
46
+++ b/tcg/tci.c
47
@@ -XXX,XX +XXX,XX @@ __thread uintptr_t tci_tb_ptr;
48
static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index,
49
uint32_t low_index, uint64_t value)
50
{
51
- regs[low_index] = value;
52
+ regs[low_index] = (uint32_t)value;
53
regs[high_index] = value >> 32;
54
}
55
56
@@ -XXX,XX +XXX,XX @@ static void tci_args_rrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
57
*r4 = extract32(insn, 24, 4);
58
}
59
60
-#if TCG_TARGET_REG_BITS == 32
61
static void tci_args_rrrr(uint32_t insn,
62
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
63
{
64
@@ -XXX,XX +XXX,XX @@ static void tci_args_rrrr(uint32_t insn,
65
*r2 = extract32(insn, 16, 4);
66
*r3 = extract32(insn, 20, 4);
67
}
68
-#endif
69
70
static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
71
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
72
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
73
T2 = tci_uint64(regs[r5], regs[r4]);
74
tci_write_reg64(regs, r1, r0, T1 - T2);
75
break;
76
+#endif /* TCG_TARGET_REG_BITS == 32 */
77
+#if TCG_TARGET_HAS_mulu2_i32
78
case INDEX_op_mulu2_i32:
79
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
80
- tci_write_reg64(regs, r1, r0, (uint64_t)regs[r2] * regs[r3]);
81
+ tmp64 = (uint64_t)(uint32_t)regs[r2] * (uint32_t)regs[r3];
82
+ tci_write_reg64(regs, r1, r0, tmp64);
83
break;
84
-#endif /* TCG_TARGET_REG_BITS == 32 */
85
+#endif
86
+#if TCG_TARGET_HAS_muls2_i32
87
+ case INDEX_op_muls2_i32:
88
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
89
+ tmp64 = (int64_t)(int32_t)regs[r2] * (int32_t)regs[r3];
90
+ tci_write_reg64(regs, r1, r0, tmp64);
91
+ break;
92
+#endif
93
#if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
94
CASE_32_64(ext8s)
95
tci_args_rr(insn, &r0, &r1);
96
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
97
regs[r0] = ctpop64(regs[r1]);
98
break;
99
#endif
100
+#if TCG_TARGET_HAS_mulu2_i64
101
+ case INDEX_op_mulu2_i64:
102
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
103
+ mulu64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
104
+ break;
105
+#endif
106
+#if TCG_TARGET_HAS_muls2_i64
107
+ case INDEX_op_muls2_i64:
108
+ tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
109
+ muls64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
110
+ break;
111
+#endif
112
113
/* Shift/rotate operations (64 bit). */
114
115
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
116
str_r(r3), str_r(r4), str_c(c));
117
break;
118
119
-#if TCG_TARGET_REG_BITS == 32
120
case INDEX_op_mulu2_i32:
121
+ case INDEX_op_mulu2_i64:
122
+ case INDEX_op_muls2_i32:
123
+ case INDEX_op_muls2_i64:
124
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
125
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
126
op_name, str_r(r0), str_r(r1),
127
str_r(r2), str_r(r3));
128
break;
129
130
+#if TCG_TARGET_REG_BITS == 32
131
case INDEX_op_add2_i32:
132
case INDEX_op_sub2_i32:
133
tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
134
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
135
index XXXXXXX..XXXXXXX 100644
136
--- a/tcg/tci/tcg-target.c.inc
137
+++ b/tcg/tci/tcg-target.c.inc
138
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
139
return C_O2_I4(r, r, r, r, r, r);
140
case INDEX_op_brcond2_i32:
141
return C_O0_I4(r, r, r, r);
142
- case INDEX_op_mulu2_i32:
143
- return C_O2_I2(r, r, r, r);
144
#endif
145
146
+ case INDEX_op_mulu2_i32:
147
+ case INDEX_op_mulu2_i64:
148
+ case INDEX_op_muls2_i32:
149
+ case INDEX_op_muls2_i64:
150
+ return C_O2_I2(r, r, r, r);
151
+
152
case INDEX_op_movcond_i32:
153
case INDEX_op_movcond_i64:
154
case INDEX_op_setcond2_i32:
155
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rrrrr(TCGContext *s, TCGOpcode op, TCGReg r0,
156
tcg_out32(s, insn);
157
}
158
159
-#if TCG_TARGET_REG_BITS == 32
160
static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
161
TCGReg r0, TCGReg r1, TCGReg r2, TCGReg r3)
162
{
163
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rrrr(TCGContext *s, TCGOpcode op,
164
insn = deposit32(insn, 20, 4, r3);
165
tcg_out32(s, insn);
166
}
167
-#endif
168
169
static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
170
TCGReg r0, TCGReg r1, TCGReg r2,
171
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
172
args[0], args[1], args[2], args[3], args[4]);
173
tcg_out_op_rl(s, INDEX_op_brcond_i32, TCG_REG_TMP, arg_label(args[5]));
174
break;
175
- case INDEX_op_mulu2_i32:
176
+#endif
177
+
178
+ CASE_32_64(mulu2)
179
+ CASE_32_64(muls2)
180
tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], args[3]);
181
break;
182
-#endif
183
184
case INDEX_op_qemu_ld_i32:
185
case INDEX_op_qemu_st_i32:
186
--
187
2.25.1
188
189
diff view generated by jsdifflib
Deleted patch
1
We already had the 32-bit versions for a 32-bit host; expand this
2
to 64-bit hosts as well. The 64-bit opcodes are new.
3
1
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
tcg/tci/tcg-target.h | 8 ++++----
9
tcg/tci.c | 40 ++++++++++++++++++++++++++--------------
10
tcg/tci/tcg-target.c.inc | 15 ++++++++-------
11
3 files changed, 38 insertions(+), 25 deletions(-)
12
13
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tcg/tci/tcg-target.h
16
+++ b/tcg/tci/tcg-target.h
17
@@ -XXX,XX +XXX,XX @@
18
#define TCG_TARGET_HAS_rot_i64 1
19
#define TCG_TARGET_HAS_movcond_i64 1
20
#define TCG_TARGET_HAS_muls2_i64 1
21
-#define TCG_TARGET_HAS_add2_i32 0
22
-#define TCG_TARGET_HAS_sub2_i32 0
23
+#define TCG_TARGET_HAS_add2_i32 1
24
+#define TCG_TARGET_HAS_sub2_i32 1
25
#define TCG_TARGET_HAS_mulu2_i32 1
26
-#define TCG_TARGET_HAS_add2_i64 0
27
-#define TCG_TARGET_HAS_sub2_i64 0
28
+#define TCG_TARGET_HAS_add2_i64 1
29
+#define TCG_TARGET_HAS_sub2_i64 1
30
#define TCG_TARGET_HAS_mulu2_i64 1
31
#define TCG_TARGET_HAS_muluh_i64 0
32
#define TCG_TARGET_HAS_mulsh_i64 0
33
diff --git a/tcg/tci.c b/tcg/tci.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/tcg/tci.c
36
+++ b/tcg/tci.c
37
@@ -XXX,XX +XXX,XX @@ static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
38
*c5 = extract32(insn, 28, 4);
39
}
40
41
-#if TCG_TARGET_REG_BITS == 32
42
static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
43
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGReg *r5)
44
{
45
@@ -XXX,XX +XXX,XX @@ static void tci_args_rrrrrr(uint32_t insn, TCGReg *r0, TCGReg *r1,
46
*r4 = extract32(insn, 24, 4);
47
*r5 = extract32(insn, 28, 4);
48
}
49
-#endif
50
51
static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
52
{
53
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
54
for (;;) {
55
uint32_t insn;
56
TCGOpcode opc;
57
- TCGReg r0, r1, r2, r3, r4;
58
+ TCGReg r0, r1, r2, r3, r4, r5;
59
tcg_target_ulong t1;
60
TCGCond condition;
61
target_ulong taddr;
62
uint8_t pos, len;
63
uint32_t tmp32;
64
uint64_t tmp64;
65
-#if TCG_TARGET_REG_BITS == 32
66
- TCGReg r5;
67
uint64_t T1, T2;
68
-#endif
69
TCGMemOpIdx oi;
70
int32_t ofs;
71
void *ptr;
72
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
73
tb_ptr = ptr;
74
}
75
break;
76
-#if TCG_TARGET_REG_BITS == 32
77
+#if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_add2_i32
78
case INDEX_op_add2_i32:
79
tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
80
T1 = tci_uint64(regs[r3], regs[r2]);
81
T2 = tci_uint64(regs[r5], regs[r4]);
82
tci_write_reg64(regs, r1, r0, T1 + T2);
83
break;
84
+#endif
85
+#if TCG_TARGET_REG_BITS == 32 || TCG_TARGET_HAS_sub2_i32
86
case INDEX_op_sub2_i32:
87
tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
88
T1 = tci_uint64(regs[r3], regs[r2]);
89
T2 = tci_uint64(regs[r5], regs[r4]);
90
tci_write_reg64(regs, r1, r0, T1 - T2);
91
break;
92
-#endif /* TCG_TARGET_REG_BITS == 32 */
93
+#endif
94
#if TCG_TARGET_HAS_mulu2_i32
95
case INDEX_op_mulu2_i32:
96
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
97
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
98
muls64(&regs[r0], &regs[r1], regs[r2], regs[r3]);
99
break;
100
#endif
101
+#if TCG_TARGET_HAS_add2_i64
102
+ case INDEX_op_add2_i64:
103
+ tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
104
+ T1 = regs[r2] + regs[r4];
105
+ T2 = regs[r3] + regs[r5] + (T1 < regs[r2]);
106
+ regs[r0] = T1;
107
+ regs[r1] = T2;
108
+ break;
109
+#endif
110
+#if TCG_TARGET_HAS_add2_i64
111
+ case INDEX_op_sub2_i64:
112
+ tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
113
+ T1 = regs[r2] - regs[r4];
114
+ T2 = regs[r3] - regs[r5] - (regs[r2] < regs[r4]);
115
+ regs[r0] = T1;
116
+ regs[r1] = T2;
117
+ break;
118
+#endif
119
120
/* Shift/rotate operations (64 bit). */
121
122
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
123
const char *op_name;
124
uint32_t insn;
125
TCGOpcode op;
126
- TCGReg r0, r1, r2, r3, r4;
127
-#if TCG_TARGET_REG_BITS == 32
128
- TCGReg r5;
129
-#endif
130
+ TCGReg r0, r1, r2, r3, r4, r5;
131
tcg_target_ulong i1;
132
int32_t s2;
133
TCGCond c;
134
@@ -XXX,XX +XXX,XX @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
135
str_r(r2), str_r(r3));
136
break;
137
138
-#if TCG_TARGET_REG_BITS == 32
139
case INDEX_op_add2_i32:
140
+ case INDEX_op_add2_i64:
141
case INDEX_op_sub2_i32:
142
+ case INDEX_op_sub2_i64:
143
tci_args_rrrrrr(insn, &r0, &r1, &r2, &r3, &r4, &r5);
144
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
145
op_name, str_r(r0), str_r(r1), str_r(r2),
146
str_r(r3), str_r(r4), str_r(r5));
147
break;
148
-#endif
149
150
case INDEX_op_qemu_ld_i64:
151
case INDEX_op_qemu_st_i64:
152
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
153
index XXXXXXX..XXXXXXX 100644
154
--- a/tcg/tci/tcg-target.c.inc
155
+++ b/tcg/tci/tcg-target.c.inc
156
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
157
case INDEX_op_brcond_i64:
158
return C_O0_I2(r, r);
159
160
-#if TCG_TARGET_REG_BITS == 32
161
- /* TODO: Support R, R, R, R, RI, RI? Will it be faster? */
162
case INDEX_op_add2_i32:
163
+ case INDEX_op_add2_i64:
164
case INDEX_op_sub2_i32:
165
+ case INDEX_op_sub2_i64:
166
return C_O2_I4(r, r, r, r, r, r);
167
+
168
+#if TCG_TARGET_REG_BITS == 32
169
case INDEX_op_brcond2_i32:
170
return C_O0_I4(r, r, r, r);
171
#endif
172
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
173
tcg_out32(s, insn);
174
}
175
176
-#if TCG_TARGET_REG_BITS == 32
177
static void tcg_out_op_rrrrrr(TCGContext *s, TCGOpcode op,
178
TCGReg r0, TCGReg r1, TCGReg r2,
179
TCGReg r3, TCGReg r4, TCGReg r5)
180
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op_rrrrrr(TCGContext *s, TCGOpcode op,
181
insn = deposit32(insn, 28, 4, r5);
182
tcg_out32(s, insn);
183
}
184
-#endif
185
186
static void tcg_out_ldst(TCGContext *s, TCGOpcode op, TCGReg val,
187
TCGReg base, intptr_t offset)
188
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
189
tcg_out_op_rr(s, opc, args[0], args[1]);
190
break;
191
192
-#if TCG_TARGET_REG_BITS == 32
193
- case INDEX_op_add2_i32:
194
- case INDEX_op_sub2_i32:
195
+ CASE_32_64(add2)
196
+ CASE_32_64(sub2)
197
tcg_out_op_rrrrrr(s, opc, args[0], args[1], args[2],
198
args[3], args[4], args[5]);
199
break;
200
+
201
+#if TCG_TARGET_REG_BITS == 32
202
case INDEX_op_brcond2_i32:
203
tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, TCG_REG_TMP,
204
args[0], args[1], args[2], args[3], args[4]);
205
--
206
2.25.1
207
208
diff view generated by jsdifflib
Deleted patch
1
We can share this code between 32-bit and 64-bit loads and stores.
2
1
3
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/tci.c | 183 +++++++++++++++++++++---------------------------------
8
1 file changed, 71 insertions(+), 112 deletions(-)
9
10
diff --git a/tcg/tci.c b/tcg/tci.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/tci.c
13
+++ b/tcg/tci.c
14
@@ -XXX,XX +XXX,XX @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
15
#define qemu_st_beq(X) \
16
cpu_stq_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
17
18
+static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr,
19
+ TCGMemOpIdx oi, const void *tb_ptr)
20
+{
21
+ MemOp mop = get_memop(oi) & (MO_BSWAP | MO_SSIZE);
22
+
23
+ switch (mop) {
24
+ case MO_UB:
25
+ return qemu_ld_ub;
26
+ case MO_SB:
27
+ return (int8_t)qemu_ld_ub;
28
+ case MO_LEUW:
29
+ return qemu_ld_leuw;
30
+ case MO_LESW:
31
+ return (int16_t)qemu_ld_leuw;
32
+ case MO_LEUL:
33
+ return qemu_ld_leul;
34
+ case MO_LESL:
35
+ return (int32_t)qemu_ld_leul;
36
+ case MO_LEQ:
37
+ return qemu_ld_leq;
38
+ case MO_BEUW:
39
+ return qemu_ld_beuw;
40
+ case MO_BESW:
41
+ return (int16_t)qemu_ld_beuw;
42
+ case MO_BEUL:
43
+ return qemu_ld_beul;
44
+ case MO_BESL:
45
+ return (int32_t)qemu_ld_beul;
46
+ case MO_BEQ:
47
+ return qemu_ld_beq;
48
+ default:
49
+ g_assert_not_reached();
50
+ }
51
+}
52
+
53
+static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val,
54
+ TCGMemOpIdx oi, const void *tb_ptr)
55
+{
56
+ MemOp mop = get_memop(oi) & (MO_BSWAP | MO_SSIZE);
57
+
58
+ switch (mop) {
59
+ case MO_UB:
60
+ qemu_st_b(val);
61
+ break;
62
+ case MO_LEUW:
63
+ qemu_st_lew(val);
64
+ break;
65
+ case MO_LEUL:
66
+ qemu_st_lel(val);
67
+ break;
68
+ case MO_LEQ:
69
+ qemu_st_leq(val);
70
+ break;
71
+ case MO_BEUW:
72
+ qemu_st_bew(val);
73
+ break;
74
+ case MO_BEUL:
75
+ qemu_st_bel(val);
76
+ break;
77
+ case MO_BEQ:
78
+ qemu_st_beq(val);
79
+ break;
80
+ default:
81
+ g_assert_not_reached();
82
+ }
83
+}
84
+
85
#if TCG_TARGET_REG_BITS == 64
86
# define CASE_32_64(x) \
87
case glue(glue(INDEX_op_, x), _i64): \
88
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
89
tci_args_rrrm(insn, &r0, &r1, &r2, &oi);
90
taddr = tci_uint64(regs[r2], regs[r1]);
91
}
92
- switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
93
- case MO_UB:
94
- tmp32 = qemu_ld_ub;
95
- break;
96
- case MO_SB:
97
- tmp32 = (int8_t)qemu_ld_ub;
98
- break;
99
- case MO_LEUW:
100
- tmp32 = qemu_ld_leuw;
101
- break;
102
- case MO_LESW:
103
- tmp32 = (int16_t)qemu_ld_leuw;
104
- break;
105
- case MO_LEUL:
106
- tmp32 = qemu_ld_leul;
107
- break;
108
- case MO_BEUW:
109
- tmp32 = qemu_ld_beuw;
110
- break;
111
- case MO_BESW:
112
- tmp32 = (int16_t)qemu_ld_beuw;
113
- break;
114
- case MO_BEUL:
115
- tmp32 = qemu_ld_beul;
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
120
+ tmp32 = tci_qemu_ld(env, taddr, oi, tb_ptr);
121
regs[r0] = tmp32;
122
break;
123
124
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
125
taddr = tci_uint64(regs[r3], regs[r2]);
126
oi = regs[r4];
127
}
128
- switch (get_memop(oi) & (MO_BSWAP | MO_SSIZE)) {
129
- case MO_UB:
130
- tmp64 = qemu_ld_ub;
131
- break;
132
- case MO_SB:
133
- tmp64 = (int8_t)qemu_ld_ub;
134
- break;
135
- case MO_LEUW:
136
- tmp64 = qemu_ld_leuw;
137
- break;
138
- case MO_LESW:
139
- tmp64 = (int16_t)qemu_ld_leuw;
140
- break;
141
- case MO_LEUL:
142
- tmp64 = qemu_ld_leul;
143
- break;
144
- case MO_LESL:
145
- tmp64 = (int32_t)qemu_ld_leul;
146
- break;
147
- case MO_LEQ:
148
- tmp64 = qemu_ld_leq;
149
- break;
150
- case MO_BEUW:
151
- tmp64 = qemu_ld_beuw;
152
- break;
153
- case MO_BESW:
154
- tmp64 = (int16_t)qemu_ld_beuw;
155
- break;
156
- case MO_BEUL:
157
- tmp64 = qemu_ld_beul;
158
- break;
159
- case MO_BESL:
160
- tmp64 = (int32_t)qemu_ld_beul;
161
- break;
162
- case MO_BEQ:
163
- tmp64 = qemu_ld_beq;
164
- break;
165
- default:
166
- g_assert_not_reached();
167
- }
168
+ tmp64 = tci_qemu_ld(env, taddr, oi, tb_ptr);
169
if (TCG_TARGET_REG_BITS == 32) {
170
tci_write_reg64(regs, r1, r0, tmp64);
171
} else {
172
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
173
taddr = tci_uint64(regs[r2], regs[r1]);
174
}
175
tmp32 = regs[r0];
176
- switch (get_memop(oi) & (MO_BSWAP | MO_SIZE)) {
177
- case MO_UB:
178
- qemu_st_b(tmp32);
179
- break;
180
- case MO_LEUW:
181
- qemu_st_lew(tmp32);
182
- break;
183
- case MO_LEUL:
184
- qemu_st_lel(tmp32);
185
- break;
186
- case MO_BEUW:
187
- qemu_st_bew(tmp32);
188
- break;
189
- case MO_BEUL:
190
- qemu_st_bel(tmp32);
191
- break;
192
- default:
193
- g_assert_not_reached();
194
- }
195
+ tci_qemu_st(env, taddr, tmp32, oi, tb_ptr);
196
break;
197
198
case INDEX_op_qemu_st_i64:
199
@@ -XXX,XX +XXX,XX @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
200
}
201
tmp64 = tci_uint64(regs[r1], regs[r0]);
202
}
203
- switch (get_memop(oi) & (MO_BSWAP | MO_SIZE)) {
204
- case MO_UB:
205
- qemu_st_b(tmp64);
206
- break;
207
- case MO_LEUW:
208
- qemu_st_lew(tmp64);
209
- break;
210
- case MO_LEUL:
211
- qemu_st_lel(tmp64);
212
- break;
213
- case MO_LEQ:
214
- qemu_st_leq(tmp64);
215
- break;
216
- case MO_BEUW:
217
- qemu_st_bew(tmp64);
218
- break;
219
- case MO_BEUL:
220
- qemu_st_bel(tmp64);
221
- break;
222
- case MO_BEQ:
223
- qemu_st_beq(tmp64);
224
- break;
225
- default:
226
- g_assert_not_reached();
227
- }
228
+ tci_qemu_st(env, taddr, tmp64, oi, tb_ptr);
229
break;
230
231
case INDEX_op_mb:
232
--
233
2.25.1
234
235
diff view generated by jsdifflib
Deleted patch
1
This reverts commit dc09f047eddec8f4a1991c4f5f4a428d7aa3f2c0.
2
1
3
For tcg, tracepoints are expanded inline in tcg opcodes.
4
Using a helper which generates a second tracepoint is incorrect.
5
6
For system mode, the extraction and re-packing of MemOp and mmu_idx
7
lost the alignment information from MemOp. So we were no longer
8
raising alignment exceptions for !TARGET_ALIGNED_ONLY guests.
9
This can be seen in tests/tcg/xtensa/test_load_store.S.
10
11
For user mode, we must update to the new signature of g2h() so that
12
the revert compiles. We can leave set_helper_retaddr for later.
13
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
---
18
tcg/tci.c | 73 ++++++++++++++++++++++++++++++++++---------------------
19
1 file changed, 45 insertions(+), 28 deletions(-)
20
21
diff --git a/tcg/tci.c b/tcg/tci.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/tcg/tci.c
24
+++ b/tcg/tci.c
25
@@ -XXX,XX +XXX,XX @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
26
return result;
27
}
28
29
-#define qemu_ld_ub \
30
- cpu_ldub_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
31
-#define qemu_ld_leuw \
32
- cpu_lduw_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
33
-#define qemu_ld_leul \
34
- cpu_ldl_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
35
-#define qemu_ld_leq \
36
- cpu_ldq_le_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
37
-#define qemu_ld_beuw \
38
- cpu_lduw_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
39
-#define qemu_ld_beul \
40
- cpu_ldl_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
41
-#define qemu_ld_beq \
42
- cpu_ldq_be_mmuidx_ra(env, taddr, get_mmuidx(oi), (uintptr_t)tb_ptr)
43
-#define qemu_st_b(X) \
44
- cpu_stb_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
45
-#define qemu_st_lew(X) \
46
- cpu_stw_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
47
-#define qemu_st_lel(X) \
48
- cpu_stl_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
49
-#define qemu_st_leq(X) \
50
- cpu_stq_le_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
51
-#define qemu_st_bew(X) \
52
- cpu_stw_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
53
-#define qemu_st_bel(X) \
54
- cpu_stl_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
55
-#define qemu_st_beq(X) \
56
- cpu_stq_be_mmuidx_ra(env, taddr, X, get_mmuidx(oi), (uintptr_t)tb_ptr)
57
+#ifdef CONFIG_SOFTMMU
58
+# define qemu_ld_ub \
59
+ helper_ret_ldub_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
60
+# define qemu_ld_leuw \
61
+ helper_le_lduw_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
62
+# define qemu_ld_leul \
63
+ helper_le_ldul_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
64
+# define qemu_ld_leq \
65
+ helper_le_ldq_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
66
+# define qemu_ld_beuw \
67
+ helper_be_lduw_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
68
+# define qemu_ld_beul \
69
+ helper_be_ldul_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
70
+# define qemu_ld_beq \
71
+ helper_be_ldq_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
72
+# define qemu_st_b(X) \
73
+ helper_ret_stb_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
74
+# define qemu_st_lew(X) \
75
+ helper_le_stw_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
76
+# define qemu_st_lel(X) \
77
+ helper_le_stl_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
78
+# define qemu_st_leq(X) \
79
+ helper_le_stq_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
80
+# define qemu_st_bew(X) \
81
+ helper_be_stw_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
82
+# define qemu_st_bel(X) \
83
+ helper_be_stl_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
84
+# define qemu_st_beq(X) \
85
+ helper_be_stq_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
86
+#else
87
+# define qemu_ld_ub ldub_p(g2h(env_cpu(env), taddr))
88
+# define qemu_ld_leuw lduw_le_p(g2h(env_cpu(env), taddr))
89
+# define qemu_ld_leul (uint32_t)ldl_le_p(g2h(env_cpu(env), taddr))
90
+# define qemu_ld_leq ldq_le_p(g2h(env_cpu(env), taddr))
91
+# define qemu_ld_beuw lduw_be_p(g2h(env_cpu(env), taddr))
92
+# define qemu_ld_beul (uint32_t)ldl_be_p(g2h(env_cpu(env), taddr))
93
+# define qemu_ld_beq ldq_be_p(g2h(env_cpu(env), taddr))
94
+# define qemu_st_b(X) stb_p(g2h(env_cpu(env), taddr), X)
95
+# define qemu_st_lew(X) stw_le_p(g2h(env_cpu(env), taddr), X)
96
+# define qemu_st_lel(X) stl_le_p(g2h(env_cpu(env), taddr), X)
97
+# define qemu_st_leq(X) stq_le_p(g2h(env_cpu(env), taddr), X)
98
+# define qemu_st_bew(X) stw_be_p(g2h(env_cpu(env), taddr), X)
99
+# define qemu_st_bel(X) stl_be_p(g2h(env_cpu(env), taddr), X)
100
+# define qemu_st_beq(X) stq_be_p(g2h(env_cpu(env), taddr), X)
101
+#endif
102
103
static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr,
104
TCGMemOpIdx oi, const void *tb_ptr)
105
--
106
2.25.1
107
108
diff view generated by jsdifflib
Deleted patch
1
These macros are only used in one place. By expanding,
2
we get to apply some common-subexpression elimination
3
and create some local variables.
4
1
5
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
tcg/tci.c | 165 +++++++++++++++++++++++++++++++++---------------------
10
1 file changed, 100 insertions(+), 65 deletions(-)
11
12
diff --git a/tcg/tci.c b/tcg/tci.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/tci.c
15
+++ b/tcg/tci.c
16
@@ -XXX,XX +XXX,XX @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
17
return result;
18
}
19
20
-#ifdef CONFIG_SOFTMMU
21
-# define qemu_ld_ub \
22
- helper_ret_ldub_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
23
-# define qemu_ld_leuw \
24
- helper_le_lduw_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
25
-# define qemu_ld_leul \
26
- helper_le_ldul_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
27
-# define qemu_ld_leq \
28
- helper_le_ldq_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
29
-# define qemu_ld_beuw \
30
- helper_be_lduw_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
31
-# define qemu_ld_beul \
32
- helper_be_ldul_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
33
-# define qemu_ld_beq \
34
- helper_be_ldq_mmu(env, taddr, oi, (uintptr_t)tb_ptr)
35
-# define qemu_st_b(X) \
36
- helper_ret_stb_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
37
-# define qemu_st_lew(X) \
38
- helper_le_stw_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
39
-# define qemu_st_lel(X) \
40
- helper_le_stl_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
41
-# define qemu_st_leq(X) \
42
- helper_le_stq_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
43
-# define qemu_st_bew(X) \
44
- helper_be_stw_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
45
-# define qemu_st_bel(X) \
46
- helper_be_stl_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
47
-# define qemu_st_beq(X) \
48
- helper_be_stq_mmu(env, taddr, X, oi, (uintptr_t)tb_ptr)
49
-#else
50
-# define qemu_ld_ub ldub_p(g2h(env_cpu(env), taddr))
51
-# define qemu_ld_leuw lduw_le_p(g2h(env_cpu(env), taddr))
52
-# define qemu_ld_leul (uint32_t)ldl_le_p(g2h(env_cpu(env), taddr))
53
-# define qemu_ld_leq ldq_le_p(g2h(env_cpu(env), taddr))
54
-# define qemu_ld_beuw lduw_be_p(g2h(env_cpu(env), taddr))
55
-# define qemu_ld_beul (uint32_t)ldl_be_p(g2h(env_cpu(env), taddr))
56
-# define qemu_ld_beq ldq_be_p(g2h(env_cpu(env), taddr))
57
-# define qemu_st_b(X) stb_p(g2h(env_cpu(env), taddr), X)
58
-# define qemu_st_lew(X) stw_le_p(g2h(env_cpu(env), taddr), X)
59
-# define qemu_st_lel(X) stl_le_p(g2h(env_cpu(env), taddr), X)
60
-# define qemu_st_leq(X) stq_le_p(g2h(env_cpu(env), taddr), X)
61
-# define qemu_st_bew(X) stw_be_p(g2h(env_cpu(env), taddr), X)
62
-# define qemu_st_bel(X) stl_be_p(g2h(env_cpu(env), taddr), X)
63
-# define qemu_st_beq(X) stq_be_p(g2h(env_cpu(env), taddr), X)
64
-#endif
65
-
66
static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr,
67
TCGMemOpIdx oi, const void *tb_ptr)
68
{
69
MemOp mop = get_memop(oi) & (MO_BSWAP | MO_SSIZE);
70
71
+#ifdef CONFIG_SOFTMMU
72
+ uintptr_t ra = (uintptr_t)tb_ptr;
73
+
74
switch (mop) {
75
case MO_UB:
76
- return qemu_ld_ub;
77
+ return helper_ret_ldub_mmu(env, taddr, oi, ra);
78
case MO_SB:
79
- return (int8_t)qemu_ld_ub;
80
+ return helper_ret_ldsb_mmu(env, taddr, oi, ra);
81
case MO_LEUW:
82
- return qemu_ld_leuw;
83
+ return helper_le_lduw_mmu(env, taddr, oi, ra);
84
case MO_LESW:
85
- return (int16_t)qemu_ld_leuw;
86
+ return helper_le_ldsw_mmu(env, taddr, oi, ra);
87
case MO_LEUL:
88
- return qemu_ld_leul;
89
+ return helper_le_ldul_mmu(env, taddr, oi, ra);
90
case MO_LESL:
91
- return (int32_t)qemu_ld_leul;
92
+ return helper_le_ldsl_mmu(env, taddr, oi, ra);
93
case MO_LEQ:
94
- return qemu_ld_leq;
95
+ return helper_le_ldq_mmu(env, taddr, oi, ra);
96
case MO_BEUW:
97
- return qemu_ld_beuw;
98
+ return helper_be_lduw_mmu(env, taddr, oi, ra);
99
case MO_BESW:
100
- return (int16_t)qemu_ld_beuw;
101
+ return helper_be_ldsw_mmu(env, taddr, oi, ra);
102
case MO_BEUL:
103
- return qemu_ld_beul;
104
+ return helper_be_ldul_mmu(env, taddr, oi, ra);
105
case MO_BESL:
106
- return (int32_t)qemu_ld_beul;
107
+ return helper_be_ldsl_mmu(env, taddr, oi, ra);
108
case MO_BEQ:
109
- return qemu_ld_beq;
110
+ return helper_be_ldq_mmu(env, taddr, oi, ra);
111
default:
112
g_assert_not_reached();
113
}
114
+#else
115
+ void *haddr = g2h(env_cpu(env), taddr);
116
+ uint64_t ret;
117
+
118
+ switch (mop) {
119
+ case MO_UB:
120
+ ret = ldub_p(haddr);
121
+ break;
122
+ case MO_SB:
123
+ ret = ldsb_p(haddr);
124
+ break;
125
+ case MO_LEUW:
126
+ ret = lduw_le_p(haddr);
127
+ break;
128
+ case MO_LESW:
129
+ ret = ldsw_le_p(haddr);
130
+ break;
131
+ case MO_LEUL:
132
+ ret = (uint32_t)ldl_le_p(haddr);
133
+ break;
134
+ case MO_LESL:
135
+ ret = (int32_t)ldl_le_p(haddr);
136
+ break;
137
+ case MO_LEQ:
138
+ ret = ldq_le_p(haddr);
139
+ break;
140
+ case MO_BEUW:
141
+ ret = lduw_be_p(haddr);
142
+ break;
143
+ case MO_BESW:
144
+ ret = ldsw_be_p(haddr);
145
+ break;
146
+ case MO_BEUL:
147
+ ret = (uint32_t)ldl_be_p(haddr);
148
+ break;
149
+ case MO_BESL:
150
+ ret = (int32_t)ldl_be_p(haddr);
151
+ break;
152
+ case MO_BEQ:
153
+ ret = ldq_be_p(haddr);
154
+ break;
155
+ default:
156
+ g_assert_not_reached();
157
+ }
158
+ return ret;
159
+#endif
160
}
161
162
static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val,
163
@@ -XXX,XX +XXX,XX @@ static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val,
164
{
165
MemOp mop = get_memop(oi) & (MO_BSWAP | MO_SSIZE);
166
167
+#ifdef CONFIG_SOFTMMU
168
+ uintptr_t ra = (uintptr_t)tb_ptr;
169
+
170
switch (mop) {
171
case MO_UB:
172
- qemu_st_b(val);
173
+ helper_ret_stb_mmu(env, taddr, val, oi, ra);
174
break;
175
case MO_LEUW:
176
- qemu_st_lew(val);
177
+ helper_le_stw_mmu(env, taddr, val, oi, ra);
178
break;
179
case MO_LEUL:
180
- qemu_st_lel(val);
181
+ helper_le_stl_mmu(env, taddr, val, oi, ra);
182
break;
183
case MO_LEQ:
184
- qemu_st_leq(val);
185
+ helper_le_stq_mmu(env, taddr, val, oi, ra);
186
break;
187
case MO_BEUW:
188
- qemu_st_bew(val);
189
+ helper_be_stw_mmu(env, taddr, val, oi, ra);
190
break;
191
case MO_BEUL:
192
- qemu_st_bel(val);
193
+ helper_be_stl_mmu(env, taddr, val, oi, ra);
194
break;
195
case MO_BEQ:
196
- qemu_st_beq(val);
197
+ helper_be_stq_mmu(env, taddr, val, oi, ra);
198
break;
199
default:
200
g_assert_not_reached();
201
}
202
+#else
203
+ void *haddr = g2h(env_cpu(env), taddr);
204
+
205
+ switch (mop) {
206
+ case MO_UB:
207
+ stb_p(haddr, val);
208
+ break;
209
+ case MO_LEUW:
210
+ stw_le_p(haddr, val);
211
+ break;
212
+ case MO_LEUL:
213
+ stl_le_p(haddr, val);
214
+ break;
215
+ case MO_LEQ:
216
+ stq_le_p(haddr, val);
217
+ break;
218
+ case MO_BEUW:
219
+ stw_be_p(haddr, val);
220
+ break;
221
+ case MO_BEUL:
222
+ stl_be_p(haddr, val);
223
+ break;
224
+ case MO_BEQ:
225
+ stq_be_p(haddr, val);
226
+ break;
227
+ default:
228
+ g_assert_not_reached();
229
+ }
230
+#endif
231
}
232
233
#if TCG_TARGET_REG_BITS == 64
234
--
235
2.25.1
236
237
diff view generated by jsdifflib
Deleted patch
1
Wrap guest memory operations for tci like we do for cpu_ld*_data.
2
1
3
We cannot actually use the cpu_ldst.h interface without duplicating
4
the memory trace operations performed within, which will already
5
have been expanded into the tcg opcode stream.
6
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
tcg/tci.c | 10 ++++++----
12
1 file changed, 6 insertions(+), 4 deletions(-)
13
14
diff --git a/tcg/tci.c b/tcg/tci.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/tci.c
17
+++ b/tcg/tci.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr,
19
TCGMemOpIdx oi, const void *tb_ptr)
20
{
21
MemOp mop = get_memop(oi) & (MO_BSWAP | MO_SSIZE);
22
-
23
-#ifdef CONFIG_SOFTMMU
24
uintptr_t ra = (uintptr_t)tb_ptr;
25
26
+#ifdef CONFIG_SOFTMMU
27
switch (mop) {
28
case MO_UB:
29
return helper_ret_ldub_mmu(env, taddr, oi, ra);
30
@@ -XXX,XX +XXX,XX @@ static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr,
31
void *haddr = g2h(env_cpu(env), taddr);
32
uint64_t ret;
33
34
+ set_helper_retaddr(ra);
35
switch (mop) {
36
case MO_UB:
37
ret = ldub_p(haddr);
38
@@ -XXX,XX +XXX,XX @@ static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr,
39
default:
40
g_assert_not_reached();
41
}
42
+ clear_helper_retaddr();
43
return ret;
44
#endif
45
}
46
@@ -XXX,XX +XXX,XX @@ static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val,
47
TCGMemOpIdx oi, const void *tb_ptr)
48
{
49
MemOp mop = get_memop(oi) & (MO_BSWAP | MO_SSIZE);
50
-
51
-#ifdef CONFIG_SOFTMMU
52
uintptr_t ra = (uintptr_t)tb_ptr;
53
54
+#ifdef CONFIG_SOFTMMU
55
switch (mop) {
56
case MO_UB:
57
helper_ret_stb_mmu(env, taddr, val, oi, ra);
58
@@ -XXX,XX +XXX,XX @@ static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val,
59
#else
60
void *haddr = g2h(env_cpu(env), taddr);
61
62
+ set_helper_retaddr(ra);
63
switch (mop) {
64
case MO_UB:
65
stb_p(haddr, val);
66
@@ -XXX,XX +XXX,XX @@ static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val,
67
default:
68
g_assert_not_reached();
69
}
70
+ clear_helper_retaddr();
71
#endif
72
}
73
74
--
75
2.25.1
76
77
diff view generated by jsdifflib
Deleted patch
1
The longest test at the moment seems to be a (slower)
2
aarch64 host, for which test-mmap takes 64 seconds.
3
1
4
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Acked-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
configure | 3 +++
11
tests/tcg/Makefile.target | 6 ++++--
12
2 files changed, 7 insertions(+), 2 deletions(-)
13
14
diff --git a/configure b/configure
15
index XXXXXXX..XXXXXXX 100755
16
--- a/configure
17
+++ b/configure
18
@@ -XXX,XX +XXX,XX @@ fi
19
if test "$optreset" = "yes" ; then
20
echo "HAVE_OPTRESET=y" >> $config_host_mak
21
fi
22
+if test "$tcg" = "enabled" -a "$tcg_interpreter" = "true" ; then
23
+ echo "CONFIG_TCG_INTERPRETER=y" >> $config_host_mak
24
+fi
25
if test "$fdatasync" = "yes" ; then
26
echo "CONFIG_FDATASYNC=y" >> $config_host_mak
27
fi
28
diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target
29
index XXXXXXX..XXXXXXX 100644
30
--- a/tests/tcg/Makefile.target
31
+++ b/tests/tcg/Makefile.target
32
@@ -XXX,XX +XXX,XX @@ LDFLAGS=
33
QEMU_OPTS=
34
35
36
-# If TCG debugging is enabled things are a lot slower
37
-ifeq ($(CONFIG_DEBUG_TCG),y)
38
+# If TCG debugging, or TCI is enabled things are a lot slower
39
+ifneq ($(CONFIG_TCG_INTERPRETER),)
40
+TIMEOUT=90
41
+else ifneq ($(CONFIG_DEBUG_TCG),)
42
TIMEOUT=60
43
else
44
TIMEOUT=15
45
--
46
2.25.1
47
48
diff view generated by jsdifflib
Deleted patch
1
This function should have been updated for vector types
2
when they were introduced.
3
1
4
Fixes: d2fd745fe8b
5
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/367
6
Cc: qemu-stable@nongnu.org
7
Tested-by: Stefan Weil <sw@weilnetz.de>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
tcg/tcg.c | 32 +++++++++++++++++++++++++++-----
12
1 file changed, 27 insertions(+), 5 deletions(-)
13
14
diff --git a/tcg/tcg.c b/tcg/tcg.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/tcg.c
17
+++ b/tcg/tcg.c
18
@@ -XXX,XX +XXX,XX @@ static void check_regs(TCGContext *s)
19
20
static void temp_allocate_frame(TCGContext *s, TCGTemp *ts)
21
{
22
- if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
23
- s->frame_end) {
24
- tcg_abort();
25
+ size_t size, align;
26
+ intptr_t off;
27
+
28
+ switch (ts->type) {
29
+ case TCG_TYPE_I32:
30
+ size = align = 4;
31
+ break;
32
+ case TCG_TYPE_I64:
33
+ case TCG_TYPE_V64:
34
+ size = align = 8;
35
+ break;
36
+ case TCG_TYPE_V128:
37
+ size = align = 16;
38
+ break;
39
+ case TCG_TYPE_V256:
40
+ /* Note that we do not require aligned storage for V256. */
41
+ size = 32, align = 16;
42
+ break;
43
+ default:
44
+ g_assert_not_reached();
45
}
46
- ts->mem_offset = s->current_frame_offset;
47
+
48
+ assert(align <= TCG_TARGET_STACK_ALIGN);
49
+ off = ROUND_UP(s->current_frame_offset, align);
50
+ assert(off + size <= s->frame_end);
51
+ s->current_frame_offset = off + size;
52
+
53
+ ts->mem_offset = off;
54
#if defined(__sparc__)
55
ts->mem_offset += TCG_TARGET_STACK_BIAS;
56
#endif
57
ts->mem_base = s->frame_temp;
58
ts->mem_allocated = 1;
59
- s->current_frame_offset += sizeof(tcg_target_long);
60
}
61
62
static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet, TCGRegSet);
63
--
64
2.25.1
65
66
diff view generated by jsdifflib
Deleted patch
1
Assume that we'll have fewer temps allocated after
2
restarting with a fewer number of instructions.
3
1
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/tcg.c | 6 +++++-
8
1 file changed, 5 insertions(+), 1 deletion(-)
9
10
diff --git a/tcg/tcg.c b/tcg/tcg.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/tcg.c
13
+++ b/tcg/tcg.c
14
@@ -XXX,XX +XXX,XX @@ static void temp_allocate_frame(TCGContext *s, TCGTemp *ts)
15
16
assert(align <= TCG_TARGET_STACK_ALIGN);
17
off = ROUND_UP(s->current_frame_offset, align);
18
- assert(off + size <= s->frame_end);
19
+
20
+ /* If we've exhausted the stack frame, restart with a smaller TB. */
21
+ if (off + size > s->frame_end) {
22
+ tcg_raise_tb_overflow(s);
23
+ }
24
s->current_frame_offset = off + size;
25
26
ts->mem_offset = off;
27
--
28
2.25.1
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Stefan Weil <sw@weilnetz.de>
2
1
3
The function is called with alignment == 0 which caused an assertion.
4
Use the code from oslib-posix.c to fix that regression.
5
6
Fixes: ed6f53f9ca9
7
Signed-off-by: Stefan Weil <sw@weilnetz.de>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-Id: <20210611105846.347954-1-sw@weilnetz.de>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
12
util/oslib-win32.c | 6 +++++-
13
1 file changed, 5 insertions(+), 1 deletion(-)
14
15
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/util/oslib-win32.c
18
+++ b/util/oslib-win32.c
19
@@ -XXX,XX +XXX,XX @@ void *qemu_try_memalign(size_t alignment, size_t size)
20
void *ptr;
21
22
g_assert(size != 0);
23
- g_assert(is_power_of_2(alignment));
24
+ if (alignment < sizeof(void *)) {
25
+ alignment = sizeof(void *);
26
+ } else {
27
+ g_assert(is_power_of_2(alignment));
28
+ }
29
ptr = _aligned_malloc(size, alignment);
30
trace_qemu_memalign(alignment, size, ptr);
31
return ptr;
32
--
33
2.25.1
34
35
diff view generated by jsdifflib