1
Pretty small still, but there are two patches that ought
1
Second try's the charm today, right?
2
to get backported to stable, so no point in delaying.
2
3
3
4
r~
4
r~
5
5
6
The following changes since commit a5ba0a7e4e150d1350a041f0d0ef9ca6c8d7c307:
7
6
8
Merge tag 'pull-aspeed-20241211' of https://github.com/legoater/qemu into staging (2024-12-11 15:16:47 +0000)
7
The following changes since commit 00b1faea41d283e931256aa78aa975a369ec3ae6:
8
9
Merge tag 'pull-target-arm-20230123' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2023-01-23 13:40:28 +0000)
9
10
10
are available in the Git repository at:
11
are available in the Git repository at:
11
12
12
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20241212
13
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20230123
13
14
14
for you to fetch changes up to 7ac87b14a92234b6a89b701b4043ad6cf8bdcccf:
15
for you to fetch changes up to 709bcd7da3f6b4655d910634a0d520fa1439df38:
15
16
16
target/sparc: Use memcpy() and remove memcpy32() (2024-12-12 14:28:38 -0600)
17
tcg/loongarch64: Reorg goto_tb implementation (2023-01-23 16:00:13 -1000)
17
18
18
----------------------------------------------------------------
19
----------------------------------------------------------------
19
tcg: Reset free_temps before tcg_optimize
20
common-user: Re-enable ppc32 host
20
tcg/riscv: Fix StoreStore barrier generation
21
tcg: Avoid recursion in tcg_gen_mulu2_i32
21
include/exec: Introduce fpst alias in helper-head.h.inc
22
tcg: Mark tcg helpers noinline to avoid an issue with LTO
22
target/sparc: Use memcpy() and remove memcpy32()
23
tcg/arm: Use register pair allocation for qemu_{ld,st}_i64
24
disas: Enable loongarch disassembler, and fixes
25
tcg/loongarch64: Improve move immediate
26
tcg/loongarch64: Improve add immediate
27
tcg/loongarch64: Improve setcond
28
tcg/loongarch64: Implement movcond
29
tcg/loongarch64: Use tcg_pcrel_diff in tcg_out_ldst
30
tcg/loongarch64: Reorg goto_tb implementation
23
31
24
----------------------------------------------------------------
32
----------------------------------------------------------------
25
Philippe Mathieu-Daudé (1):
33
Richard Henderson (14):
26
target/sparc: Use memcpy() and remove memcpy32()
34
tcg: Avoid recursion in tcg_gen_mulu2_i32
35
tcg/arm: Use register pair allocation for qemu_{ld,st}_i64
36
common-user/host/ppc: Implement safe-syscall.inc.S
37
linux-user: Implment host/ppc/host-signal.h
38
tcg: Mark tcg helpers noinline to avoid an issue with LTO
39
target/loongarch: Enable the disassembler for host tcg
40
target/loongarch: Disassemble jirl properly
41
target/loongarch: Disassemble pcadd* addresses
42
tcg/loongarch64: Update tcg-insn-defs.c.inc
43
tcg/loongarch64: Introduce tcg_out_addi
44
tcg/loongarch64: Improve setcond expansion
45
tcg/loongarch64: Implement movcond
46
tcg/loongarch64: Use tcg_pcrel_diff in tcg_out_ldst
47
tcg/loongarch64: Reorg goto_tb implementation
27
48
28
Richard Henderson (2):
49
Rui Wang (1):
29
tcg: Reset free_temps before tcg_optimize
50
tcg/loongarch64: Optimize immediate loading
30
include/exec: Introduce fpst alias in helper-head.h.inc
31
51
32
Roman Artemev (1):
52
include/exec/helper-proto.h | 32 ++-
33
tcg/riscv: Fix StoreStore barrier generation
53
include/tcg/tcg.h | 7 -
34
54
linux-user/include/host/ppc/host-signal.h | 39 +++
35
include/tcg/tcg-temp-internal.h | 6 ++++++
55
tcg/arm/tcg-target-con-set.h | 7 +-
36
accel/tcg/plugin-gen.c | 2 +-
56
tcg/arm/tcg-target-con-str.h | 2 +
37
target/sparc/win_helper.c | 26 ++++++++------------------
57
tcg/loongarch64/tcg-target-con-set.h | 5 +-
38
tcg/tcg.c | 5 ++++-
58
tcg/loongarch64/tcg-target-con-str.h | 2 +-
39
include/exec/helper-head.h.inc | 3 +++
59
tcg/loongarch64/tcg-target.h | 11 +-
40
tcg/riscv/tcg-target.c.inc | 2 +-
60
target/loongarch/insns.decode | 3 +-
41
6 files changed, 23 insertions(+), 21 deletions(-)
61
disas.c | 2 +
42
62
target/loongarch/disas.c | 39 ++-
63
tcg/tcg-op.c | 4 +-
64
target/loongarch/insn_trans/trans_branch.c.inc | 2 +-
65
tcg/arm/tcg-target.c.inc | 28 +-
66
tcg/loongarch64/tcg-insn-defs.c.inc | 10 +-
67
tcg/loongarch64/tcg-target.c.inc | 364 ++++++++++++++++---------
68
common-user/host/ppc/safe-syscall.inc.S | 107 ++++++++
69
target/loongarch/meson.build | 3 +-
70
18 files changed, 497 insertions(+), 170 deletions(-)
71
create mode 100644 linux-user/include/host/ppc/host-signal.h
72
create mode 100644 common-user/host/ppc/safe-syscall.inc.S
diff view generated by jsdifflib
New patch
1
We have a test for one of TCG_TARGET_HAS_mulu2_i32 or
2
TCG_TARGET_HAS_muluh_i32 being defined, but the test
3
became non-functional when we changed to always define
4
all of these macros.
1
5
6
Replace this with a build-time test in tcg_gen_mulu2_i32.
7
8
Fixes: 25c4d9cc845 ("tcg: Always define all of the TCGOpcode enum members.")
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1435
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
12
include/tcg/tcg.h | 7 -------
13
tcg/tcg-op.c | 4 +++-
14
2 files changed, 3 insertions(+), 8 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 @@ typedef uint64_t TCGRegSet;
21
#define TCG_TARGET_HAS_rem_i64 0
22
#endif
23
24
-/* For 32-bit targets, some sort of unsigned widening multiply is required. */
25
-#if TCG_TARGET_REG_BITS == 32 \
26
- && !(defined(TCG_TARGET_HAS_mulu2_i32) \
27
- || defined(TCG_TARGET_HAS_muluh_i32))
28
-# error "Missing unsigned widening multiply"
29
-#endif
30
-
31
#if !defined(TCG_TARGET_HAS_v64) \
32
&& !defined(TCG_TARGET_HAS_v128) \
33
&& !defined(TCG_TARGET_HAS_v256)
34
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/tcg/tcg-op.c
37
+++ b/tcg/tcg-op.c
38
@@ -XXX,XX +XXX,XX @@ void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
39
tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
40
tcg_gen_mov_i32(rl, t);
41
tcg_temp_free_i32(t);
42
- } else {
43
+ } else if (TCG_TARGET_REG_BITS == 64) {
44
TCGv_i64 t0 = tcg_temp_new_i64();
45
TCGv_i64 t1 = tcg_temp_new_i64();
46
tcg_gen_extu_i32_i64(t0, arg1);
47
@@ -XXX,XX +XXX,XX @@ void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
48
tcg_gen_extr_i64_i32(rl, rh, t0);
49
tcg_temp_free_i64(t0);
50
tcg_temp_free_i64(t1);
51
+ } else {
52
+ qemu_build_not_reached();
53
}
54
}
55
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
Although we still can't use ldrd and strd for all operations,
2
increase the chances by getting the register allocation correct.
1
3
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/arm/tcg-target-con-set.h | 7 ++++---
7
tcg/arm/tcg-target-con-str.h | 2 ++
8
tcg/arm/tcg-target.c.inc | 28 ++++++++++++++++++----------
9
3 files changed, 24 insertions(+), 13 deletions(-)
10
11
diff --git a/tcg/arm/tcg-target-con-set.h b/tcg/arm/tcg-target-con-set.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/arm/tcg-target-con-set.h
14
+++ b/tcg/arm/tcg-target-con-set.h
15
@@ -XXX,XX +XXX,XX @@ C_O0_I2(r, rIN)
16
C_O0_I2(s, s)
17
C_O0_I2(w, r)
18
C_O0_I3(s, s, s)
19
+C_O0_I3(S, p, s)
20
C_O0_I4(r, r, rI, rI)
21
-C_O0_I4(s, s, s, s)
22
+C_O0_I4(S, p, s, s)
23
C_O1_I1(r, l)
24
C_O1_I1(r, r)
25
C_O1_I1(w, r)
26
@@ -XXX,XX +XXX,XX @@ C_O1_I2(w, w, wZ)
27
C_O1_I3(w, w, w, w)
28
C_O1_I4(r, r, r, rI, rI)
29
C_O1_I4(r, r, rIN, rIK, 0)
30
-C_O2_I1(r, r, l)
31
-C_O2_I2(r, r, l, l)
32
+C_O2_I1(e, p, l)
33
+C_O2_I2(e, p, l, l)
34
C_O2_I2(r, r, r, r)
35
C_O2_I4(r, r, r, r, rIN, rIK)
36
C_O2_I4(r, r, rI, rI, rIN, rIK)
37
diff --git a/tcg/arm/tcg-target-con-str.h b/tcg/arm/tcg-target-con-str.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/tcg/arm/tcg-target-con-str.h
40
+++ b/tcg/arm/tcg-target-con-str.h
41
@@ -XXX,XX +XXX,XX @@
42
* Define constraint letters for register sets:
43
* REGS(letter, register_mask)
44
*/
45
+REGS('e', ALL_GENERAL_REGS & 0x5555) /* even regs */
46
REGS('r', ALL_GENERAL_REGS)
47
REGS('l', ALL_QLOAD_REGS)
48
REGS('s', ALL_QSTORE_REGS)
49
+REGS('S', ALL_QSTORE_REGS & 0x5555) /* even qstore */
50
REGS('w', ALL_VECTOR_REGS)
51
52
/*
53
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
54
index XXXXXXX..XXXXXXX 100644
55
--- a/tcg/arm/tcg-target.c.inc
56
+++ b/tcg/arm/tcg-target.c.inc
57
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_index(TCGContext *s, MemOp opc,
58
tcg_out_ld32_r(s, COND_AL, datalo, addrlo, addend);
59
break;
60
case MO_UQ:
61
+ /* We used pair allocation for datalo, so already should be aligned. */
62
+ tcg_debug_assert((datalo & 1) == 0);
63
+ tcg_debug_assert(datahi == datalo + 1);
64
/* LDRD requires alignment; double-check that. */
65
- if (get_alignment_bits(opc) >= MO_64
66
- && (datalo & 1) == 0 && datahi == datalo + 1) {
67
+ if (get_alignment_bits(opc) >= MO_64) {
68
/*
69
* Rm (the second address op) must not overlap Rt or Rt + 1.
70
* Since datalo is aligned, we can simplify the test via alignment.
71
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg datalo,
72
tcg_out_ld32_12(s, COND_AL, datalo, addrlo, 0);
73
break;
74
case MO_UQ:
75
+ /* We used pair allocation for datalo, so already should be aligned. */
76
+ tcg_debug_assert((datalo & 1) == 0);
77
+ tcg_debug_assert(datahi == datalo + 1);
78
/* LDRD requires alignment; double-check that. */
79
- if (get_alignment_bits(opc) >= MO_64
80
- && (datalo & 1) == 0 && datahi == datalo + 1) {
81
+ if (get_alignment_bits(opc) >= MO_64) {
82
tcg_out_ldrd_8(s, COND_AL, datalo, addrlo, 0);
83
} else if (datalo == addrlo) {
84
tcg_out_ld32_12(s, COND_AL, datahi, addrlo, 4);
85
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_index(TCGContext *s, ARMCond cond, MemOp opc,
86
tcg_out_st32_r(s, cond, datalo, addrlo, addend);
87
break;
88
case MO_64:
89
+ /* We used pair allocation for datalo, so already should be aligned. */
90
+ tcg_debug_assert((datalo & 1) == 0);
91
+ tcg_debug_assert(datahi == datalo + 1);
92
/* STRD requires alignment; double-check that. */
93
- if (get_alignment_bits(opc) >= MO_64
94
- && (datalo & 1) == 0 && datahi == datalo + 1) {
95
+ if (get_alignment_bits(opc) >= MO_64) {
96
tcg_out_strd_r(s, cond, datalo, addrlo, addend);
97
} else if (scratch_addend) {
98
tcg_out_st32_rwb(s, cond, datalo, addend, addrlo);
99
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg datalo,
100
tcg_out_st32_12(s, COND_AL, datalo, addrlo, 0);
101
break;
102
case MO_64:
103
+ /* We used pair allocation for datalo, so already should be aligned. */
104
+ tcg_debug_assert((datalo & 1) == 0);
105
+ tcg_debug_assert(datahi == datalo + 1);
106
/* STRD requires alignment; double-check that. */
107
- if (get_alignment_bits(opc) >= MO_64
108
- && (datalo & 1) == 0 && datahi == datalo + 1) {
109
+ if (get_alignment_bits(opc) >= MO_64) {
110
tcg_out_strd_8(s, COND_AL, datalo, addrlo, 0);
111
} else {
112
tcg_out_st32_12(s, COND_AL, datalo, addrlo, 0);
113
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
114
case INDEX_op_qemu_ld_i32:
115
return TARGET_LONG_BITS == 32 ? C_O1_I1(r, l) : C_O1_I2(r, l, l);
116
case INDEX_op_qemu_ld_i64:
117
- return TARGET_LONG_BITS == 32 ? C_O2_I1(r, r, l) : C_O2_I2(r, r, l, l);
118
+ return TARGET_LONG_BITS == 32 ? C_O2_I1(e, p, l) : C_O2_I2(e, p, l, l);
119
case INDEX_op_qemu_st_i32:
120
return TARGET_LONG_BITS == 32 ? C_O0_I2(s, s) : C_O0_I3(s, s, s);
121
case INDEX_op_qemu_st_i64:
122
- return TARGET_LONG_BITS == 32 ? C_O0_I3(s, s, s) : C_O0_I4(s, s, s, s);
123
+ return TARGET_LONG_BITS == 32 ? C_O0_I3(S, p, s) : C_O0_I4(S, p, s, s);
124
125
case INDEX_op_st_vec:
126
return C_O0_I2(w, r);
127
--
128
2.34.1
diff view generated by jsdifflib
New patch
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
3
Message-Id: <20220729172141.1789105-2-richard.henderson@linaro.org>
4
---
5
common-user/host/ppc/safe-syscall.inc.S | 107 ++++++++++++++++++++++++
6
1 file changed, 107 insertions(+)
7
create mode 100644 common-user/host/ppc/safe-syscall.inc.S
1
8
9
diff --git a/common-user/host/ppc/safe-syscall.inc.S b/common-user/host/ppc/safe-syscall.inc.S
10
new file mode 100644
11
index XXXXXXX..XXXXXXX
12
--- /dev/null
13
+++ b/common-user/host/ppc/safe-syscall.inc.S
14
@@ -XXX,XX +XXX,XX @@
15
+/*
16
+ * safe-syscall.inc.S : host-specific assembly fragment
17
+ * to handle signals occurring at the same time as system calls.
18
+ * This is intended to be included by common-user/safe-syscall.S
19
+ *
20
+ * Copyright (C) 2022 Linaro, Ltd.
21
+ *
22
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
23
+ * See the COPYING file in the top-level directory.
24
+ */
25
+
26
+/*
27
+ * Standardize on the _CALL_FOO symbols used by GCC:
28
+ * Apple XCode does not define _CALL_DARWIN.
29
+ * Clang defines _CALL_ELF (64-bit) but not _CALL_SYSV (32-bit).
30
+ */
31
+#if !defined(_CALL_SYSV) && \
32
+ !defined(_CALL_DARWIN) && \
33
+ !defined(_CALL_AIX) && \
34
+ !defined(_CALL_ELF)
35
+# if defined(__APPLE__)
36
+# define _CALL_DARWIN
37
+# elif defined(__ELF__) && TCG_TARGET_REG_BITS == 32
38
+# define _CALL_SYSV
39
+# else
40
+# error "Unknown ABI"
41
+# endif
42
+#endif
43
+
44
+#ifndef _CALL_SYSV
45
+# error "Unsupported ABI"
46
+#endif
47
+
48
+
49
+ .global safe_syscall_base
50
+ .global safe_syscall_start
51
+ .global safe_syscall_end
52
+ .type safe_syscall_base, @function
53
+
54
+ .text
55
+
56
+ /*
57
+ * This is the entry point for making a system call. The calling
58
+ * convention here is that of a C varargs function with the
59
+ * first argument an 'int *' to the signal_pending flag, the
60
+ * second one the system call number (as a 'long'), and all further
61
+ * arguments being syscall arguments (also 'long').
62
+ */
63
+safe_syscall_base:
64
+ .cfi_startproc
65
+ stwu 1, -8(1)
66
+ .cfi_def_cfa_offset 8
67
+ stw 30, 4(1)
68
+ .cfi_offset 30, -4
69
+
70
+ /*
71
+ * We enter with r3 == &signal_pending
72
+ * r4 == syscall number
73
+ * r5 ... r10 == syscall arguments
74
+ * and return the result in r3
75
+ * and the syscall instruction needs
76
+ * r0 == syscall number
77
+ * r3 ... r8 == syscall arguments
78
+ * and returns the result in r3
79
+ * Shuffle everything around appropriately.
80
+ */
81
+ mr 30, 3 /* signal_pending */
82
+ mr 0, 4 /* syscall number */
83
+ mr 3, 5 /* syscall arguments */
84
+ mr 4, 6
85
+ mr 5, 7
86
+ mr 6, 8
87
+ mr 7, 9
88
+ mr 8, 10
89
+
90
+ /*
91
+ * This next sequence of code works in conjunction with the
92
+ * rewind_if_safe_syscall_function(). If a signal is taken
93
+ * and the interrupted PC is anywhere between 'safe_syscall_start'
94
+ * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
95
+ * The code sequence must therefore be able to cope with this, and
96
+ * the syscall instruction must be the final one in the sequence.
97
+ */
98
+safe_syscall_start:
99
+ /* if signal_pending is non-zero, don't do the call */
100
+ lwz 12, 0(30)
101
+ cmpwi 0, 12, 0
102
+ bne- 2f
103
+ sc
104
+safe_syscall_end:
105
+ /* code path when we did execute the syscall */
106
+ lwz 30, 4(1) /* restore r30 */
107
+ addi 1, 1, 8 /* restore stack */
108
+ .cfi_restore 30
109
+ .cfi_def_cfa_offset 0
110
+ bnslr+ /* return on success */
111
+ b safe_syscall_set_errno_tail
112
+
113
+ /* code path when we didn't execute the syscall */
114
+2: lwz 30, 4(1)
115
+ addi 1, 1, 8
116
+ addi 3, 0, QEMU_ERESTARTSYS
117
+ b safe_syscall_set_errno_tail
118
+
119
+ .cfi_endproc
120
+
121
+ .size safe_syscall_base, .-safe_syscall_base
122
--
123
2.34.1
diff view generated by jsdifflib
New patch
1
This commit re-enables ppc32 as a linux-user host,
2
as existance of the directory is noted by configure.
1
3
4
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1097
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
7
Message-Id: <20220729172141.1789105-3-richard.henderson@linaro.org>
8
---
9
linux-user/include/host/ppc/host-signal.h | 39 +++++++++++++++++++++++
10
1 file changed, 39 insertions(+)
11
create mode 100644 linux-user/include/host/ppc/host-signal.h
12
13
diff --git a/linux-user/include/host/ppc/host-signal.h b/linux-user/include/host/ppc/host-signal.h
14
new file mode 100644
15
index XXXXXXX..XXXXXXX
16
--- /dev/null
17
+++ b/linux-user/include/host/ppc/host-signal.h
18
@@ -XXX,XX +XXX,XX @@
19
+/*
20
+ * host-signal.h: signal info dependent on the host architecture
21
+ *
22
+ * Copyright (c) 2022 Linaro Ltd.
23
+ *
24
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
25
+ * See the COPYING file in the top-level directory.
26
+ */
27
+
28
+#ifndef PPC_HOST_SIGNAL_H
29
+#define PPC_HOST_SIGNAL_H
30
+
31
+#include <asm/ptrace.h>
32
+
33
+/* The third argument to a SA_SIGINFO handler is ucontext_t. */
34
+typedef ucontext_t host_sigcontext;
35
+
36
+static inline uintptr_t host_signal_pc(host_sigcontext *uc)
37
+{
38
+ return uc->uc_mcontext.regs->nip;
39
+}
40
+
41
+static inline void host_signal_set_pc(host_sigcontext *uc, uintptr_t pc)
42
+{
43
+ uc->uc_mcontext.regs->nip = pc;
44
+}
45
+
46
+static inline void *host_signal_mask(host_sigcontext *uc)
47
+{
48
+ return &uc->uc_sigmask;
49
+}
50
+
51
+static inline bool host_signal_write(siginfo_t *info, host_sigcontext *uc)
52
+{
53
+ return uc->uc_mcontext.regs->trap != 0x400
54
+ && (uc->uc_mcontext.regs->dsisr & 0x02000000);
55
+}
56
+
57
+#endif
58
--
59
2.34.1
diff view generated by jsdifflib
New patch
1
Marking helpers __attribute__((noinline)) prevents an issue
2
with GCC's ipa-split pass under --enable-lto.
1
3
4
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1454
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Tested-by: Idan Horowitz <idan.horowitz@gmail.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
include/exec/helper-proto.h | 32 ++++++++++++++++++++++++--------
10
1 file changed, 24 insertions(+), 8 deletions(-)
11
12
diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/exec/helper-proto.h
15
+++ b/include/exec/helper-proto.h
16
@@ -XXX,XX +XXX,XX @@
17
18
#include "exec/helper-head.h"
19
20
+/*
21
+ * Work around an issue with --enable-lto, in which GCC's ipa-split pass
22
+ * decides to split out the noreturn code paths that raise an exception,
23
+ * taking the __builtin_return_address() along into the new function,
24
+ * where it no longer computes a value that returns to TCG generated code.
25
+ * Despite the name, the noinline attribute affects splitter, so this
26
+ * prevents the optimization in question. Given that helpers should not
27
+ * otherwise be called directly, this should have any other visible effect.
28
+ *
29
+ * See https://gitlab.com/qemu-project/qemu/-/issues/1454
30
+ */
31
+#define DEF_HELPER_ATTR __attribute__((noinline))
32
+
33
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
34
-dh_ctype(ret) HELPER(name) (void);
35
+dh_ctype(ret) HELPER(name) (void) DEF_HELPER_ATTR;
36
37
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
38
-dh_ctype(ret) HELPER(name) (dh_ctype(t1));
39
+dh_ctype(ret) HELPER(name) (dh_ctype(t1)) DEF_HELPER_ATTR;
40
41
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
42
-dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
43
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)) DEF_HELPER_ATTR;
44
45
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
46
-dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3));
47
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), \
48
+ dh_ctype(t3)) DEF_HELPER_ATTR;
49
50
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
51
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
52
- dh_ctype(t4));
53
+ dh_ctype(t4)) DEF_HELPER_ATTR;
54
55
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
56
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
57
- dh_ctype(t4), dh_ctype(t5));
58
+ dh_ctype(t4), dh_ctype(t5)) DEF_HELPER_ATTR;
59
60
#define DEF_HELPER_FLAGS_6(name, flags, ret, t1, t2, t3, t4, t5, t6) \
61
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
62
- dh_ctype(t4), dh_ctype(t5), dh_ctype(t6));
63
+ dh_ctype(t4), dh_ctype(t5), \
64
+ dh_ctype(t6)) DEF_HELPER_ATTR;
65
66
#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7) \
67
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
68
dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \
69
- dh_ctype(t7));
70
+ dh_ctype(t7)) DEF_HELPER_ATTR;
71
72
#define IN_HELPER_PROTO
73
74
@@ -XXX,XX +XXX,XX @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
75
#undef DEF_HELPER_FLAGS_5
76
#undef DEF_HELPER_FLAGS_6
77
#undef DEF_HELPER_FLAGS_7
78
+#undef DEF_HELPER_ATTR
79
80
#endif /* HELPER_PROTO_H */
81
--
82
2.34.1
83
84
diff view generated by jsdifflib
New patch
1
Reuse the decodetree based disassembler from
2
target/loongarch/ for tcg/loongarch64/.
1
3
4
The generation of decode-insns.c.inc into ./libcommon.fa.p/ could
5
eventually result in conflict, if any other host requires the same
6
trick, but this is good enough for now.
7
8
Reviewed-by: WANG Xuerui <git@xen0n.name>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
12
disas.c | 2 ++
13
target/loongarch/meson.build | 3 ++-
14
2 files changed, 4 insertions(+), 1 deletion(-)
15
16
diff --git a/disas.c b/disas.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/disas.c
19
+++ b/disas.c
20
@@ -XXX,XX +XXX,XX @@ static void initialize_debug_host(CPUDebug *s)
21
s->info.cap_insn_split = 6;
22
#elif defined(__hppa__)
23
s->info.print_insn = print_insn_hppa;
24
+#elif defined(__loongarch__)
25
+ s->info.print_insn = print_insn_loongarch;
26
#endif
27
}
28
29
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/loongarch/meson.build
32
+++ b/target/loongarch/meson.build
33
@@ -XXX,XX +XXX,XX @@ gen = decodetree.process('insns.decode')
34
loongarch_ss = ss.source_set()
35
loongarch_ss.add(files(
36
'cpu.c',
37
- 'disas.c',
38
))
39
loongarch_tcg_ss = ss.source_set()
40
loongarch_tcg_ss.add(gen)
41
@@ -XXX,XX +XXX,XX @@ loongarch_softmmu_ss.add(files(
42
'iocsr_helper.c',
43
))
44
45
+common_ss.add(when: 'CONFIG_LOONGARCH_DIS', if_true: [files('disas.c'), gen])
46
+
47
loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss])
48
49
target_arch += {'loongarch': loongarch_ss}
50
--
51
2.34.1
52
53
diff view generated by jsdifflib
New patch
1
While jirl shares the same instruction format as bne etc,
2
it is not assembled the same. In particular, rd is printed
3
first not second and the immediate is not pc-relative.
1
4
5
Decode into the arg_rr_i structure, which prints correctly.
6
This changes the "offs" member to "imm", to update translate.
7
8
Reviewed-by: WANG Xuerui <git@xen0n.name>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
target/loongarch/insns.decode | 3 ++-
12
target/loongarch/disas.c | 2 +-
13
target/loongarch/insn_trans/trans_branch.c.inc | 2 +-
14
3 files changed, 4 insertions(+), 3 deletions(-)
15
16
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/loongarch/insns.decode
19
+++ b/target/loongarch/insns.decode
20
@@ -XXX,XX +XXX,XX @@
21
@rr_ui12 .... ...... imm:12 rj:5 rd:5 &rr_i
22
@rr_i14s2 .... .... .............. rj:5 rd:5 &rr_i imm=%i14s2
23
@rr_i16 .... .. imm:s16 rj:5 rd:5 &rr_i
24
+@rr_i16s2 .... .. ................ rj:5 rd:5 &rr_i imm=%offs16
25
@hint_r_i12 .... ...... imm:s12 rj:5 hint:5 &hint_r_i
26
@rrr_sa2p1 .... ........ ... .. rk:5 rj:5 rd:5 &rrr_sa sa=%sa2p1
27
@rrr_sa2 .... ........ ... sa:2 rk:5 rj:5 rd:5 &rrr_sa
28
@@ -XXX,XX +XXX,XX @@ beqz 0100 00 ................ ..... ..... @r_offs21
29
bnez 0100 01 ................ ..... ..... @r_offs21
30
bceqz 0100 10 ................ 00 ... ..... @c_offs21
31
bcnez 0100 10 ................ 01 ... ..... @c_offs21
32
-jirl 0100 11 ................ ..... ..... @rr_offs16
33
+jirl 0100 11 ................ ..... ..... @rr_i16s2
34
b 0101 00 .......................... @offs26
35
bl 0101 01 .......................... @offs26
36
beq 0101 10 ................ ..... ..... @rr_offs16
37
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/loongarch/disas.c
40
+++ b/target/loongarch/disas.c
41
@@ -XXX,XX +XXX,XX @@ INSN(beqz, r_offs)
42
INSN(bnez, r_offs)
43
INSN(bceqz, c_offs)
44
INSN(bcnez, c_offs)
45
-INSN(jirl, rr_offs)
46
+INSN(jirl, rr_i)
47
INSN(b, offs)
48
INSN(bl, offs)
49
INSN(beq, rr_offs)
50
diff --git a/target/loongarch/insn_trans/trans_branch.c.inc b/target/loongarch/insn_trans/trans_branch.c.inc
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/loongarch/insn_trans/trans_branch.c.inc
53
+++ b/target/loongarch/insn_trans/trans_branch.c.inc
54
@@ -XXX,XX +XXX,XX @@ static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
55
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
56
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
57
58
- tcg_gen_addi_tl(cpu_pc, src1, a->offs);
59
+ tcg_gen_addi_tl(cpu_pc, src1, a->imm);
60
tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
61
gen_set_gpr(a->rd, dest, EXT_NONE);
62
tcg_gen_lookup_and_goto_ptr();
63
--
64
2.34.1
diff view generated by jsdifflib
New patch
1
Print both the raw field and the resolved pc-relative
2
address, as we do for branches.
1
3
4
Reviewed-by: WANG Xuerui <git@xen0n.name>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
target/loongarch/disas.c | 37 +++++++++++++++++++++++++++++++++----
8
1 file changed, 33 insertions(+), 4 deletions(-)
9
10
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/loongarch/disas.c
13
+++ b/target/loongarch/disas.c
14
@@ -XXX,XX +XXX,XX @@ INSN(fsel, fffc)
15
INSN(addu16i_d, rr_i)
16
INSN(lu12i_w, r_i)
17
INSN(lu32i_d, r_i)
18
-INSN(pcaddi, r_i)
19
-INSN(pcalau12i, r_i)
20
-INSN(pcaddu12i, r_i)
21
-INSN(pcaddu18i, r_i)
22
INSN(ll_w, rr_i)
23
INSN(sc_w, rr_i)
24
INSN(ll_d, rr_i)
25
@@ -XXX,XX +XXX,XX @@ static bool trans_fcmp_cond_##suffix(DisasContext *ctx, \
26
27
FCMP_INSN(s)
28
FCMP_INSN(d)
29
+
30
+#define PCADD_INSN(name) \
31
+static bool trans_##name(DisasContext *ctx, arg_##name *a) \
32
+{ \
33
+ output(ctx, #name, "r%d, %d # 0x%" PRIx64, \
34
+ a->rd, a->imm, gen_##name(ctx->pc, a->imm)); \
35
+ return true; \
36
+}
37
+
38
+static uint64_t gen_pcaddi(uint64_t pc, int imm)
39
+{
40
+ return pc + (imm << 2);
41
+}
42
+
43
+static uint64_t gen_pcalau12i(uint64_t pc, int imm)
44
+{
45
+ return (pc + (imm << 12)) & ~0xfff;
46
+}
47
+
48
+static uint64_t gen_pcaddu12i(uint64_t pc, int imm)
49
+{
50
+ return pc + (imm << 12);
51
+}
52
+
53
+static uint64_t gen_pcaddu18i(uint64_t pc, int imm)
54
+{
55
+ return pc + ((uint64_t)(imm) << 18);
56
+}
57
+
58
+PCADD_INSN(pcaddi)
59
+PCADD_INSN(pcalau12i)
60
+PCADD_INSN(pcaddu12i)
61
+PCADD_INSN(pcaddu18i)
62
--
63
2.34.1
diff view generated by jsdifflib
1
From: Roman Artemev <roman.artemev@syntacore.com>
1
From: Rui Wang <wangrui@loongson.cn>
2
2
3
On RISC-V to StoreStore barrier corresponds
3
diff:
4
`fence w, w` not `fence r, r`
4
Imm Before After
5
0000000000000000 addi.w rd, zero, 0 addi.w rd, zero, 0
6
lu52i.d rd, zero, 0
7
00000000fffff800 lu12i.w rd, -1 addi.w rd, zero, -2048
8
ori rd, rd, 2048 lu32i.d rd, 0
9
lu32i.d rd, 0
5
10
6
Cc: qemu-stable@nongnu.org
11
Reviewed-by: WANG Xuerui <git@xen0n.name>
7
Fixes: efbea94c76b ("tcg/riscv: Add slowpath load and store instructions")
12
Signed-off-by: Rui Wang <wangrui@loongson.cn>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-Id: <20221107144713.845550-1-wangrui@loongson.cn>
9
Signed-off-by: Denis Tomashev <denis.tomashev@syntacore.com>
10
Signed-off-by: Roman Artemev <roman.artemev@syntacore.com>
11
Message-ID: <e2f2131e294a49e79959d4fa9ec02cf4@syntacore.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
---
15
---
14
tcg/riscv/tcg-target.c.inc | 2 +-
16
tcg/loongarch64/tcg-target.c.inc | 35 +++++++++++---------------------
15
1 file changed, 1 insertion(+), 1 deletion(-)
17
1 file changed, 12 insertions(+), 23 deletions(-)
16
18
17
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
19
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/tcg/riscv/tcg-target.c.inc
21
--- a/tcg/loongarch64/tcg-target.c.inc
20
+++ b/tcg/riscv/tcg-target.c.inc
22
+++ b/tcg/loongarch64/tcg-target.c.inc
21
@@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
23
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
22
insn |= 0x02100000;
24
return true;
25
}
26
27
-static bool imm_part_needs_loading(bool high_bits_are_ones,
28
- tcg_target_long part)
29
-{
30
- if (high_bits_are_ones) {
31
- return part != -1;
32
- } else {
33
- return part != 0;
34
- }
35
-}
36
-
37
/* Loads a 32-bit immediate into rd, sign-extended. */
38
static void tcg_out_movi_i32(TCGContext *s, TCGReg rd, int32_t val)
39
{
40
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi_i32(TCGContext *s, TCGReg rd, int32_t val)
41
tcg_target_long hi12 = sextreg(val, 12, 20);
42
43
/* Single-instruction cases. */
44
- if (lo == val) {
45
- /* val fits in simm12: addi.w rd, zero, val */
46
- tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val);
47
- return;
48
- }
49
- if (0x800 <= val && val <= 0xfff) {
50
+ if (hi12 == 0) {
51
/* val fits in uimm12: ori rd, zero, val */
52
tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val);
53
return;
23
}
54
}
24
if (a0 & TCG_MO_ST_ST) {
55
+ if (hi12 == sextreg(lo, 12, 20)) {
25
- insn |= 0x02200000;
56
+ /* val fits in simm12: addi.w rd, zero, val */
26
+ insn |= 0x01100000;
57
+ tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val);
58
+ return;
59
+ }
60
61
/* High bits must be set; load with lu12i.w + optional ori. */
62
tcg_out_opc_lu12i_w(s, rd, hi12);
63
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
64
65
intptr_t pc_offset;
66
tcg_target_long val_lo, val_hi, pc_hi, offset_hi;
67
- tcg_target_long hi32, hi52;
68
- bool rd_high_bits_are_ones;
69
+ tcg_target_long hi12, hi32, hi52;
70
71
/* Value fits in signed i32. */
72
if (type == TCG_TYPE_I32 || val == (int32_t)val) {
73
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
74
return;
27
}
75
}
28
tcg_out32(s, insn);
76
77
+ hi12 = sextreg(val, 12, 20);
78
hi32 = sextreg(val, 32, 20);
79
hi52 = sextreg(val, 52, 12);
80
81
/* Single cu52i.d case. */
82
- if (ctz64(val) >= 52) {
83
+ if ((hi52 != 0) && (ctz64(val) >= 52)) {
84
tcg_out_opc_cu52i_d(s, rd, TCG_REG_ZERO, hi52);
85
return;
86
}
87
88
/* Slow path. Initialize the low 32 bits, then concat high bits. */
89
tcg_out_movi_i32(s, rd, val);
90
- rd_high_bits_are_ones = (int32_t)val < 0;
91
92
- if (imm_part_needs_loading(rd_high_bits_are_ones, hi32)) {
93
+ /* Load hi32 and hi52 explicitly when they are unexpected values. */
94
+ if (hi32 != sextreg(hi12, 20, 20)) {
95
tcg_out_opc_cu32i_d(s, rd, hi32);
96
- rd_high_bits_are_ones = hi32 < 0;
97
}
98
99
- if (imm_part_needs_loading(rd_high_bits_are_ones, hi52)) {
100
+ if (hi52 != sextreg(hi32, 20, 12)) {
101
tcg_out_opc_cu52i_d(s, rd, rd, hi52);
102
}
29
}
103
}
30
--
104
--
31
2.43.0
105
2.34.1
diff view generated by jsdifflib
1
When allocating new temps during tcg_optmize, do not re-use
1
Regenerate with ADDU16I included:
2
any EBB temps that were used within the TB. We do not have
3
any idea what span of the TB in which the temp was live.
4
2
5
Introduce tcg_temp_ebb_reset_freed and use before tcg_optimize,
3
$ cd loongarch-opcodes/scripts/go
6
as well as replacing the equivalent in plugin_gen_inject and
4
$ go run ./genqemutcgdefs > $QEMU/tcg/loongarch64/tcg-insn-defs.c.inc
7
tcg_func_start.
8
5
9
Cc: qemu-stable@nongnu.org
6
Reviewed-by: WANG Xuerui <git@xen0n.name>
10
Fixes: fb04ab7ddd8 ("tcg/optimize: Lower TCG_COND_TST{EQ,NE} if unsupported")
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2711
12
Reported-by: wannacu <wannacu2049@gmail.com>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
---
9
---
17
include/tcg/tcg-temp-internal.h | 6 ++++++
10
tcg/loongarch64/tcg-insn-defs.c.inc | 10 +++++++++-
18
accel/tcg/plugin-gen.c | 2 +-
11
1 file changed, 9 insertions(+), 1 deletion(-)
19
tcg/tcg.c | 5 ++++-
20
3 files changed, 11 insertions(+), 2 deletions(-)
21
12
22
diff --git a/include/tcg/tcg-temp-internal.h b/include/tcg/tcg-temp-internal.h
13
diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc b/tcg/loongarch64/tcg-insn-defs.c.inc
23
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
24
--- a/include/tcg/tcg-temp-internal.h
15
--- a/tcg/loongarch64/tcg-insn-defs.c.inc
25
+++ b/include/tcg/tcg-temp-internal.h
16
+++ b/tcg/loongarch64/tcg-insn-defs.c.inc
26
@@ -XXX,XX +XXX,XX @@ TCGv_i64 tcg_temp_ebb_new_i64(void);
17
@@ -XXX,XX +XXX,XX @@
27
TCGv_ptr tcg_temp_ebb_new_ptr(void);
18
*
28
TCGv_i128 tcg_temp_ebb_new_i128(void);
19
* This file is auto-generated by genqemutcgdefs from
29
20
* https://github.com/loongson-community/loongarch-opcodes,
30
+/* Forget all freed EBB temps, so that new allocations produce new temps. */
21
- * from commit 961f0c60f5b63e574d785995600c71ad5413fdc4.
31
+static inline void tcg_temp_ebb_reset_freed(TCGContext *s)
22
+ * from commit 25ca7effe9d88101c1cf96c4005423643386d81f.
23
* DO NOT EDIT.
24
*/
25
26
@@ -XXX,XX +XXX,XX @@ typedef enum {
27
OPC_ANDI = 0x03400000,
28
OPC_ORI = 0x03800000,
29
OPC_XORI = 0x03c00000,
30
+ OPC_ADDU16I_D = 0x10000000,
31
OPC_LU12I_W = 0x14000000,
32
OPC_CU32I_D = 0x16000000,
33
OPC_PCADDU2I = 0x18000000,
34
@@ -XXX,XX +XXX,XX @@ tcg_out_opc_xori(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12)
35
tcg_out32(s, encode_djuk12_insn(OPC_XORI, d, j, uk12));
36
}
37
38
+/* Emits the `addu16i.d d, j, sk16` instruction. */
39
+static void __attribute__((unused))
40
+tcg_out_opc_addu16i_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16)
32
+{
41
+{
33
+ memset(s->free_temps, 0, sizeof(s->free_temps));
42
+ tcg_out32(s, encode_djsk16_insn(OPC_ADDU16I_D, d, j, sk16));
34
+}
43
+}
35
+
44
+
36
#endif /* TCG_TEMP_FREE_H */
45
/* Emits the `lu12i.w d, sj20` instruction. */
37
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
46
static void __attribute__((unused))
38
index XXXXXXX..XXXXXXX 100644
47
tcg_out_opc_lu12i_w(TCGContext *s, TCGReg d, int32_t sj20)
39
--- a/accel/tcg/plugin-gen.c
40
+++ b/accel/tcg/plugin-gen.c
41
@@ -XXX,XX +XXX,XX @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
42
* that might be live within the existing opcode stream.
43
* The simplest solution is to release them all and create new.
44
*/
45
- memset(tcg_ctx->free_temps, 0, sizeof(tcg_ctx->free_temps));
46
+ tcg_temp_ebb_reset_freed(tcg_ctx);
47
48
QTAILQ_FOREACH_SAFE(op, &tcg_ctx->ops, link, next) {
49
switch (op->opc) {
50
diff --git a/tcg/tcg.c b/tcg/tcg.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/tcg/tcg.c
53
+++ b/tcg/tcg.c
54
@@ -XXX,XX +XXX,XX @@ void tcg_func_start(TCGContext *s)
55
s->nb_temps = s->nb_globals;
56
57
/* No temps have been previously allocated for size or locality. */
58
- memset(s->free_temps, 0, sizeof(s->free_temps));
59
+ tcg_temp_ebb_reset_freed(s);
60
61
/* No constant temps have been previously allocated. */
62
for (int i = 0; i < TCG_TYPE_COUNT; ++i) {
63
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
64
}
65
#endif
66
67
+ /* Do not reuse any EBB that may be allocated within the TB. */
68
+ tcg_temp_ebb_reset_freed(s);
69
+
70
tcg_optimize(s);
71
72
reachable_code_pass(s);
73
--
48
--
74
2.43.0
49
2.34.1
75
50
76
51
diff view generated by jsdifflib
New patch
1
Adjust the constraints to allow any int32_t for immediate
2
addition. Split immediate adds into addu16i + addi, which
3
covers quite a lot of the immediate space. For the hole in
4
the middle, load the constant into TMP0 instead.
1
5
6
Reviewed-by: WANG Xuerui <git@xen0n.name>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
tcg/loongarch64/tcg-target-con-set.h | 4 +-
10
tcg/loongarch64/tcg-target-con-str.h | 2 +-
11
tcg/loongarch64/tcg-target.c.inc | 57 ++++++++++++++++++++++++----
12
3 files changed, 53 insertions(+), 10 deletions(-)
13
14
diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/loongarch64/tcg-target-con-set.h
17
+++ b/tcg/loongarch64/tcg-target-con-set.h
18
@@ -XXX,XX +XXX,XX @@ C_O1_I1(r, L)
19
C_O1_I2(r, r, rC)
20
C_O1_I2(r, r, ri)
21
C_O1_I2(r, r, rI)
22
+C_O1_I2(r, r, rJ)
23
C_O1_I2(r, r, rU)
24
C_O1_I2(r, r, rW)
25
C_O1_I2(r, r, rZ)
26
C_O1_I2(r, 0, rZ)
27
-C_O1_I2(r, rZ, rN)
28
+C_O1_I2(r, rZ, ri)
29
+C_O1_I2(r, rZ, rJ)
30
C_O1_I2(r, rZ, rZ)
31
diff --git a/tcg/loongarch64/tcg-target-con-str.h b/tcg/loongarch64/tcg-target-con-str.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tcg/loongarch64/tcg-target-con-str.h
34
+++ b/tcg/loongarch64/tcg-target-con-str.h
35
@@ -XXX,XX +XXX,XX @@ REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
36
* CONST(letter, TCG_CT_CONST_* bit set)
37
*/
38
CONST('I', TCG_CT_CONST_S12)
39
-CONST('N', TCG_CT_CONST_N12)
40
+CONST('J', TCG_CT_CONST_S32)
41
CONST('U', TCG_CT_CONST_U12)
42
CONST('Z', TCG_CT_CONST_ZERO)
43
CONST('C', TCG_CT_CONST_C12)
44
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
45
index XXXXXXX..XXXXXXX 100644
46
--- a/tcg/loongarch64/tcg-target.c.inc
47
+++ b/tcg/loongarch64/tcg-target.c.inc
48
@@ -XXX,XX +XXX,XX @@ static const int tcg_target_call_oarg_regs[] = {
49
50
#define TCG_CT_CONST_ZERO 0x100
51
#define TCG_CT_CONST_S12 0x200
52
-#define TCG_CT_CONST_N12 0x400
53
+#define TCG_CT_CONST_S32 0x400
54
#define TCG_CT_CONST_U12 0x800
55
#define TCG_CT_CONST_C12 0x1000
56
#define TCG_CT_CONST_WSZ 0x2000
57
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
58
if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
59
return true;
60
}
61
- if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) {
62
+ if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
63
return true;
64
}
65
if ((ct & TCG_CT_CONST_U12) && val >= 0 && val <= 0xfff) {
66
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
67
}
68
}
69
70
+static void tcg_out_addi(TCGContext *s, TCGType type, TCGReg rd,
71
+ TCGReg rs, tcg_target_long imm)
72
+{
73
+ tcg_target_long lo12 = sextreg(imm, 0, 12);
74
+ tcg_target_long hi16 = sextreg(imm - lo12, 16, 16);
75
+
76
+ /*
77
+ * Note that there's a hole in between hi16 and lo12:
78
+ *
79
+ * 3 2 1 0
80
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
81
+ * ...+-------------------------------+-------+-----------------------+
82
+ * | hi16 | | lo12 |
83
+ * ...+-------------------------------+-------+-----------------------+
84
+ *
85
+ * For bits within that hole, it's more efficient to use LU12I and ADD.
86
+ */
87
+ if (imm == (hi16 << 16) + lo12) {
88
+ if (hi16) {
89
+ tcg_out_opc_addu16i_d(s, rd, rs, hi16);
90
+ rs = rd;
91
+ }
92
+ if (type == TCG_TYPE_I32) {
93
+ tcg_out_opc_addi_w(s, rd, rs, lo12);
94
+ } else if (lo12) {
95
+ tcg_out_opc_addi_d(s, rd, rs, lo12);
96
+ } else {
97
+ tcg_out_mov(s, type, rd, rs);
98
+ }
99
+ } else {
100
+ tcg_out_movi(s, type, TCG_REG_TMP0, imm);
101
+ if (type == TCG_TYPE_I32) {
102
+ tcg_out_opc_add_w(s, rd, rs, TCG_REG_TMP0);
103
+ } else {
104
+ tcg_out_opc_add_d(s, rd, rs, TCG_REG_TMP0);
105
+ }
106
+ }
107
+}
108
+
109
static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg)
110
{
111
tcg_out_opc_andi(s, ret, arg, 0xff);
112
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
113
114
case INDEX_op_add_i32:
115
if (c2) {
116
- tcg_out_opc_addi_w(s, a0, a1, a2);
117
+ tcg_out_addi(s, TCG_TYPE_I32, a0, a1, a2);
118
} else {
119
tcg_out_opc_add_w(s, a0, a1, a2);
120
}
121
break;
122
case INDEX_op_add_i64:
123
if (c2) {
124
- tcg_out_opc_addi_d(s, a0, a1, a2);
125
+ tcg_out_addi(s, TCG_TYPE_I64, a0, a1, a2);
126
} else {
127
tcg_out_opc_add_d(s, a0, a1, a2);
128
}
129
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
130
131
case INDEX_op_sub_i32:
132
if (c2) {
133
- tcg_out_opc_addi_w(s, a0, a1, -a2);
134
+ tcg_out_addi(s, TCG_TYPE_I32, a0, a1, -a2);
135
} else {
136
tcg_out_opc_sub_w(s, a0, a1, a2);
137
}
138
break;
139
case INDEX_op_sub_i64:
140
if (c2) {
141
- tcg_out_opc_addi_d(s, a0, a1, -a2);
142
+ tcg_out_addi(s, TCG_TYPE_I64, a0, a1, -a2);
143
} else {
144
tcg_out_opc_sub_d(s, a0, a1, a2);
145
}
146
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
147
return C_O1_I2(r, r, ri);
148
149
case INDEX_op_add_i32:
150
+ return C_O1_I2(r, r, ri);
151
case INDEX_op_add_i64:
152
- return C_O1_I2(r, r, rI);
153
+ return C_O1_I2(r, r, rJ);
154
155
case INDEX_op_and_i32:
156
case INDEX_op_and_i64:
157
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
158
return C_O1_I2(r, 0, rZ);
159
160
case INDEX_op_sub_i32:
161
+ return C_O1_I2(r, rZ, ri);
162
case INDEX_op_sub_i64:
163
- return C_O1_I2(r, rZ, rN);
164
+ return C_O1_I2(r, rZ, rJ);
165
166
case INDEX_op_mul_i32:
167
case INDEX_op_mul_i64:
168
--
169
2.34.1
diff view generated by jsdifflib
New patch
1
Split out a helper function, tcg_out_setcond_int, which
2
does not always produce the complete boolean result, but
3
returns a set of flags to do so.
1
4
5
Accept all int32_t as constant input, so that LE/GT can
6
adjust the constant to LT.
7
8
Reviewed-by: WANG Xuerui <git@xen0n.name>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
tcg/loongarch64/tcg-target.c.inc | 165 +++++++++++++++++++++----------
12
1 file changed, 115 insertions(+), 50 deletions(-)
13
14
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/loongarch64/tcg-target.c.inc
17
+++ b/tcg/loongarch64/tcg-target.c.inc
18
@@ -XXX,XX +XXX,XX @@ static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc,
19
tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
20
}
21
22
-static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
23
- TCGReg arg1, TCGReg arg2, bool c2)
24
-{
25
- TCGReg tmp;
26
+#define SETCOND_INV TCG_TARGET_NB_REGS
27
+#define SETCOND_NEZ (SETCOND_INV << 1)
28
+#define SETCOND_FLAGS (SETCOND_INV | SETCOND_NEZ)
29
30
- if (c2) {
31
- tcg_debug_assert(arg2 == 0);
32
+static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
33
+ TCGReg arg1, tcg_target_long arg2, bool c2)
34
+{
35
+ int flags = 0;
36
+
37
+ switch (cond) {
38
+ case TCG_COND_EQ: /* -> NE */
39
+ case TCG_COND_GE: /* -> LT */
40
+ case TCG_COND_GEU: /* -> LTU */
41
+ case TCG_COND_GT: /* -> LE */
42
+ case TCG_COND_GTU: /* -> LEU */
43
+ cond = tcg_invert_cond(cond);
44
+ flags ^= SETCOND_INV;
45
+ break;
46
+ default:
47
+ break;
48
}
49
50
switch (cond) {
51
- case TCG_COND_EQ:
52
- if (c2) {
53
- tmp = arg1;
54
- } else {
55
- tcg_out_opc_sub_d(s, ret, arg1, arg2);
56
- tmp = ret;
57
- }
58
- tcg_out_opc_sltui(s, ret, tmp, 1);
59
- break;
60
- case TCG_COND_NE:
61
- if (c2) {
62
- tmp = arg1;
63
- } else {
64
- tcg_out_opc_sub_d(s, ret, arg1, arg2);
65
- tmp = ret;
66
- }
67
- tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp);
68
- break;
69
- case TCG_COND_LT:
70
- tcg_out_opc_slt(s, ret, arg1, arg2);
71
- break;
72
- case TCG_COND_GE:
73
- tcg_out_opc_slt(s, ret, arg1, arg2);
74
- tcg_out_opc_xori(s, ret, ret, 1);
75
- break;
76
case TCG_COND_LE:
77
- tcg_out_setcond(s, TCG_COND_GE, ret, arg2, arg1, false);
78
- break;
79
- case TCG_COND_GT:
80
- tcg_out_setcond(s, TCG_COND_LT, ret, arg2, arg1, false);
81
- break;
82
- case TCG_COND_LTU:
83
- tcg_out_opc_sltu(s, ret, arg1, arg2);
84
- break;
85
- case TCG_COND_GEU:
86
- tcg_out_opc_sltu(s, ret, arg1, arg2);
87
- tcg_out_opc_xori(s, ret, ret, 1);
88
- break;
89
case TCG_COND_LEU:
90
- tcg_out_setcond(s, TCG_COND_GEU, ret, arg2, arg1, false);
91
+ /*
92
+ * If we have a constant input, the most efficient way to implement
93
+ * LE is by adding 1 and using LT. Watch out for wrap around for LEU.
94
+ * We don't need to care for this for LE because the constant input
95
+ * is still constrained to int32_t, and INT32_MAX+1 is representable
96
+ * in the 64-bit temporary register.
97
+ */
98
+ if (c2) {
99
+ if (cond == TCG_COND_LEU) {
100
+ /* unsigned <= -1 is true */
101
+ if (arg2 == -1) {
102
+ tcg_out_movi(s, TCG_TYPE_REG, ret, !(flags & SETCOND_INV));
103
+ return ret;
104
+ }
105
+ cond = TCG_COND_LTU;
106
+ } else {
107
+ cond = TCG_COND_LT;
108
+ }
109
+ arg2 += 1;
110
+ } else {
111
+ TCGReg tmp = arg2;
112
+ arg2 = arg1;
113
+ arg1 = tmp;
114
+ cond = tcg_swap_cond(cond); /* LE -> GE */
115
+ cond = tcg_invert_cond(cond); /* GE -> LT */
116
+ flags ^= SETCOND_INV;
117
+ }
118
break;
119
- case TCG_COND_GTU:
120
- tcg_out_setcond(s, TCG_COND_LTU, ret, arg2, arg1, false);
121
+ default:
122
break;
123
+ }
124
+
125
+ switch (cond) {
126
+ case TCG_COND_NE:
127
+ flags |= SETCOND_NEZ;
128
+ if (!c2) {
129
+ tcg_out_opc_xor(s, ret, arg1, arg2);
130
+ } else if (arg2 == 0) {
131
+ ret = arg1;
132
+ } else if (arg2 >= 0 && arg2 <= 0xfff) {
133
+ tcg_out_opc_xori(s, ret, arg1, arg2);
134
+ } else {
135
+ tcg_out_addi(s, TCG_TYPE_REG, ret, arg1, -arg2);
136
+ }
137
+ break;
138
+
139
+ case TCG_COND_LT:
140
+ case TCG_COND_LTU:
141
+ if (c2) {
142
+ if (arg2 >= -0x800 && arg2 <= 0x7ff) {
143
+ if (cond == TCG_COND_LT) {
144
+ tcg_out_opc_slti(s, ret, arg1, arg2);
145
+ } else {
146
+ tcg_out_opc_sltui(s, ret, arg1, arg2);
147
+ }
148
+ break;
149
+ }
150
+ tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP0, arg2);
151
+ arg2 = TCG_REG_TMP0;
152
+ }
153
+ if (cond == TCG_COND_LT) {
154
+ tcg_out_opc_slt(s, ret, arg1, arg2);
155
+ } else {
156
+ tcg_out_opc_sltu(s, ret, arg1, arg2);
157
+ }
158
+ break;
159
+
160
default:
161
g_assert_not_reached();
162
break;
163
}
164
+
165
+ return ret | flags;
166
+}
167
+
168
+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
169
+ TCGReg arg1, tcg_target_long arg2, bool c2)
170
+{
171
+ int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2, c2);
172
+
173
+ if (tmpflags != ret) {
174
+ TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
175
+
176
+ switch (tmpflags & SETCOND_FLAGS) {
177
+ case SETCOND_INV:
178
+ /* Intermediate result is boolean: simply invert. */
179
+ tcg_out_opc_xori(s, ret, tmp, 1);
180
+ break;
181
+ case SETCOND_NEZ:
182
+ /* Intermediate result is zero/non-zero: test != 0. */
183
+ tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp);
184
+ break;
185
+ case SETCOND_NEZ | SETCOND_INV:
186
+ /* Intermediate result is zero/non-zero: test == 0. */
187
+ tcg_out_opc_sltui(s, ret, tmp, 1);
188
+ break;
189
+ default:
190
+ g_assert_not_reached();
191
+ }
192
+ }
193
}
194
195
/*
196
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
197
case INDEX_op_ctz_i64:
198
return C_O1_I2(r, r, rW);
199
200
- case INDEX_op_setcond_i32:
201
- case INDEX_op_setcond_i64:
202
- return C_O1_I2(r, r, rZ);
203
-
204
case INDEX_op_deposit_i32:
205
case INDEX_op_deposit_i64:
206
/* Must deposit into the same register as input */
207
return C_O1_I2(r, 0, rZ);
208
209
case INDEX_op_sub_i32:
210
+ case INDEX_op_setcond_i32:
211
return C_O1_I2(r, rZ, ri);
212
case INDEX_op_sub_i64:
213
+ case INDEX_op_setcond_i64:
214
return C_O1_I2(r, rZ, rJ);
215
216
case INDEX_op_mul_i32:
217
--
218
2.34.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Reviewed-by: WANG Xuerui <git@xen0n.name>
2
3
Rather than manually copying each register, use
4
the libc memcpy(), which is well optimized nowadays.
5
6
Suggested-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-ID: <20241205205418.67613-1-philmd@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
3
---
13
target/sparc/win_helper.c | 26 ++++++++------------------
4
tcg/loongarch64/tcg-target-con-set.h | 1 +
14
1 file changed, 8 insertions(+), 18 deletions(-)
5
tcg/loongarch64/tcg-target.h | 4 ++--
6
tcg/loongarch64/tcg-target.c.inc | 33 ++++++++++++++++++++++++++++
7
3 files changed, 36 insertions(+), 2 deletions(-)
15
8
16
diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c
9
diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h
17
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
18
--- a/target/sparc/win_helper.c
11
--- a/tcg/loongarch64/tcg-target-con-set.h
19
+++ b/target/sparc/win_helper.c
12
+++ b/tcg/loongarch64/tcg-target-con-set.h
20
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@ C_O1_I2(r, 0, rZ)
21
#include "exec/helper-proto.h"
14
C_O1_I2(r, rZ, ri)
22
#include "trace.h"
15
C_O1_I2(r, rZ, rJ)
23
16
C_O1_I2(r, rZ, rZ)
24
-static inline void memcpy32(target_ulong *dst, const target_ulong *src)
17
+C_O1_I4(r, rZ, rJ, rZ, rZ)
25
-{
18
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
26
- dst[0] = src[0];
19
index XXXXXXX..XXXXXXX 100644
27
- dst[1] = src[1];
20
--- a/tcg/loongarch64/tcg-target.h
28
- dst[2] = src[2];
21
+++ b/tcg/loongarch64/tcg-target.h
29
- dst[3] = src[3];
22
@@ -XXX,XX +XXX,XX @@ typedef enum {
30
- dst[4] = src[4];
23
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
31
- dst[5] = src[5];
24
32
- dst[6] = src[6];
25
/* optional instructions */
33
- dst[7] = src[7];
26
-#define TCG_TARGET_HAS_movcond_i32 0
34
-}
27
+#define TCG_TARGET_HAS_movcond_i32 1
35
-
28
#define TCG_TARGET_HAS_div_i32 1
36
void cpu_set_cwp(CPUSPARCState *env, int new_cwp)
29
#define TCG_TARGET_HAS_rem_i32 1
37
{
30
#define TCG_TARGET_HAS_div2_i32 0
38
/* put the modified wrap registers at their proper location */
31
@@ -XXX,XX +XXX,XX @@ typedef enum {
39
if (env->cwp == env->nwindows - 1) {
32
#define TCG_TARGET_HAS_qemu_st8_i32 0
40
- memcpy32(env->regbase, env->regbase + env->nwindows * 16);
33
41
+ memcpy(env->regbase, env->regbase + env->nwindows * 16,
34
/* 64-bit operations */
42
+ sizeof(env->gregs));
35
-#define TCG_TARGET_HAS_movcond_i64 0
43
}
36
+#define TCG_TARGET_HAS_movcond_i64 1
44
env->cwp = new_cwp;
37
#define TCG_TARGET_HAS_div_i64 1
45
38
#define TCG_TARGET_HAS_rem_i64 1
46
/* put the wrap registers at their temporary location */
39
#define TCG_TARGET_HAS_div2_i64 0
47
if (new_cwp == env->nwindows - 1) {
40
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
48
- memcpy32(env->regbase + env->nwindows * 16, env->regbase);
41
index XXXXXXX..XXXXXXX 100644
49
+ memcpy(env->regbase + env->nwindows * 16, env->regbase,
42
--- a/tcg/loongarch64/tcg-target.c.inc
50
+ sizeof(env->gregs));
43
+++ b/tcg/loongarch64/tcg-target.c.inc
51
}
44
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
52
env->regwptr = env->regbase + (new_cwp * 16);
53
}
54
@@ -XXX,XX +XXX,XX @@ void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl)
55
dst = get_gl_gregset(env, env->gl);
56
57
if (src != dst) {
58
- memcpy32(dst, env->gregs);
59
- memcpy32(env->gregs, src);
60
+ memcpy(dst, env->gregs, sizeof(env->gregs));
61
+ memcpy(env->gregs, src, sizeof(env->gregs));
62
}
45
}
63
}
46
}
64
47
65
@@ -XXX,XX +XXX,XX @@ void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate)
48
+static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
66
/* Switch global register bank */
49
+ TCGReg c1, tcg_target_long c2, bool const2,
67
src = get_gregset(env, new_pstate_regs);
50
+ TCGReg v1, TCGReg v2)
68
dst = get_gregset(env, pstate_regs);
51
+{
69
- memcpy32(dst, env->gregs);
52
+ int tmpflags = tcg_out_setcond_int(s, cond, TCG_REG_TMP0, c1, c2, const2);
70
- memcpy32(env->gregs, src);
53
+ TCGReg t;
71
+ memcpy(dst, env->gregs, sizeof(env->gregs));
54
+
72
+ memcpy(env->gregs, src, sizeof(env->gregs));
55
+ /* Standardize the test below to t != 0. */
73
} else {
56
+ if (tmpflags & SETCOND_INV) {
74
trace_win_helper_no_switch_pstate(new_pstate_regs);
57
+ t = v1, v1 = v2, v2 = t;
58
+ }
59
+
60
+ t = tmpflags & ~SETCOND_FLAGS;
61
+ if (v1 == TCG_REG_ZERO) {
62
+ tcg_out_opc_masknez(s, ret, v2, t);
63
+ } else if (v2 == TCG_REG_ZERO) {
64
+ tcg_out_opc_maskeqz(s, ret, v1, t);
65
+ } else {
66
+ tcg_out_opc_masknez(s, TCG_REG_TMP2, v2, t); /* t ? 0 : v2 */
67
+ tcg_out_opc_maskeqz(s, TCG_REG_TMP1, v1, t); /* t ? v1 : 0 */
68
+ tcg_out_opc_or(s, ret, TCG_REG_TMP1, TCG_REG_TMP2);
69
+ }
70
+}
71
+
72
/*
73
* Branch helpers
74
*/
75
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
76
tcg_out_setcond(s, args[3], a0, a1, a2, c2);
77
break;
78
79
+ case INDEX_op_movcond_i32:
80
+ case INDEX_op_movcond_i64:
81
+ tcg_out_movcond(s, args[5], a0, a1, a2, c2, args[3], args[4]);
82
+ break;
83
+
84
case INDEX_op_ld8s_i32:
85
case INDEX_op_ld8s_i64:
86
tcg_out_ldst(s, OPC_LD_B, a0, a1, a2);
87
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
88
case INDEX_op_remu_i64:
89
return C_O1_I2(r, rZ, rZ);
90
91
+ case INDEX_op_movcond_i32:
92
+ case INDEX_op_movcond_i64:
93
+ return C_O1_I4(r, rZ, rJ, rZ, rZ);
94
+
95
default:
96
g_assert_not_reached();
75
}
97
}
76
--
98
--
77
2.43.0
99
2.34.1
78
79
diff view generated by jsdifflib
1
This allows targets to declare that the helper requires a
1
Take the w^x split into account when computing the
2
float_status pointer and instead of a generic void pointer.
2
pc-relative distance to an absolute pointer.
3
3
4
Reviewed-by: WANG Xuerui <git@xen0n.name>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
---
7
include/exec/helper-head.h.inc | 3 +++
8
tcg/loongarch64/tcg-target.c.inc | 2 +-
8
1 file changed, 3 insertions(+)
9
1 file changed, 1 insertion(+), 1 deletion(-)
9
10
10
diff --git a/include/exec/helper-head.h.inc b/include/exec/helper-head.h.inc
11
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
11
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
12
--- a/include/exec/helper-head.h.inc
13
--- a/tcg/loongarch64/tcg-target.c.inc
13
+++ b/include/exec/helper-head.h.inc
14
+++ b/tcg/loongarch64/tcg-target.c.inc
14
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data,
15
#define dh_alias_ptr ptr
16
intptr_t imm12 = sextreg(offset, 0, 12);
16
#define dh_alias_cptr ptr
17
17
#define dh_alias_env ptr
18
if (offset != imm12) {
18
+#define dh_alias_fpst ptr
19
- intptr_t diff = offset - (uintptr_t)s->code_ptr;
19
#define dh_alias_void void
20
+ intptr_t diff = tcg_pcrel_diff(s, (void *)offset);
20
#define dh_alias_noreturn noreturn
21
21
#define dh_alias(t) glue(dh_alias_, t)
22
if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
22
@@ -XXX,XX +XXX,XX @@
23
imm12 = sextreg(diff, 0, 12);
23
#define dh_ctype_ptr void *
24
#define dh_ctype_cptr const void *
25
#define dh_ctype_env CPUArchState *
26
+#define dh_ctype_fpst float_status *
27
#define dh_ctype_void void
28
#define dh_ctype_noreturn G_NORETURN void
29
#define dh_ctype(t) dh_ctype_##t
30
@@ -XXX,XX +XXX,XX @@
31
#define dh_typecode_f64 dh_typecode_i64
32
#define dh_typecode_cptr dh_typecode_ptr
33
#define dh_typecode_env dh_typecode_ptr
34
+#define dh_typecode_fpst dh_typecode_ptr
35
#define dh_typecode(t) dh_typecode_##t
36
37
#define dh_callflag_i32 0
38
--
24
--
39
2.43.0
25
2.34.1
40
26
41
27
diff view generated by jsdifflib
New patch
1
The old implementation replaces two insns, swapping between
1
2
3
b <dest>
4
nop
5
and
6
pcaddu18i tmp, <dest>
7
jirl zero, tmp, <dest> & 0xffff
8
9
There is a race condition in which a thread could be stopped at
10
the jirl, i.e. with the top of the address loaded, and when
11
restarted we have re-linked to a different TB, so that the top
12
half no longer matches the bottom half.
13
14
Note that while we never directly re-link to a different TB, we
15
can link, unlink, and link again all while the stopped thread
16
remains stopped.
17
18
The new implementation replaces only one insn, swapping between
19
20
b <dest>
21
and
22
pcadd tmp, <jmp_addr>
23
24
falling through to load the address from tmp, and branch.
25
26
Reviewed-by: WANG Xuerui <git@xen0n.name>
27
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
28
---
29
tcg/loongarch64/tcg-target.h | 7 +---
30
tcg/loongarch64/tcg-target.c.inc | 72 ++++++++++++++------------------
31
2 files changed, 33 insertions(+), 46 deletions(-)
32
33
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/tcg/loongarch64/tcg-target.h
36
+++ b/tcg/loongarch64/tcg-target.h
37
@@ -XXX,XX +XXX,XX @@
38
39
#define TCG_TARGET_INSN_UNIT_SIZE 4
40
#define TCG_TARGET_NB_REGS 32
41
-/*
42
- * PCADDU18I + JIRL sequence can give 20 + 16 + 2 = 38 bits
43
- * signed offset, which is +/- 128 GiB.
44
- */
45
-#define MAX_CODE_GEN_BUFFER_SIZE (128 * GiB)
46
+
47
+#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
48
49
typedef enum {
50
TCG_REG_ZERO,
51
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tcg/loongarch64/tcg-target.c.inc
54
+++ b/tcg/loongarch64/tcg-target.c.inc
55
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args)
56
#endif
57
}
58
59
-/* LoongArch uses `andi zero, zero, 0` as NOP. */
60
-#define NOP OPC_ANDI
61
-static void tcg_out_nop(TCGContext *s)
62
-{
63
- tcg_out32(s, NOP);
64
-}
65
-
66
-void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
67
- uintptr_t jmp_rx, uintptr_t jmp_rw)
68
-{
69
- tcg_insn_unit i1, i2;
70
- ptrdiff_t upper, lower;
71
- uintptr_t addr = tb->jmp_target_addr[n];
72
- ptrdiff_t offset = (ptrdiff_t)(addr - jmp_rx) >> 2;
73
-
74
- if (offset == sextreg(offset, 0, 26)) {
75
- i1 = encode_sd10k16_insn(OPC_B, offset);
76
- i2 = NOP;
77
- } else {
78
- tcg_debug_assert(offset == sextreg(offset, 0, 36));
79
- lower = (int16_t)offset;
80
- upper = (offset - lower) >> 16;
81
-
82
- i1 = encode_dsj20_insn(OPC_PCADDU18I, TCG_REG_TMP0, upper);
83
- i2 = encode_djsk16_insn(OPC_JIRL, TCG_REG_ZERO, TCG_REG_TMP0, lower);
84
- }
85
- uint64_t pair = ((uint64_t)i2 << 32) | i1;
86
- qatomic_set((uint64_t *)jmp_rw, pair);
87
- flush_idcache_range(jmp_rx, jmp_rw, 8);
88
-}
89
-
90
/*
91
* Entry-points
92
*/
93
@@ -XXX,XX +XXX,XX @@ static void tcg_out_exit_tb(TCGContext *s, uintptr_t a0)
94
static void tcg_out_goto_tb(TCGContext *s, int which)
95
{
96
/*
97
- * Ensure that patch area is 8-byte aligned so that an
98
- * atomic write can be used to patch the target address.
99
+ * Direct branch, or load indirect address, to be patched
100
+ * by tb_target_set_jmp_target. Check indirect load offset
101
+ * in range early, regardless of direct branch distance,
102
+ * via assert within tcg_out_opc_pcaddu2i.
103
*/
104
- if ((uintptr_t)s->code_ptr & 7) {
105
- tcg_out_nop(s);
106
- }
107
+ uintptr_t i_addr = get_jmp_target_addr(s, which);
108
+ intptr_t i_disp = tcg_pcrel_diff(s, (void *)i_addr);
109
+
110
set_jmp_insn_offset(s, which);
111
- /*
112
- * actual branch destination will be patched by
113
- * tb_target_set_jmp_target later
114
- */
115
- tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, 0);
116
+ tcg_out_opc_pcaddu2i(s, TCG_REG_TMP0, i_disp >> 2);
117
+
118
+ /* Finish the load and indirect branch. */
119
+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_TMP0, 0);
120
tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0);
121
set_jmp_reset_offset(s, which);
122
}
123
124
+void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
125
+ uintptr_t jmp_rx, uintptr_t jmp_rw)
126
+{
127
+ uintptr_t d_addr = tb->jmp_target_addr[n];
128
+ ptrdiff_t d_disp = (ptrdiff_t)(d_addr - jmp_rx) >> 2;
129
+ tcg_insn_unit insn;
130
+
131
+ /* Either directly branch, or load slot address for indirect branch. */
132
+ if (d_disp == sextreg(d_disp, 0, 26)) {
133
+ insn = encode_sd10k16_insn(OPC_B, d_disp);
134
+ } else {
135
+ uintptr_t i_addr = (uintptr_t)&tb->jmp_target_addr[n];
136
+ intptr_t i_disp = i_addr - jmp_rx;
137
+ insn = encode_dsj20_insn(OPC_PCADDU2I, TCG_REG_TMP0, i_disp >> 2);
138
+ }
139
+
140
+ qatomic_set((tcg_insn_unit *)jmp_rw, insn);
141
+ flush_idcache_range(jmp_rx, jmp_rw, 4);
142
+}
143
+
144
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
145
const TCGArg args[TCG_MAX_OP_ARGS],
146
const int const_args[TCG_MAX_OP_ARGS])
147
--
148
2.34.1
diff view generated by jsdifflib