1
The following changes since commit e18e5501d8ac692d32657a3e1ef545b14e72b730:
1
Second try's the charm today, right?
2
2
3
Merge remote-tracking branch 'remotes/dgilbert-gitlab/tags/pull-virtiofs-20200210' into staging (2020-02-10 18:09:14 +0000)
3
4
r~
5
6
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)
4
10
5
are available in the Git repository at:
11
are available in the Git repository at:
6
12
7
https://github.com/rth7680/qemu.git tags/pull-tcg-20200212
13
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20230123
8
14
9
for you to fetch changes up to 2445971604c1cfd3ec484457159f4ac300fb04d2:
15
for you to fetch changes up to 709bcd7da3f6b4655d910634a0d520fa1439df38:
10
16
11
tcg: Add tcg_gen_gvec_5_ptr (2020-02-12 14:58:36 -0800)
17
tcg/loongarch64: Reorg goto_tb implementation (2023-01-23 16:00:13 -1000)
12
18
13
----------------------------------------------------------------
19
----------------------------------------------------------------
14
Fix breakpoint invalidation.
20
common-user: Re-enable ppc32 host
15
Add support for tcg helpers with 7 arguments.
21
tcg: Avoid recursion in tcg_gen_mulu2_i32
16
Add support for gvec helpers with 5 arguments.
22
tcg: Mark tcg helpers noinline to avoid an issue with LTO
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
17
31
18
----------------------------------------------------------------
32
----------------------------------------------------------------
19
Max Filippov (1):
33
Richard Henderson (14):
20
exec: flush CPU TB cache in breakpoint_invalidate
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
21
48
22
Richard Henderson (1):
49
Rui Wang (1):
23
tcg: Add tcg_gen_gvec_5_ptr
50
tcg/loongarch64: Optimize immediate loading
24
51
25
Taylor Simpson (1):
52
include/exec/helper-proto.h | 32 ++-
26
tcg: Add support for a helper with 7 arguments
53
include/tcg/tcg.h | 7 -
27
54
linux-user/include/host/ppc/host-signal.h | 39 +++
28
include/exec/helper-gen.h | 13 +++++++++++++
55
tcg/arm/tcg-target-con-set.h | 7 +-
29
include/exec/helper-head.h | 2 ++
56
tcg/arm/tcg-target-con-str.h | 2 +
30
include/exec/helper-proto.h | 6 ++++++
57
tcg/loongarch64/tcg-target-con-set.h | 5 +-
31
include/exec/helper-tcg.h | 7 +++++++
58
tcg/loongarch64/tcg-target-con-str.h | 2 +-
32
include/tcg/tcg-op-gvec.h | 7 +++++++
59
tcg/loongarch64/tcg-target.h | 11 +-
33
exec.c | 15 +++++++--------
60
target/loongarch/insns.decode | 3 +-
34
tcg/tcg-op-gvec.c | 32 ++++++++++++++++++++++++++++++++
61
disas.c | 2 +
35
7 files changed, 74 insertions(+), 8 deletions(-)
62
target/loongarch/disas.c | 39 ++-
36
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
1
From: Taylor Simpson <tsimpson@quicinc.com>
1
Marking helpers __attribute__((noinline)) prevents an issue
2
with GCC's ipa-split pass under --enable-lto.
2
3
3
Currently, helpers can only take up to 6 arguments. This patch adds the
4
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1454
4
capability for up to 7 arguments. I have tested it with the Hexagon port
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
that I am preparing for submission.
6
Tested-by: Idan Horowitz <idan.horowitz@gmail.com>
6
7
Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
8
Message-Id: <1580942510-2820-1-git-send-email-tsimpson@quicinc.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
8
---
11
include/exec/helper-gen.h | 13 +++++++++++++
9
include/exec/helper-proto.h | 32 ++++++++++++++++++++++++--------
12
include/exec/helper-head.h | 2 ++
10
1 file changed, 24 insertions(+), 8 deletions(-)
13
include/exec/helper-proto.h | 6 ++++++
14
include/exec/helper-tcg.h | 7 +++++++
15
4 files changed, 28 insertions(+)
16
11
17
diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/helper-gen.h
20
+++ b/include/exec/helper-gen.h
21
@@ -XXX,XX +XXX,XX @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
22
tcg_gen_callN(HELPER(name), dh_retvar(ret), 6, args); \
23
}
24
25
+#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7)\
26
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
27
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
28
+ dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6), \
29
+ dh_arg_decl(t7, 7)) \
30
+{ \
31
+ TCGTemp *args[7] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
32
+ dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \
33
+ dh_arg(t7, 7) }; \
34
+ tcg_gen_callN(HELPER(name), dh_retvar(ret), 7, args); \
35
+}
36
+
37
#include "helper.h"
38
#include "trace/generated-helpers.h"
39
#include "trace/generated-helpers-wrappers.h"
40
@@ -XXX,XX +XXX,XX @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
41
#undef DEF_HELPER_FLAGS_4
42
#undef DEF_HELPER_FLAGS_5
43
#undef DEF_HELPER_FLAGS_6
44
+#undef DEF_HELPER_FLAGS_7
45
#undef GEN_HELPER
46
47
#endif /* HELPER_GEN_H */
48
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/include/exec/helper-head.h
51
+++ b/include/exec/helper-head.h
52
@@ -XXX,XX +XXX,XX @@
53
DEF_HELPER_FLAGS_5(name, 0, ret, t1, t2, t3, t4, t5)
54
#define DEF_HELPER_6(name, ret, t1, t2, t3, t4, t5, t6) \
55
DEF_HELPER_FLAGS_6(name, 0, ret, t1, t2, t3, t4, t5, t6)
56
+#define DEF_HELPER_7(name, ret, t1, t2, t3, t4, t5, t6, t7) \
57
+ DEF_HELPER_FLAGS_7(name, 0, ret, t1, t2, t3, t4, t5, t6, t7)
58
59
/* MAX_OPC_PARAM_IARGS must be set to n if last entry is DEF_HELPER_FLAGS_n. */
60
61
diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h
12
diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h
62
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
63
--- a/include/exec/helper-proto.h
14
--- a/include/exec/helper-proto.h
64
+++ b/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
65
@@ -XXX,XX +XXX,XX @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
74
@@ -XXX,XX +XXX,XX @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
66
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
67
dh_ctype(t4), dh_ctype(t5), dh_ctype(t6));
68
69
+#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7) \
70
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
71
+ dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \
72
+ dh_ctype(t7));
73
+
74
#include "helper.h"
75
#include "trace/generated-helpers.h"
76
#include "tcg-runtime.h"
77
@@ -XXX,XX +XXX,XX @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
78
#undef DEF_HELPER_FLAGS_4
79
#undef DEF_HELPER_FLAGS_5
75
#undef DEF_HELPER_FLAGS_5
80
#undef DEF_HELPER_FLAGS_6
76
#undef DEF_HELPER_FLAGS_6
81
+#undef DEF_HELPER_FLAGS_7
77
#undef DEF_HELPER_FLAGS_7
78
+#undef DEF_HELPER_ATTR
82
79
83
#endif /* HELPER_PROTO_H */
80
#endif /* HELPER_PROTO_H */
84
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
85
index XXXXXXX..XXXXXXX 100644
86
--- a/include/exec/helper-tcg.h
87
+++ b/include/exec/helper-tcg.h
88
@@ -XXX,XX +XXX,XX @@
89
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
90
| dh_sizemask(t5, 5) | dh_sizemask(t6, 6) },
91
92
+#define DEF_HELPER_FLAGS_7(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6, t7) \
93
+ { .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
94
+ .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
95
+ | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
96
+ | dh_sizemask(t5, 5) | dh_sizemask(t6, 6) | dh_sizemask(t7, 7) },
97
+
98
#include "helper.h"
99
#include "trace/generated-helpers.h"
100
#include "tcg-runtime.h"
101
@@ -XXX,XX +XXX,XX @@
102
#undef DEF_HELPER_FLAGS_4
103
#undef DEF_HELPER_FLAGS_5
104
#undef DEF_HELPER_FLAGS_6
105
+#undef DEF_HELPER_FLAGS_7
106
107
#endif /* HELPER_TCG_H */
108
--
81
--
109
2.20.1
82
2.34.1
110
83
111
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
New patch
1
From: Rui Wang <wangrui@loongson.cn>
1
2
3
diff:
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
10
11
Reviewed-by: WANG Xuerui <git@xen0n.name>
12
Signed-off-by: Rui Wang <wangrui@loongson.cn>
13
Message-Id: <20221107144713.845550-1-wangrui@loongson.cn>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
---
16
tcg/loongarch64/tcg-target.c.inc | 35 +++++++++++---------------------
17
1 file changed, 12 insertions(+), 23 deletions(-)
18
19
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
20
index XXXXXXX..XXXXXXX 100644
21
--- a/tcg/loongarch64/tcg-target.c.inc
22
+++ b/tcg/loongarch64/tcg-target.c.inc
23
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
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;
54
}
55
+ if (hi12 == sextreg(lo, 12, 20)) {
56
+ /* val fits in simm12: addi.w rd, zero, val */
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;
75
}
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
}
103
}
104
--
105
2.34.1
diff view generated by jsdifflib
1
Extend the vector generator infrastructure to handle
1
Regenerate with ADDU16I included:
2
5 vector arguments.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
3
$ cd loongarch-opcodes/scripts/go
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
$ go run ./genqemutcgdefs > $QEMU/tcg/loongarch64/tcg-insn-defs.c.inc
6
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
5
6
Reviewed-by: WANG Xuerui <git@xen0n.name>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
---
9
include/tcg/tcg-op-gvec.h | 7 +++++++
10
tcg/loongarch64/tcg-insn-defs.c.inc | 10 +++++++++-
10
tcg/tcg-op-gvec.c | 32 ++++++++++++++++++++++++++++++++
11
1 file changed, 9 insertions(+), 1 deletion(-)
11
2 files changed, 39 insertions(+)
12
12
13
diff --git a/include/tcg/tcg-op-gvec.h b/include/tcg/tcg-op-gvec.h
13
diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc b/tcg/loongarch64/tcg-insn-defs.c.inc
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/tcg/tcg-op-gvec.h
15
--- a/tcg/loongarch64/tcg-insn-defs.c.inc
16
+++ b/include/tcg/tcg-op-gvec.h
16
+++ b/tcg/loongarch64/tcg-insn-defs.c.inc
17
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_4_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
17
@@ -XXX,XX +XXX,XX @@
18
uint32_t maxsz, int32_t data,
18
*
19
gen_helper_gvec_4_ptr *fn);
19
* This file is auto-generated by genqemutcgdefs from
20
20
* https://github.com/loongson-community/loongarch-opcodes,
21
+typedef void gen_helper_gvec_5_ptr(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr,
21
- * from commit 961f0c60f5b63e574d785995600c71ad5413fdc4.
22
+ TCGv_ptr, TCGv_ptr, TCGv_i32);
22
+ * from commit 25ca7effe9d88101c1cf96c4005423643386d81f.
23
+void tcg_gen_gvec_5_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
23
* DO NOT EDIT.
24
+ uint32_t cofs, uint32_t eofs, TCGv_ptr ptr,
24
*/
25
+ uint32_t oprsz, uint32_t maxsz, int32_t data,
25
26
+ gen_helper_gvec_5_ptr *fn);
26
@@ -XXX,XX +XXX,XX @@ typedef enum {
27
+
27
OPC_ANDI = 0x03400000,
28
/* Expand a gvec operation. Either inline or out-of-line depending on
28
OPC_ORI = 0x03800000,
29
the actual vector size and the operations supported by the host. */
29
OPC_XORI = 0x03c00000,
30
typedef struct {
30
+ OPC_ADDU16I_D = 0x10000000,
31
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
31
OPC_LU12I_W = 0x14000000,
32
index XXXXXXX..XXXXXXX 100644
32
OPC_CU32I_D = 0x16000000,
33
--- a/tcg/tcg-op-gvec.c
33
OPC_PCADDU2I = 0x18000000,
34
+++ b/tcg/tcg-op-gvec.c
34
@@ -XXX,XX +XXX,XX @@ tcg_out_opc_xori(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12)
35
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_4_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
35
tcg_out32(s, encode_djuk12_insn(OPC_XORI, d, j, uk12));
36
tcg_temp_free_i32(desc);
37
}
36
}
38
37
39
+/* Generate a call to a gvec-style helper with five vector operands
38
+/* Emits the `addu16i.d d, j, sk16` instruction. */
40
+ and an extra pointer operand. */
39
+static void __attribute__((unused))
41
+void tcg_gen_gvec_5_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
40
+tcg_out_opc_addu16i_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16)
42
+ uint32_t cofs, uint32_t eofs, TCGv_ptr ptr,
43
+ uint32_t oprsz, uint32_t maxsz, int32_t data,
44
+ gen_helper_gvec_5_ptr *fn)
45
+{
41
+{
46
+ TCGv_ptr a0, a1, a2, a3, a4;
42
+ tcg_out32(s, encode_djsk16_insn(OPC_ADDU16I_D, d, j, sk16));
47
+ TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
48
+
49
+ a0 = tcg_temp_new_ptr();
50
+ a1 = tcg_temp_new_ptr();
51
+ a2 = tcg_temp_new_ptr();
52
+ a3 = tcg_temp_new_ptr();
53
+ a4 = tcg_temp_new_ptr();
54
+
55
+ tcg_gen_addi_ptr(a0, cpu_env, dofs);
56
+ tcg_gen_addi_ptr(a1, cpu_env, aofs);
57
+ tcg_gen_addi_ptr(a2, cpu_env, bofs);
58
+ tcg_gen_addi_ptr(a3, cpu_env, cofs);
59
+ tcg_gen_addi_ptr(a4, cpu_env, eofs);
60
+
61
+ fn(a0, a1, a2, a3, a4, ptr, desc);
62
+
63
+ tcg_temp_free_ptr(a0);
64
+ tcg_temp_free_ptr(a1);
65
+ tcg_temp_free_ptr(a2);
66
+ tcg_temp_free_ptr(a3);
67
+ tcg_temp_free_ptr(a4);
68
+ tcg_temp_free_i32(desc);
69
+}
43
+}
70
+
44
+
71
/* Return true if we want to implement something of OPRSZ bytes
45
/* Emits the `lu12i.w d, sj20` instruction. */
72
in units of LNSZ. This limits the expansion of inline code. */
46
static void __attribute__((unused))
73
static inline bool check_size_impl(uint32_t oprsz, uint32_t lnsz)
47
tcg_out_opc_lu12i_w(TCGContext *s, TCGReg d, int32_t sj20)
74
--
48
--
75
2.20.1
49
2.34.1
76
50
77
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
New patch
1
Reviewed-by: WANG Xuerui <git@xen0n.name>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
tcg/loongarch64/tcg-target-con-set.h | 1 +
5
tcg/loongarch64/tcg-target.h | 4 ++--
6
tcg/loongarch64/tcg-target.c.inc | 33 ++++++++++++++++++++++++++++
7
3 files changed, 36 insertions(+), 2 deletions(-)
1
8
9
diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/loongarch64/tcg-target-con-set.h
12
+++ b/tcg/loongarch64/tcg-target-con-set.h
13
@@ -XXX,XX +XXX,XX @@ C_O1_I2(r, 0, rZ)
14
C_O1_I2(r, rZ, ri)
15
C_O1_I2(r, rZ, rJ)
16
C_O1_I2(r, rZ, rZ)
17
+C_O1_I4(r, rZ, rJ, rZ, rZ)
18
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/tcg/loongarch64/tcg-target.h
21
+++ b/tcg/loongarch64/tcg-target.h
22
@@ -XXX,XX +XXX,XX @@ typedef enum {
23
#define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL
24
25
/* optional instructions */
26
-#define TCG_TARGET_HAS_movcond_i32 0
27
+#define TCG_TARGET_HAS_movcond_i32 1
28
#define TCG_TARGET_HAS_div_i32 1
29
#define TCG_TARGET_HAS_rem_i32 1
30
#define TCG_TARGET_HAS_div2_i32 0
31
@@ -XXX,XX +XXX,XX @@ typedef enum {
32
#define TCG_TARGET_HAS_qemu_st8_i32 0
33
34
/* 64-bit operations */
35
-#define TCG_TARGET_HAS_movcond_i64 0
36
+#define TCG_TARGET_HAS_movcond_i64 1
37
#define TCG_TARGET_HAS_div_i64 1
38
#define TCG_TARGET_HAS_rem_i64 1
39
#define TCG_TARGET_HAS_div2_i64 0
40
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
41
index XXXXXXX..XXXXXXX 100644
42
--- a/tcg/loongarch64/tcg-target.c.inc
43
+++ b/tcg/loongarch64/tcg-target.c.inc
44
@@ -XXX,XX +XXX,XX @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
45
}
46
}
47
48
+static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
49
+ TCGReg c1, tcg_target_long c2, bool const2,
50
+ TCGReg v1, TCGReg v2)
51
+{
52
+ int tmpflags = tcg_out_setcond_int(s, cond, TCG_REG_TMP0, c1, c2, const2);
53
+ TCGReg t;
54
+
55
+ /* Standardize the test below to t != 0. */
56
+ if (tmpflags & SETCOND_INV) {
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();
97
}
98
--
99
2.34.1
diff view generated by jsdifflib
1
From: Max Filippov <jcmvbkbc@gmail.com>
1
Take the w^x split into account when computing the
2
pc-relative distance to an absolute pointer.
2
3
3
When a breakpoint is inserted at location for which there's currently no
4
Reviewed-by: WANG Xuerui <git@xen0n.name>
4
virtual to physical translation no action is taken on CPU TB cache. If a
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
TB for that virtual address already exists but is not visible ATM the
6
breakpoint won't be hit next time an instruction at that address will be
7
executed.
8
9
Flush entire CPU TB cache in breakpoint_invalidate to force
10
re-translation of all TBs for the breakpoint address.
11
12
This change fixes the following scenario:
13
- linux user application is running
14
- a breakpoint is inserted from QEMU gdbstub for a user address that is
15
not currently present in the target CPU TLB
16
- an instruction at that address is executed, but the external debugger
17
doesn't get control.
18
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
21
Message-Id: <20191127220602.10827-2-jcmvbkbc@gmail.com>
22
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
23
---
7
---
24
exec.c | 15 +++++++--------
8
tcg/loongarch64/tcg-target.c.inc | 2 +-
25
1 file changed, 7 insertions(+), 8 deletions(-)
9
1 file changed, 1 insertion(+), 1 deletion(-)
26
10
27
diff --git a/exec.c b/exec.c
11
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
28
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
29
--- a/exec.c
13
--- a/tcg/loongarch64/tcg-target.c.inc
30
+++ b/exec.c
14
+++ b/tcg/loongarch64/tcg-target.c.inc
31
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
15
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data,
32
16
intptr_t imm12 = sextreg(offset, 0, 12);
33
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
17
34
{
18
if (offset != imm12) {
35
- MemTxAttrs attrs;
19
- intptr_t diff = offset - (uintptr_t)s->code_ptr;
36
- hwaddr phys = cpu_get_phys_page_attrs_debug(cpu, pc, &attrs);
20
+ intptr_t diff = tcg_pcrel_diff(s, (void *)offset);
37
- int asidx = cpu_asidx_from_attrs(cpu, attrs);
21
38
- if (phys != -1) {
22
if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
39
- /* Locks grabbed by tb_invalidate_phys_addr */
23
imm12 = sextreg(diff, 0, 12);
40
- tb_invalidate_phys_addr(cpu->cpu_ases[asidx].as,
41
- phys | (pc & ~TARGET_PAGE_MASK), attrs);
42
- }
43
+ /*
44
+ * There may not be a virtual to physical translation for the pc
45
+ * right now, but there may exist cached TB for this pc.
46
+ * Flush the whole TB cache to force re-translation of such TBs.
47
+ * This is heavyweight, but we're debugging anyway.
48
+ */
49
+ tb_flush(cpu);
50
}
51
#endif
52
53
--
24
--
54
2.20.1
25
2.34.1
55
26
56
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