1
The following changes since commit 6eeea6725a70e6fcb5abba0764496bdab07ddfb3:
1
Note that I've extended the expiration date of my gpg key
2
and have uploaded it to keyserver.ubuntu.com.
2
3
3
Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2020-10-06' into staging (2020-10-06 21:13:34 +0100)
4
5
r~
6
7
8
The following changes since commit 99c44988d5ba1866a411450c877ed818b1b70081:
9
10
Merge remote-tracking branch 'remotes/bsdimp/tags/pull-bsd-user-20210910' into staging (2021-09-11 14:00:39 +0100)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://github.com/rth7680/qemu.git tags/pull-tcg-20201008
14
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20210912
8
15
9
for you to fetch changes up to 62475e9d007d83db4d0a6ccebcda8914f392e9c9:
16
for you to fetch changes up to 267a3ec3e2a8fb3e06a9d46d09fcfc57dfefd118:
10
17
11
accel/tcg: Fix computing of is_write for MIPS (2020-10-08 05:57:32 -0500)
18
tcg/arm: Fix tcg_out_vec_op function signature (2021-09-12 05:07:36 -0700)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
Extend maximum gvec vector size
21
Fix translation race condition for user-only.
15
Fix i386 avx2 dupi
22
Fix tcg/i386 encoding for VPSLLVQ, VPSRLVQ.
16
Fix mips host user-only write detection
23
Fix tcg/arm tcg_out_vec_op signature.
17
Misc cleanups.
24
Fix tcg/ppc (32bit) build with clang.
25
Remove dupluate TCG_KICK_PERIOD definition.
26
Remove unused tcg_global_reg_new.
27
Use __builtin_bswap*.
18
28
19
----------------------------------------------------------------
29
----------------------------------------------------------------
20
Kele Huang (1):
30
Bin Meng (1):
21
accel/tcg: Fix computing of is_write for MIPS
31
tcg: Remove tcg_global_reg_new defines
22
32
23
Richard Henderson (10):
33
Ilya Leoshkevich (2):
24
tcg: Adjust simd_desc size encoding
34
accel/tcg: Add DisasContextBase argument to translator_ld*
25
tcg: Drop union from TCGArgConstraint
35
accel/tcg: Clear PAGE_WRITE before translation
26
tcg: Move sorted_args into TCGArgConstraint.sort_index
27
tcg: Remove TCG_CT_REG
28
tcg: Move some TCG_CT_* bits to TCGArgConstraint bitfields
29
tcg: Remove TCGOpDef.used
30
tcg/i386: Fix dupi for avx2 32-bit hosts
31
tcg: Fix generation of dupi_vec for 32-bit host
32
tcg/optimize: Fold dup2_vec
33
tcg: Remove TCG_TARGET_HAS_cmp_vec
34
36
35
include/tcg/tcg-gvec-desc.h | 38 ++++++++++++------
37
Jose R. Ziviani (1):
36
include/tcg/tcg.h | 22 ++++------
38
tcg/arm: Fix tcg_out_vec_op function signature
37
tcg/aarch64/tcg-target.h | 1 -
38
tcg/i386/tcg-target.h | 1 -
39
tcg/ppc/tcg-target.h | 1 -
40
accel/tcg/user-exec.c | 43 ++++++++++++++++++--
41
tcg/optimize.c | 15 +++++++
42
tcg/tcg-op-gvec.c | 35 ++++++++++++----
43
tcg/tcg-op-vec.c | 12 ++++--
44
tcg/tcg.c | 96 +++++++++++++++++++-------------------------
45
tcg/aarch64/tcg-target.c.inc | 17 ++++----
46
tcg/arm/tcg-target.c.inc | 29 ++++++-------
47
tcg/i386/tcg-target.c.inc | 39 +++++++-----------
48
tcg/mips/tcg-target.c.inc | 21 +++++-----
49
tcg/ppc/tcg-target.c.inc | 29 ++++++-------
50
tcg/riscv/tcg-target.c.inc | 16 ++++----
51
tcg/s390/tcg-target.c.inc | 22 +++++-----
52
tcg/sparc/tcg-target.c.inc | 21 ++++------
53
tcg/tci/tcg-target.c.inc | 3 +-
54
19 files changed, 244 insertions(+), 217 deletions(-)
55
39
40
Luc Michel (1):
41
accel/tcg: remove redundant TCG_KICK_PERIOD define
42
43
Richard Henderson (4):
44
tcg/i386: Split P_VEXW from P_REXW
45
include/qemu: Use builtins for bswap
46
tcg/ppc: Replace TCG_TARGET_CALL_DARWIN with _CALL_DARWIN
47
tcg/ppc: Ensure _CALL_SYSV is set for 32-bit ELF
48
49
meson.build | 6 ----
50
include/exec/translate-all.h | 1 +
51
include/exec/translator.h | 44 +++++++++++++----------
52
include/qemu/bswap.h | 53 ++-------------------------
53
include/tcg/tcg-op.h | 2 --
54
target/arm/arm_ldst.h | 12 +++----
55
accel/tcg/tcg-accel-ops-rr.c | 2 --
56
accel/tcg/translate-all.c | 59 ++++++++++++++++++-------------
57
accel/tcg/translator.c | 39 ++++++++++++++++++++
58
target/alpha/translate.c | 2 +-
59
target/arm/translate-a64.c | 2 +-
60
target/arm/translate.c | 9 ++---
61
target/hexagon/translate.c | 3 +-
62
target/hppa/translate.c | 5 +--
63
target/i386/tcg/translate.c | 10 +++---
64
target/m68k/translate.c | 2 +-
65
target/mips/tcg/translate.c | 8 ++---
66
target/openrisc/translate.c | 2 +-
67
target/ppc/translate.c | 5 +--
68
target/riscv/translate.c | 5 +--
69
target/s390x/tcg/translate.c | 16 +++++----
70
target/sh4/translate.c | 4 +--
71
target/sparc/translate.c | 2 +-
72
target/xtensa/translate.c | 5 +--
73
target/mips/tcg/micromips_translate.c.inc | 2 +-
74
target/mips/tcg/mips16e_translate.c.inc | 4 +--
75
target/mips/tcg/nanomips_translate.c.inc | 4 +--
76
tcg/arm/tcg-target.c.inc | 3 +-
77
tcg/i386/tcg-target.c.inc | 13 +++----
78
tcg/ppc/tcg-target.c.inc | 25 ++++++++++---
79
30 files changed, 185 insertions(+), 164 deletions(-)
80
diff view generated by jsdifflib
Deleted patch
1
With larger vector sizes, it turns out oprsz == maxsz, and we only
2
need to represent mismatch for oprsz <= 32. We do, however, need
3
to represent larger oprsz and do so without reducing SIMD_DATA_BITS.
4
1
5
Reduce the size of the oprsz field and increase the maxsz field.
6
Steal the oprsz value of 24 to indicate equality with maxsz.
7
8
Tested-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Frank Chang <frank.chang@sifive.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
13
include/tcg/tcg-gvec-desc.h | 38 ++++++++++++++++++++++++-------------
14
tcg/tcg-op-gvec.c | 35 ++++++++++++++++++++++++++--------
15
2 files changed, 52 insertions(+), 21 deletions(-)
16
17
diff --git a/include/tcg/tcg-gvec-desc.h b/include/tcg/tcg-gvec-desc.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/tcg/tcg-gvec-desc.h
20
+++ b/include/tcg/tcg-gvec-desc.h
21
@@ -XXX,XX +XXX,XX @@
22
#ifndef TCG_TCG_GVEC_DESC_H
23
#define TCG_TCG_GVEC_DESC_H
24
25
-/* ??? These bit widths are set for ARM SVE, maxing out at 256 byte vectors. */
26
-#define SIMD_OPRSZ_SHIFT 0
27
-#define SIMD_OPRSZ_BITS 5
28
+/*
29
+ * This configuration allows MAXSZ to represent 2048 bytes, and
30
+ * OPRSZ to match MAXSZ, or represent the smaller values 8, 16, or 32.
31
+ *
32
+ * Encode this with:
33
+ * 0, 1, 3 -> 8, 16, 32
34
+ * 2 -> maxsz
35
+ *
36
+ * This steals the input that would otherwise map to 24 to match maxsz.
37
+ */
38
+#define SIMD_MAXSZ_SHIFT 0
39
+#define SIMD_MAXSZ_BITS 8
40
41
-#define SIMD_MAXSZ_SHIFT (SIMD_OPRSZ_SHIFT + SIMD_OPRSZ_BITS)
42
-#define SIMD_MAXSZ_BITS 5
43
+#define SIMD_OPRSZ_SHIFT (SIMD_MAXSZ_SHIFT + SIMD_MAXSZ_BITS)
44
+#define SIMD_OPRSZ_BITS 2
45
46
-#define SIMD_DATA_SHIFT (SIMD_MAXSZ_SHIFT + SIMD_MAXSZ_BITS)
47
+#define SIMD_DATA_SHIFT (SIMD_OPRSZ_SHIFT + SIMD_OPRSZ_BITS)
48
#define SIMD_DATA_BITS (32 - SIMD_DATA_SHIFT)
49
50
/* Create a descriptor from components. */
51
uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t data);
52
53
-/* Extract the operation size from a descriptor. */
54
-static inline intptr_t simd_oprsz(uint32_t desc)
55
-{
56
- return (extract32(desc, SIMD_OPRSZ_SHIFT, SIMD_OPRSZ_BITS) + 1) * 8;
57
-}
58
-
59
/* Extract the max vector size from a descriptor. */
60
static inline intptr_t simd_maxsz(uint32_t desc)
61
{
62
- return (extract32(desc, SIMD_MAXSZ_SHIFT, SIMD_MAXSZ_BITS) + 1) * 8;
63
+ return extract32(desc, SIMD_MAXSZ_SHIFT, SIMD_MAXSZ_BITS) * 8 + 8;
64
+}
65
+
66
+/* Extract the operation size from a descriptor. */
67
+static inline intptr_t simd_oprsz(uint32_t desc)
68
+{
69
+ uint32_t f = extract32(desc, SIMD_OPRSZ_SHIFT, SIMD_OPRSZ_BITS);
70
+ intptr_t o = f * 8 + 8;
71
+ intptr_t m = simd_maxsz(desc);
72
+ return f == 2 ? m : o;
73
}
74
75
/* Extract the operation-specific data from a descriptor. */
76
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/tcg/tcg-op-gvec.c
79
+++ b/tcg/tcg-op-gvec.c
80
@@ -XXX,XX +XXX,XX @@ static const TCGOpcode vecop_list_empty[1] = { 0 };
81
of the operand offsets so that we can check them all at once. */
82
static void check_size_align(uint32_t oprsz, uint32_t maxsz, uint32_t ofs)
83
{
84
- uint32_t opr_align = oprsz >= 16 ? 15 : 7;
85
- uint32_t max_align = maxsz >= 16 || oprsz >= 16 ? 15 : 7;
86
- tcg_debug_assert(oprsz > 0);
87
- tcg_debug_assert(oprsz <= maxsz);
88
- tcg_debug_assert((oprsz & opr_align) == 0);
89
+ uint32_t max_align;
90
+
91
+ switch (oprsz) {
92
+ case 8:
93
+ case 16:
94
+ case 32:
95
+ tcg_debug_assert(oprsz <= maxsz);
96
+ break;
97
+ default:
98
+ tcg_debug_assert(oprsz == maxsz);
99
+ break;
100
+ }
101
+ tcg_debug_assert(maxsz <= (8 << SIMD_MAXSZ_BITS));
102
+
103
+ max_align = maxsz >= 16 ? 15 : 7;
104
tcg_debug_assert((maxsz & max_align) == 0);
105
tcg_debug_assert((ofs & max_align) == 0);
106
}
107
@@ -XXX,XX +XXX,XX @@ uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t data)
108
{
109
uint32_t desc = 0;
110
111
- assert(oprsz % 8 == 0 && oprsz <= (8 << SIMD_OPRSZ_BITS));
112
- assert(maxsz % 8 == 0 && maxsz <= (8 << SIMD_MAXSZ_BITS));
113
- assert(data == sextract32(data, 0, SIMD_DATA_BITS));
114
+ check_size_align(oprsz, maxsz, 0);
115
+ tcg_debug_assert(data == sextract32(data, 0, SIMD_DATA_BITS));
116
117
oprsz = (oprsz / 8) - 1;
118
maxsz = (maxsz / 8) - 1;
119
+
120
+ /*
121
+ * We have just asserted in check_size_align that either
122
+ * oprsz is {8,16,32} or matches maxsz. Encode the final
123
+ * case with '2', as that would otherwise map to 24.
124
+ */
125
+ if (oprsz == maxsz) {
126
+ oprsz = 2;
127
+ }
128
+
129
desc = deposit32(desc, SIMD_OPRSZ_SHIFT, SIMD_OPRSZ_BITS, oprsz);
130
desc = deposit32(desc, SIMD_MAXSZ_SHIFT, SIMD_MAXSZ_BITS, maxsz);
131
desc = deposit32(desc, SIMD_DATA_SHIFT, SIMD_DATA_BITS, data);
132
--
133
2.25.1
134
135
diff view generated by jsdifflib
1
From: Kele Huang <kele.hwang@gmail.com>
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
2
2
3
Detect all MIPS store instructions in cpu_signal_handler for all available
3
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
4
MIPS versions, and set is_write if encountering such store instructions.
4
[rth: Split out of a larger patch.]
5
6
This fixed the error while dealing with self-modified code for MIPS.
7
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Kele Huang <kele.hwang@gmail.com>
10
Signed-off-by: Xu Zou <iwatchnima@gmail.com>
11
Message-Id: <20201002081420.10814-1-kele.hwang@gmail.com>
12
[rth: Use uintptr_t for pc to fix n32 build error.]
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
---
6
---
15
accel/tcg/user-exec.c | 43 +++++++++++++++++++++++++++++++++++++++----
7
include/exec/translator.h | 9 +++++----
16
1 file changed, 39 insertions(+), 4 deletions(-)
8
target/arm/arm_ldst.h | 12 ++++++------
9
target/alpha/translate.c | 2 +-
10
target/arm/translate-a64.c | 2 +-
11
target/arm/translate.c | 9 +++++----
12
target/hexagon/translate.c | 3 ++-
13
target/hppa/translate.c | 2 +-
14
target/i386/tcg/translate.c | 10 +++++-----
15
target/m68k/translate.c | 2 +-
16
target/mips/tcg/translate.c | 8 ++++----
17
target/openrisc/translate.c | 2 +-
18
target/ppc/translate.c | 5 +++--
19
target/riscv/translate.c | 5 +++--
20
target/s390x/tcg/translate.c | 16 +++++++++-------
21
target/sh4/translate.c | 4 ++--
22
target/sparc/translate.c | 2 +-
23
target/xtensa/translate.c | 5 +++--
24
target/mips/tcg/micromips_translate.c.inc | 2 +-
25
target/mips/tcg/mips16e_translate.c.inc | 4 ++--
26
target/mips/tcg/nanomips_translate.c.inc | 4 ++--
27
20 files changed, 58 insertions(+), 50 deletions(-)
17
28
18
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
29
diff --git a/include/exec/translator.h b/include/exec/translator.h
19
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
20
--- a/accel/tcg/user-exec.c
31
--- a/include/exec/translator.h
21
+++ b/accel/tcg/user-exec.c
32
+++ b/include/exec/translator.h
22
@@ -XXX,XX +XXX,XX @@ int cpu_signal_handler(int host_signum, void *pinfo,
33
@@ -XXX,XX +XXX,XX @@ bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest);
23
34
24
#elif defined(__mips__)
35
#define GEN_TRANSLATOR_LD(fullname, type, load_fn, swap_fn) \
25
36
static inline type \
26
+#if defined(__misp16) || defined(__mips_micromips)
37
- fullname ## _swap(CPUArchState *env, abi_ptr pc, bool do_swap) \
27
+#error "Unsupported encoding"
38
+ fullname ## _swap(CPUArchState *env, DisasContextBase *dcbase, \
28
+#endif
39
+ abi_ptr pc, bool do_swap) \
29
+
40
{ \
30
int cpu_signal_handler(int host_signum, void *pinfo,
41
type ret = load_fn(env, pc); \
31
void *puc)
42
if (do_swap) { \
32
{
43
@@ -XXX,XX +XXX,XX @@ bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest);
33
siginfo_t *info = pinfo;
44
plugin_insn_append(&ret, sizeof(ret)); \
34
ucontext_t *uc = puc;
45
return ret; \
35
- greg_t pc = uc->uc_mcontext.pc;
46
} \
36
- int is_write;
47
- \
37
+ uintptr_t pc = uc->uc_mcontext.pc;
48
- static inline type fullname(CPUArchState *env, abi_ptr pc) \
38
+ uint32_t insn = *(uint32_t *)pc;
49
+ static inline type fullname(CPUArchState *env, \
39
+ int is_write = 0;
50
+ DisasContextBase *dcbase, abi_ptr pc) \
40
+
51
{ \
41
+ /* Detect all store instructions at program counter. */
52
- return fullname ## _swap(env, pc, false); \
42
+ switch((insn >> 26) & 077) {
53
+ return fullname ## _swap(env, dcbase, pc, false); \
43
+ case 050: /* SB */
54
}
44
+ case 051: /* SH */
55
45
+ case 052: /* SWL */
56
GEN_TRANSLATOR_LD(translator_ldub, uint8_t, cpu_ldub_code, /* no swap */)
46
+ case 053: /* SW */
57
diff --git a/target/arm/arm_ldst.h b/target/arm/arm_ldst.h
47
+ case 054: /* SDL */
58
index XXXXXXX..XXXXXXX 100644
48
+ case 055: /* SDR */
59
--- a/target/arm/arm_ldst.h
49
+ case 056: /* SWR */
60
+++ b/target/arm/arm_ldst.h
50
+ case 070: /* SC */
61
@@ -XXX,XX +XXX,XX @@
51
+ case 071: /* SWC1 */
62
#include "qemu/bswap.h"
52
+ case 074: /* SCD */
63
53
+ case 075: /* SDC1 */
64
/* Load an instruction and return it in the standard little-endian order */
54
+ case 077: /* SD */
65
-static inline uint32_t arm_ldl_code(CPUARMState *env, target_ulong addr,
55
+#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
66
- bool sctlr_b)
56
+ case 072: /* SWC2 */
67
+static inline uint32_t arm_ldl_code(CPUARMState *env, DisasContextBase *s,
57
+ case 076: /* SDC2 */
68
+ target_ulong addr, bool sctlr_b)
58
+#endif
69
{
59
+ is_write = 1;
70
- return translator_ldl_swap(env, addr, bswap_code(sctlr_b));
60
+ break;
71
+ return translator_ldl_swap(env, s, addr, bswap_code(sctlr_b));
61
+ case 023: /* COP1X */
72
}
62
+ /* Required in all versions of MIPS64 since
73
63
+ MIPS64r1 and subsequent versions of MIPS32r2. */
74
/* Ditto, for a halfword (Thumb) instruction */
64
+ switch (insn & 077) {
75
-static inline uint16_t arm_lduw_code(CPUARMState *env, target_ulong addr,
65
+ case 010: /* SWXC1 */
76
- bool sctlr_b)
66
+ case 011: /* SDXC1 */
77
+static inline uint16_t arm_lduw_code(CPUARMState *env, DisasContextBase* s,
67
+ case 015: /* SUXC1 */
78
+ target_ulong addr, bool sctlr_b)
68
+ is_write = 1;
79
{
69
+ }
80
#ifndef CONFIG_USER_ONLY
70
+ break;
81
/* In big-endian (BE32) mode, adjacent Thumb instructions have been swapped
71
+ }
82
@@ -XXX,XX +XXX,XX @@ static inline uint16_t arm_lduw_code(CPUARMState *env, target_ulong addr,
72
83
addr ^= 2;
73
- /* XXX: compute is_write */
84
}
74
- is_write = 0;
85
#endif
75
return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
86
- return translator_lduw_swap(env, addr, bswap_code(sctlr_b));
76
}
87
+ return translator_lduw_swap(env, s, addr, bswap_code(sctlr_b));
77
88
}
89
90
#endif
91
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/alpha/translate.c
94
+++ b/target/alpha/translate.c
95
@@ -XXX,XX +XXX,XX @@ static void alpha_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
96
{
97
DisasContext *ctx = container_of(dcbase, DisasContext, base);
98
CPUAlphaState *env = cpu->env_ptr;
99
- uint32_t insn = translator_ldl(env, ctx->base.pc_next);
100
+ uint32_t insn = translator_ldl(env, &ctx->base, ctx->base.pc_next);
101
102
ctx->base.pc_next += 4;
103
ctx->base.is_jmp = translate_one(ctx, insn);
104
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/translate-a64.c
107
+++ b/target/arm/translate-a64.c
108
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
109
uint32_t insn;
110
111
s->pc_curr = s->base.pc_next;
112
- insn = arm_ldl_code(env, s->base.pc_next, s->sctlr_b);
113
+ insn = arm_ldl_code(env, &s->base, s->base.pc_next, s->sctlr_b);
114
s->insn = insn;
115
s->base.pc_next += 4;
116
117
diff --git a/target/arm/translate.c b/target/arm/translate.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/translate.c
120
+++ b/target/arm/translate.c
121
@@ -XXX,XX +XXX,XX @@ static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
122
* boundary, so we cross the page if the first 16 bits indicate
123
* that this is a 32 bit insn.
124
*/
125
- uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
126
+ uint16_t insn = arm_lduw_code(env, &s->base, s->base.pc_next, s->sctlr_b);
127
128
return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
129
}
130
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
131
}
132
133
dc->pc_curr = dc->base.pc_next;
134
- insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
135
+ insn = arm_ldl_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
136
dc->insn = insn;
137
dc->base.pc_next += 4;
138
disas_arm_insn(dc, insn);
139
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
140
}
141
142
dc->pc_curr = dc->base.pc_next;
143
- insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
144
+ insn = arm_lduw_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
145
is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
146
dc->base.pc_next += 2;
147
if (!is_16bit) {
148
- uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
149
+ uint32_t insn2 = arm_lduw_code(env, &dc->base, dc->base.pc_next,
150
+ dc->sctlr_b);
151
152
insn = insn << 16 | insn2;
153
dc->base.pc_next += 2;
154
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/target/hexagon/translate.c
157
+++ b/target/hexagon/translate.c
158
@@ -XXX,XX +XXX,XX @@ static int read_packet_words(CPUHexagonState *env, DisasContext *ctx,
159
memset(words, 0, PACKET_WORDS_MAX * sizeof(uint32_t));
160
for (nwords = 0; !found_end && nwords < PACKET_WORDS_MAX; nwords++) {
161
words[nwords] =
162
- translator_ldl(env, ctx->base.pc_next + nwords * sizeof(uint32_t));
163
+ translator_ldl(env, &ctx->base,
164
+ ctx->base.pc_next + nwords * sizeof(uint32_t));
165
found_end = is_packet_end(words[nwords]);
166
}
167
if (!found_end) {
168
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/target/hppa/translate.c
171
+++ b/target/hppa/translate.c
172
@@ -XXX,XX +XXX,XX @@ static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
173
{
174
/* Always fetch the insn, even if nullified, so that we check
175
the page permissions for execute. */
176
- uint32_t insn = translator_ldl(env, ctx->base.pc_next);
177
+ uint32_t insn = translator_ldl(env, &ctx->base, ctx->base.pc_next);
178
179
/* Set up the IA queue for the next insn.
180
This will be overwritten by a branch. */
181
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/i386/tcg/translate.c
184
+++ b/target/i386/tcg/translate.c
185
@@ -XXX,XX +XXX,XX @@ static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
186
187
static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
188
{
189
- return translator_ldub(env, advance_pc(env, s, 1));
190
+ return translator_ldub(env, &s->base, advance_pc(env, s, 1));
191
}
192
193
static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
194
{
195
- return translator_ldsw(env, advance_pc(env, s, 2));
196
+ return translator_ldsw(env, &s->base, advance_pc(env, s, 2));
197
}
198
199
static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
200
{
201
- return translator_lduw(env, advance_pc(env, s, 2));
202
+ return translator_lduw(env, &s->base, advance_pc(env, s, 2));
203
}
204
205
static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
206
{
207
- return translator_ldl(env, advance_pc(env, s, 4));
208
+ return translator_ldl(env, &s->base, advance_pc(env, s, 4));
209
}
210
211
#ifdef TARGET_X86_64
212
static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
213
{
214
- return translator_ldq(env, advance_pc(env, s, 8));
215
+ return translator_ldq(env, &s->base, advance_pc(env, s, 8));
216
}
217
#endif
218
219
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
220
index XXXXXXX..XXXXXXX 100644
221
--- a/target/m68k/translate.c
222
+++ b/target/m68k/translate.c
223
@@ -XXX,XX +XXX,XX @@ static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
224
static inline uint16_t read_im16(CPUM68KState *env, DisasContext *s)
225
{
226
uint16_t im;
227
- im = translator_lduw(env, s->pc);
228
+ im = translator_lduw(env, &s->base, s->pc);
229
s->pc += 2;
230
return im;
231
}
232
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
233
index XXXXXXX..XXXXXXX 100644
234
--- a/target/mips/tcg/translate.c
235
+++ b/target/mips/tcg/translate.c
236
@@ -XXX,XX +XXX,XX @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
237
238
is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
239
if (ctx->insn_flags & ISA_NANOMIPS32) {
240
- ctx->opcode = translator_lduw(env, ctx->base.pc_next);
241
+ ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
242
insn_bytes = decode_isa_nanomips(env, ctx);
243
} else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
244
- ctx->opcode = translator_ldl(env, ctx->base.pc_next);
245
+ ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
246
insn_bytes = 4;
247
decode_opc(env, ctx);
248
} else if (ctx->insn_flags & ASE_MICROMIPS) {
249
- ctx->opcode = translator_lduw(env, ctx->base.pc_next);
250
+ ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
251
insn_bytes = decode_isa_micromips(env, ctx);
252
} else if (ctx->insn_flags & ASE_MIPS16) {
253
- ctx->opcode = translator_lduw(env, ctx->base.pc_next);
254
+ ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
255
insn_bytes = decode_ase_mips16e(env, ctx);
256
} else {
257
gen_reserved_instruction(ctx);
258
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
259
index XXXXXXX..XXXXXXX 100644
260
--- a/target/openrisc/translate.c
261
+++ b/target/openrisc/translate.c
262
@@ -XXX,XX +XXX,XX @@ static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
263
{
264
DisasContext *dc = container_of(dcbase, DisasContext, base);
265
OpenRISCCPU *cpu = OPENRISC_CPU(cs);
266
- uint32_t insn = translator_ldl(&cpu->env, dc->base.pc_next);
267
+ uint32_t insn = translator_ldl(&cpu->env, &dc->base, dc->base.pc_next);
268
269
if (!decode(dc, insn)) {
270
gen_illegal_exception(dc);
271
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
272
index XXXXXXX..XXXXXXX 100644
273
--- a/target/ppc/translate.c
274
+++ b/target/ppc/translate.c
275
@@ -XXX,XX +XXX,XX @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
276
ctx->base.pc_next, ctx->mem_idx, (int)msr_ir);
277
278
ctx->cia = pc = ctx->base.pc_next;
279
- insn = translator_ldl_swap(env, pc, need_byteswap(ctx));
280
+ insn = translator_ldl_swap(env, dcbase, pc, need_byteswap(ctx));
281
ctx->base.pc_next = pc += 4;
282
283
if (!is_prefix_insn(ctx, insn)) {
284
@@ -XXX,XX +XXX,XX @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
285
gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_INSN);
286
ok = true;
287
} else {
288
- uint32_t insn2 = translator_ldl_swap(env, pc, need_byteswap(ctx));
289
+ uint32_t insn2 = translator_ldl_swap(env, dcbase, pc,
290
+ need_byteswap(ctx));
291
ctx->base.pc_next = pc += 4;
292
ok = decode_insn64(ctx, deposit64(insn2, 32, 32, insn));
293
}
294
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
295
index XXXXXXX..XXXXXXX 100644
296
--- a/target/riscv/translate.c
297
+++ b/target/riscv/translate.c
298
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
299
} else {
300
uint32_t opcode32 = opcode;
301
opcode32 = deposit32(opcode32, 16, 16,
302
- translator_lduw(env, ctx->base.pc_next + 2));
303
+ translator_lduw(env, &ctx->base,
304
+ ctx->base.pc_next + 2));
305
ctx->pc_succ_insn = ctx->base.pc_next + 4;
306
if (!decode_insn32(ctx, opcode32)) {
307
gen_exception_illegal(ctx);
308
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
309
{
310
DisasContext *ctx = container_of(dcbase, DisasContext, base);
311
CPURISCVState *env = cpu->env_ptr;
312
- uint16_t opcode16 = translator_lduw(env, ctx->base.pc_next);
313
+ uint16_t opcode16 = translator_lduw(env, &ctx->base, ctx->base.pc_next);
314
315
decode_opc(env, ctx, opcode16);
316
ctx->base.pc_next = ctx->pc_succ_insn;
317
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
318
index XXXXXXX..XXXXXXX 100644
319
--- a/target/s390x/tcg/translate.c
320
+++ b/target/s390x/tcg/translate.c
321
@@ -XXX,XX +XXX,XX @@ static void update_cc_op(DisasContext *s)
322
}
323
}
324
325
-static inline uint64_t ld_code2(CPUS390XState *env, uint64_t pc)
326
+static inline uint64_t ld_code2(CPUS390XState *env, DisasContext *s,
327
+ uint64_t pc)
328
{
329
- return (uint64_t)cpu_lduw_code(env, pc);
330
+ return (uint64_t)translator_lduw(env, &s->base, pc);
331
}
332
333
-static inline uint64_t ld_code4(CPUS390XState *env, uint64_t pc)
334
+static inline uint64_t ld_code4(CPUS390XState *env, DisasContext *s,
335
+ uint64_t pc)
336
{
337
- return (uint64_t)(uint32_t)cpu_ldl_code(env, pc);
338
+ return (uint64_t)(uint32_t)translator_ldl(env, &s->base, pc);
339
}
340
341
static int get_mem_index(DisasContext *s)
342
@@ -XXX,XX +XXX,XX @@ static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s)
343
ilen = s->ex_value & 0xf;
344
op = insn >> 56;
345
} else {
346
- insn = ld_code2(env, pc);
347
+ insn = ld_code2(env, s, pc);
348
op = (insn >> 8) & 0xff;
349
ilen = get_ilen(op);
350
switch (ilen) {
351
@@ -XXX,XX +XXX,XX @@ static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s)
352
insn = insn << 48;
353
break;
354
case 4:
355
- insn = ld_code4(env, pc) << 32;
356
+ insn = ld_code4(env, s, pc) << 32;
357
break;
358
case 6:
359
- insn = (insn << 48) | (ld_code4(env, pc + 2) << 16);
360
+ insn = (insn << 48) | (ld_code4(env, s, pc + 2) << 16);
361
break;
362
default:
363
g_assert_not_reached();
364
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
365
index XXXXXXX..XXXXXXX 100644
366
--- a/target/sh4/translate.c
367
+++ b/target/sh4/translate.c
368
@@ -XXX,XX +XXX,XX @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
369
370
/* Read all of the insns for the region. */
371
for (i = 0; i < max_insns; ++i) {
372
- insns[i] = translator_lduw(env, pc + i * 2);
373
+ insns[i] = translator_lduw(env, &ctx->base, pc + i * 2);
374
}
375
376
ld_adr = ld_dst = ld_mop = -1;
377
@@ -XXX,XX +XXX,XX @@ static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
378
}
379
#endif
380
381
- ctx->opcode = translator_lduw(env, ctx->base.pc_next);
382
+ ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
383
decode_opc(ctx);
384
ctx->base.pc_next += 2;
385
}
386
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
387
index XXXXXXX..XXXXXXX 100644
388
--- a/target/sparc/translate.c
389
+++ b/target/sparc/translate.c
390
@@ -XXX,XX +XXX,XX @@ static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
391
CPUSPARCState *env = cs->env_ptr;
392
unsigned int insn;
393
394
- insn = translator_ldl(env, dc->pc);
395
+ insn = translator_ldl(env, &dc->base, dc->pc);
396
dc->base.pc_next += 4;
397
disas_sparc_insn(dc, insn);
398
399
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
400
index XXXXXXX..XXXXXXX 100644
401
--- a/target/xtensa/translate.c
402
+++ b/target/xtensa/translate.c
403
@@ -XXX,XX +XXX,XX @@ static int arg_copy_compare(const void *a, const void *b)
404
static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
405
{
406
xtensa_isa isa = dc->config->isa;
407
- unsigned char b[MAX_INSN_LENGTH] = {translator_ldub(env, dc->pc)};
408
+ unsigned char b[MAX_INSN_LENGTH] = {translator_ldub(env, &dc->base,
409
+ dc->pc)};
410
unsigned len = xtensa_op0_insn_len(dc, b[0]);
411
xtensa_format fmt;
412
int slot, slots;
413
@@ -XXX,XX +XXX,XX @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
414
415
dc->base.pc_next = dc->pc + len;
416
for (i = 1; i < len; ++i) {
417
- b[i] = translator_ldub(env, dc->pc + i);
418
+ b[i] = translator_ldub(env, &dc->base, dc->pc + i);
419
}
420
xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len);
421
fmt = xtensa_format_decode(isa, dc->insnbuf);
422
diff --git a/target/mips/tcg/micromips_translate.c.inc b/target/mips/tcg/micromips_translate.c.inc
423
index XXXXXXX..XXXXXXX 100644
424
--- a/target/mips/tcg/micromips_translate.c.inc
425
+++ b/target/mips/tcg/micromips_translate.c.inc
426
@@ -XXX,XX +XXX,XX @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
427
uint32_t op, minor, minor2, mips32_op;
428
uint32_t cond, fmt, cc;
429
430
- insn = translator_lduw(env, ctx->base.pc_next + 2);
431
+ insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
432
ctx->opcode = (ctx->opcode << 16) | insn;
433
434
rt = (ctx->opcode >> 21) & 0x1f;
435
diff --git a/target/mips/tcg/mips16e_translate.c.inc b/target/mips/tcg/mips16e_translate.c.inc
436
index XXXXXXX..XXXXXXX 100644
437
--- a/target/mips/tcg/mips16e_translate.c.inc
438
+++ b/target/mips/tcg/mips16e_translate.c.inc
439
@@ -XXX,XX +XXX,XX @@ static void decode_i64_mips16(DisasContext *ctx,
440
441
static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
442
{
443
- int extend = translator_lduw(env, ctx->base.pc_next + 2);
444
+ int extend = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
445
int op, rx, ry, funct, sa;
446
int16_t imm, offset;
447
448
@@ -XXX,XX +XXX,XX @@ static int decode_ase_mips16e(CPUMIPSState *env, DisasContext *ctx)
449
/* No delay slot, so just process as a normal instruction */
450
break;
451
case M16_OPC_JAL:
452
- offset = translator_lduw(env, ctx->base.pc_next + 2);
453
+ offset = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
454
offset = (((ctx->opcode & 0x1f) << 21)
455
| ((ctx->opcode >> 5) & 0x1f) << 16
456
| offset) << 2;
457
diff --git a/target/mips/tcg/nanomips_translate.c.inc b/target/mips/tcg/nanomips_translate.c.inc
458
index XXXXXXX..XXXXXXX 100644
459
--- a/target/mips/tcg/nanomips_translate.c.inc
460
+++ b/target/mips/tcg/nanomips_translate.c.inc
461
@@ -XXX,XX +XXX,XX @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
462
int offset;
463
int imm;
464
465
- insn = translator_lduw(env, ctx->base.pc_next + 2);
466
+ insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
467
ctx->opcode = (ctx->opcode << 16) | insn;
468
469
rt = extract32(ctx->opcode, 21, 5);
470
@@ -XXX,XX +XXX,XX @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
471
break;
472
case NM_P48I:
473
{
474
- insn = translator_lduw(env, ctx->base.pc_next + 4);
475
+ insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 4);
476
target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
477
switch (extract32(ctx->opcode, 16, 5)) {
478
case NM_LI48:
78
--
479
--
79
2.25.1
480
2.25.1
80
481
81
482
diff view generated by jsdifflib
1
These are easier to set and test when they have their own fields.
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
2
Reduce the size of alias_index and sort_index to 4 bits, which is
2
3
sufficient for TCG_MAX_OP_ARGS. This leaves only the bits indicating
3
translate_insn() implementations fetch instruction bytes piecemeal,
4
constants within the ct field.
4
which can cause qemu-user to generate inconsistent translations if
5
5
another thread modifies them concurrently [1].
6
Move all initialization to allocation time, rather than init
6
7
individual fields in process_op_defs.
7
Fix by making pages containing translated instruction non-writable
8
8
right before loading instruction bytes from them.
9
10
[1] https://lists.nongnu.org/archive/html/qemu-devel/2021-08/msg00644.html
11
12
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
13
Message-Id: <20210805204835.158918-1-iii@linux.ibm.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
15
---
11
include/tcg/tcg.h | 14 +++++++-------
16
include/exec/translate-all.h | 1 +
12
tcg/tcg.c | 28 ++++++++++++----------------
17
include/exec/translator.h | 39 ++++++++++++++----------
13
2 files changed, 19 insertions(+), 23 deletions(-)
18
accel/tcg/translate-all.c | 59 +++++++++++++++++++++---------------
14
19
accel/tcg/translator.c | 39 ++++++++++++++++++++++++
15
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
20
4 files changed, 97 insertions(+), 41 deletions(-)
16
index XXXXXXX..XXXXXXX 100644
21
17
--- a/include/tcg/tcg.h
22
diff --git a/include/exec/translate-all.h b/include/exec/translate-all.h
18
+++ b/include/tcg/tcg.h
23
index XXXXXXX..XXXXXXX 100644
19
@@ -XXX,XX +XXX,XX @@ int64_t tcg_cpu_exec_time(void);
24
--- a/include/exec/translate-all.h
20
void tcg_dump_info(void);
25
+++ b/include/exec/translate-all.h
21
void tcg_dump_op_count(void);
26
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end);
22
27
void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr);
23
-#define TCG_CT_ALIAS 0x80
28
24
-#define TCG_CT_IALIAS 0x40
29
#ifdef CONFIG_USER_ONLY
25
-#define TCG_CT_NEWREG 0x20 /* output requires a new register */
30
+void page_protect(tb_page_addr_t page_addr);
26
-#define TCG_CT_CONST 0x02 /* any constant of register size */
31
int page_unprotect(target_ulong address, uintptr_t pc);
27
+#define TCG_CT_CONST 1 /* any constant of register size */
32
#endif
28
33
29
typedef struct TCGArgConstraint {
34
diff --git a/include/exec/translator.h b/include/exec/translator.h
30
- uint16_t ct;
35
index XXXXXXX..XXXXXXX 100644
31
- uint8_t alias_index;
36
--- a/include/exec/translator.h
32
- uint8_t sort_index;
37
+++ b/include/exec/translator.h
33
+ unsigned ct : 16;
38
@@ -XXX,XX +XXX,XX @@
34
+ unsigned alias_index : 4;
39
#include "exec/exec-all.h"
35
+ unsigned sort_index : 4;
40
#include "exec/cpu_ldst.h"
36
+ bool oalias : 1;
41
#include "exec/plugin-gen.h"
37
+ bool ialias : 1;
42
+#include "exec/translate-all.h"
38
+ bool newreg : 1;
43
#include "tcg/tcg.h"
39
TCGRegSet regs;
44
40
} TCGArgConstraint;
45
41
46
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContextBase {
42
diff --git a/tcg/tcg.c b/tcg/tcg.c
47
int num_insns;
43
index XXXXXXX..XXXXXXX 100644
48
int max_insns;
44
--- a/tcg/tcg.c
49
bool singlestep_enabled;
45
+++ b/tcg/tcg.c
50
+#ifdef CONFIG_USER_ONLY
46
@@ -XXX,XX +XXX,XX @@ void tcg_context_init(TCGContext *s)
51
+ /*
47
total_args += n;
52
+ * Guest address of the last byte of the last protected page.
53
+ *
54
+ * Pages containing the translated instructions are made non-writable in
55
+ * order to achieve consistency in case another thread is modifying the
56
+ * code while translate_insn() fetches the instruction bytes piecemeal.
57
+ * Such writer threads are blocked on mmap_lock() in page_unprotect().
58
+ */
59
+ target_ulong page_protect_end;
60
+#endif
61
} DisasContextBase;
62
63
/**
64
@@ -XXX,XX +XXX,XX @@ bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest);
65
*/
66
67
#define GEN_TRANSLATOR_LD(fullname, type, load_fn, swap_fn) \
68
- static inline type \
69
- fullname ## _swap(CPUArchState *env, DisasContextBase *dcbase, \
70
- abi_ptr pc, bool do_swap) \
71
- { \
72
- type ret = load_fn(env, pc); \
73
- if (do_swap) { \
74
- ret = swap_fn(ret); \
75
- } \
76
- plugin_insn_append(&ret, sizeof(ret)); \
77
- return ret; \
78
- } \
79
+ type fullname ## _swap(CPUArchState *env, DisasContextBase *dcbase, \
80
+ abi_ptr pc, bool do_swap); \
81
static inline type fullname(CPUArchState *env, \
82
DisasContextBase *dcbase, abi_ptr pc) \
83
{ \
84
return fullname ## _swap(env, dcbase, pc, false); \
48
}
85
}
49
86
50
- args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
87
-GEN_TRANSLATOR_LD(translator_ldub, uint8_t, cpu_ldub_code, /* no swap */)
51
+ args_ct = g_new0(TCGArgConstraint, total_args);
88
-GEN_TRANSLATOR_LD(translator_ldsw, int16_t, cpu_ldsw_code, bswap16)
52
89
-GEN_TRANSLATOR_LD(translator_lduw, uint16_t, cpu_lduw_code, bswap16)
53
for(op = 0; op < NB_OPS; op++) {
90
-GEN_TRANSLATOR_LD(translator_ldl, uint32_t, cpu_ldl_code, bswap32)
54
def = &tcg_op_defs[op];
91
-GEN_TRANSLATOR_LD(translator_ldq, uint64_t, cpu_ldq_code, bswap64)
55
@@ -XXX,XX +XXX,XX @@ static int get_constraint_priority(const TCGOpDef *def, int k)
92
+#define FOR_EACH_TRANSLATOR_LD(F) \
56
const TCGArgConstraint *arg_ct = &def->args_ct[k];
93
+ F(translator_ldub, uint8_t, cpu_ldub_code, /* no swap */) \
57
int n;
94
+ F(translator_ldsw, int16_t, cpu_ldsw_code, bswap16) \
58
95
+ F(translator_lduw, uint16_t, cpu_lduw_code, bswap16) \
59
- if (arg_ct->ct & TCG_CT_ALIAS) {
96
+ F(translator_ldl, uint32_t, cpu_ldl_code, bswap32) \
60
+ if (arg_ct->oalias) {
97
+ F(translator_ldq, uint64_t, cpu_ldq_code, bswap64)
61
/* an alias is equivalent to a single register */
98
+
62
n = 1;
99
+FOR_EACH_TRANSLATOR_LD(GEN_TRANSLATOR_LD)
63
} else {
100
+
64
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
101
#undef GEN_TRANSLATOR_LD
65
/* Incomplete TCGTargetOpDef entry. */
102
66
tcg_debug_assert(ct_str != NULL);
103
#endif /* EXEC__TRANSLATOR_H */
67
104
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
68
- def->args_ct[i].regs = 0;
105
index XXXXXXX..XXXXXXX 100644
69
- def->args_ct[i].ct = 0;
106
--- a/accel/tcg/translate-all.c
70
while (*ct_str != '\0') {
107
+++ b/accel/tcg/translate-all.c
71
switch(*ct_str) {
108
@@ -XXX,XX +XXX,XX @@ static inline void tb_page_add(PageDesc *p, TranslationBlock *tb,
72
case '0' ... '9':
109
invalidate_page_bitmap(p);
73
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
110
74
tcg_debug_assert(ct_str == tdefs->args_ct_str[i]);
111
#if defined(CONFIG_USER_ONLY)
75
tcg_debug_assert(oarg < def->nb_oargs);
112
- if (p->flags & PAGE_WRITE) {
76
tcg_debug_assert(def->args_ct[oarg].regs != 0);
113
- target_ulong addr;
77
- /* TCG_CT_ALIAS is for the output arguments.
114
- PageDesc *p2;
78
- The input is tagged with TCG_CT_IALIAS. */
115
- int prot;
79
def->args_ct[i] = def->args_ct[oarg];
116
-
80
- def->args_ct[oarg].ct |= TCG_CT_ALIAS;
117
- /* force the host page as non writable (writes will have a
81
+ /* The output sets oalias. */
118
- page fault + mprotect overhead) */
82
+ def->args_ct[oarg].oalias = true;
119
- page_addr &= qemu_host_page_mask;
83
def->args_ct[oarg].alias_index = i;
120
- prot = 0;
84
- def->args_ct[i].ct |= TCG_CT_IALIAS;
121
- for (addr = page_addr; addr < page_addr + qemu_host_page_size;
85
+ /* The input sets ialias. */
122
- addr += TARGET_PAGE_SIZE) {
86
+ def->args_ct[i].ialias = true;
123
-
87
def->args_ct[i].alias_index = oarg;
124
- p2 = page_find(addr >> TARGET_PAGE_BITS);
88
}
125
- if (!p2) {
89
ct_str++;
126
- continue;
90
break;
127
- }
91
case '&':
128
- prot |= p2->flags;
92
- def->args_ct[i].ct |= TCG_CT_NEWREG;
129
- p2->flags &= ~PAGE_WRITE;
93
+ def->args_ct[i].newreg = true;
130
- }
94
ct_str++;
131
- mprotect(g2h_untagged(page_addr), qemu_host_page_size,
95
break;
132
- (prot & PAGE_BITS) & ~PAGE_WRITE);
96
case 'i':
133
- if (DEBUG_TB_INVALIDATE_GATE) {
97
@@ -XXX,XX +XXX,XX @@ static void liveness_pass_1(TCGContext *s)
134
- printf("protecting code page: 0x" TB_PAGE_ADDR_FMT "\n", page_addr);
98
set = *pset;
135
- }
99
136
- }
100
set &= ct->regs;
137
+ /* translator_loop() must have made all TB pages non-writable */
101
- if (ct->ct & TCG_CT_IALIAS) {
138
+ assert(!(p->flags & PAGE_WRITE));
102
+ if (ct->ialias) {
139
#else
103
set &= op->output_pref[ct->alias_index];
140
/* if some code is already present, then the pages are already
104
}
141
protected. So we handle the case where only the first TB is
105
/* If the combination is not possible, restart. */
142
@@ -XXX,XX +XXX,XX @@ int page_check_range(target_ulong start, target_ulong len, int flags)
106
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
143
return 0;
107
}
144
}
108
145
109
i_preferred_regs = o_preferred_regs = 0;
146
+void page_protect(tb_page_addr_t page_addr)
110
- if (arg_ct->ct & TCG_CT_IALIAS) {
147
+{
111
+ if (arg_ct->ialias) {
148
+ target_ulong addr;
112
o_preferred_regs = op->output_pref[arg_ct->alias_index];
149
+ PageDesc *p;
113
if (ts->fixed_reg) {
150
+ int prot;
114
/* if fixed register, we must allocate a new register
151
+
115
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
152
+ p = page_find(page_addr >> TARGET_PAGE_BITS);
116
reg = ts->reg;
153
+ if (p && (p->flags & PAGE_WRITE)) {
117
for (k2 = 0 ; k2 < k ; k2++) {
154
+ /*
118
i2 = def->args_ct[nb_oargs + k2].sort_index;
155
+ * Force the host page as non writable (writes will have a page fault +
119
- if ((def->args_ct[i2].ct & TCG_CT_IALIAS) &&
156
+ * mprotect overhead).
120
- reg == new_args[i2]) {
157
+ */
121
+ if (def->args_ct[i2].ialias && reg == new_args[i2]) {
158
+ page_addr &= qemu_host_page_mask;
122
goto allocate_in_reg;
159
+ prot = 0;
123
}
160
+ for (addr = page_addr; addr < page_addr + qemu_host_page_size;
124
}
161
+ addr += TARGET_PAGE_SIZE) {
125
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
162
+
126
/* ENV should not be modified. */
163
+ p = page_find(addr >> TARGET_PAGE_BITS);
127
tcg_debug_assert(!ts->fixed_reg);
164
+ if (!p) {
128
165
+ continue;
129
- if ((arg_ct->ct & TCG_CT_ALIAS)
166
+ }
130
- && !const_args[arg_ct->alias_index]) {
167
+ prot |= p->flags;
131
+ if (arg_ct->oalias && !const_args[arg_ct->alias_index]) {
168
+ p->flags &= ~PAGE_WRITE;
132
reg = new_args[arg_ct->alias_index];
169
+ }
133
- } else if (arg_ct->ct & TCG_CT_NEWREG) {
170
+ mprotect(g2h_untagged(page_addr), qemu_host_page_size,
134
+ } else if (arg_ct->newreg) {
171
+ (prot & PAGE_BITS) & ~PAGE_WRITE);
135
reg = tcg_reg_alloc(s, arg_ct->regs,
172
+ if (DEBUG_TB_INVALIDATE_GATE) {
136
i_allocated_regs | o_allocated_regs,
173
+ printf("protecting code page: 0x" TB_PAGE_ADDR_FMT "\n", page_addr);
137
op->output_pref[k], ts->indirect_base);
174
+ }
175
+ }
176
+}
177
+
178
/* called from signal handler: invalidate the code and unprotect the
179
* page. Return 0 if the fault was not handled, 1 if it was handled,
180
* and 2 if it was handled but the caller must cause the TB to be
181
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/accel/tcg/translator.c
184
+++ b/accel/tcg/translator.c
185
@@ -XXX,XX +XXX,XX @@ bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest)
186
return ((db->pc_first ^ dest) & TARGET_PAGE_MASK) == 0;
187
}
188
189
+static inline void translator_page_protect(DisasContextBase *dcbase,
190
+ target_ulong pc)
191
+{
192
+#ifdef CONFIG_USER_ONLY
193
+ dcbase->page_protect_end = pc | ~TARGET_PAGE_MASK;
194
+ page_protect(pc);
195
+#endif
196
+}
197
+
198
void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
199
CPUState *cpu, TranslationBlock *tb, int max_insns)
200
{
201
@@ -XXX,XX +XXX,XX @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
202
db->num_insns = 0;
203
db->max_insns = max_insns;
204
db->singlestep_enabled = cflags & CF_SINGLE_STEP;
205
+ translator_page_protect(db, db->pc_next);
206
207
ops->init_disas_context(db, cpu);
208
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
209
@@ -XXX,XX +XXX,XX @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
210
}
211
#endif
212
}
213
+
214
+static inline void translator_maybe_page_protect(DisasContextBase *dcbase,
215
+ target_ulong pc, size_t len)
216
+{
217
+#ifdef CONFIG_USER_ONLY
218
+ target_ulong end = pc + len - 1;
219
+
220
+ if (end > dcbase->page_protect_end) {
221
+ translator_page_protect(dcbase, end);
222
+ }
223
+#endif
224
+}
225
+
226
+#define GEN_TRANSLATOR_LD(fullname, type, load_fn, swap_fn) \
227
+ type fullname ## _swap(CPUArchState *env, DisasContextBase *dcbase, \
228
+ abi_ptr pc, bool do_swap) \
229
+ { \
230
+ translator_maybe_page_protect(dcbase, pc, sizeof(type)); \
231
+ type ret = load_fn(env, pc); \
232
+ if (do_swap) { \
233
+ ret = swap_fn(ret); \
234
+ } \
235
+ plugin_insn_append(&ret, sizeof(ret)); \
236
+ return ret; \
237
+ }
238
+
239
+FOR_EACH_TRANSLATOR_LD(GEN_TRANSLATOR_LD)
240
+
241
+#undef GEN_TRANSLATOR_LD
138
--
242
--
139
2.25.1
243
2.25.1
140
244
141
245
diff view generated by jsdifflib
1
The previous change wrongly stated that 32-bit avx2 should have
1
We need to be able to represent VEX.W on a 32-bit host, where REX.W
2
used VPBROADCASTW. But that's a 16-bit broadcast and we want a
2
will always be zero. Fixes the encoding for VPSLLVQ and VPSRLVQ.
3
32-bit broadcast.
4
3
5
Fixes: 7b60ef3264e
4
Fixes: a2ce146a068 ("tcg/i386: Support vector variable shift opcodes")
6
Cc: qemu-stable@nongnu.org
5
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/385
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
7
---
9
tcg/i386/tcg-target.c.inc | 2 +-
8
tcg/i386/tcg-target.c.inc | 13 +++++++------
10
1 file changed, 1 insertion(+), 1 deletion(-)
9
1 file changed, 7 insertions(+), 6 deletions(-)
11
10
12
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
11
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/i386/tcg-target.c.inc
13
--- a/tcg/i386/tcg-target.c.inc
15
+++ b/tcg/i386/tcg-target.c.inc
14
+++ b/tcg/i386/tcg-target.c.inc
16
@@ -XXX,XX +XXX,XX @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
15
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
17
new_pool_label(s, arg, R_386_PC32, s->code_ptr - 4, -4);
16
#define P_EXT        0x100        /* 0x0f opcode prefix */
18
} else {
17
#define P_EXT38 0x200 /* 0x0f 0x38 opcode prefix */
19
if (have_avx2) {
18
#define P_DATA16 0x400 /* 0x66 opcode prefix */
20
- tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTW + vex_l, ret);
19
+#define P_VEXW 0x1000 /* Set VEX.W = 1 */
21
+ tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTD + vex_l, ret);
20
#if TCG_TARGET_REG_BITS == 64
22
} else {
21
-# define P_REXW 0x1000 /* Set REX.W = 1 */
23
tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSS, ret);
22
+# define P_REXW P_VEXW /* Set REX.W = 1; match VEXW */
24
}
23
# define P_REXB_R 0x2000 /* REG field as byte register */
24
# define P_REXB_RM 0x4000 /* R/M field as byte register */
25
# define P_GS 0x8000 /* gs segment override */
26
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
27
#define OPC_VPBROADCASTW (0x79 | P_EXT38 | P_DATA16)
28
#define OPC_VPBROADCASTD (0x58 | P_EXT38 | P_DATA16)
29
#define OPC_VPBROADCASTQ (0x59 | P_EXT38 | P_DATA16)
30
-#define OPC_VPERMQ (0x00 | P_EXT3A | P_DATA16 | P_REXW)
31
+#define OPC_VPERMQ (0x00 | P_EXT3A | P_DATA16 | P_VEXW)
32
#define OPC_VPERM2I128 (0x46 | P_EXT3A | P_DATA16 | P_VEXL)
33
#define OPC_VPSLLVD (0x47 | P_EXT38 | P_DATA16)
34
-#define OPC_VPSLLVQ (0x47 | P_EXT38 | P_DATA16 | P_REXW)
35
+#define OPC_VPSLLVQ (0x47 | P_EXT38 | P_DATA16 | P_VEXW)
36
#define OPC_VPSRAVD (0x46 | P_EXT38 | P_DATA16)
37
#define OPC_VPSRLVD (0x45 | P_EXT38 | P_DATA16)
38
-#define OPC_VPSRLVQ (0x45 | P_EXT38 | P_DATA16 | P_REXW)
39
+#define OPC_VPSRLVQ (0x45 | P_EXT38 | P_DATA16 | P_VEXW)
40
#define OPC_VZEROUPPER (0x77 | P_EXT)
41
#define OPC_XCHG_ax_r32    (0x90)
42
43
@@ -XXX,XX +XXX,XX @@ static void tcg_out_vex_opc(TCGContext *s, int opc, int r, int v,
44
45
/* Use the two byte form if possible, which cannot encode
46
VEX.W, VEX.B, VEX.X, or an m-mmmm field other than P_EXT. */
47
- if ((opc & (P_EXT | P_EXT38 | P_EXT3A | P_REXW)) == P_EXT
48
+ if ((opc & (P_EXT | P_EXT38 | P_EXT3A | P_VEXW)) == P_EXT
49
&& ((rm | index) & 8) == 0) {
50
/* Two byte VEX prefix. */
51
tcg_out8(s, 0xc5);
52
@@ -XXX,XX +XXX,XX @@ static void tcg_out_vex_opc(TCGContext *s, int opc, int r, int v,
53
tmp |= (rm & 8 ? 0 : 0x20); /* VEX.B */
54
tcg_out8(s, tmp);
55
56
- tmp = (opc & P_REXW ? 0x80 : 0); /* VEX.W */
57
+ tmp = (opc & P_VEXW ? 0x80 : 0); /* VEX.W */
58
}
59
60
tmp |= (opc & P_VEXL ? 0x04 : 0); /* VEX.L */
25
--
61
--
26
2.25.1
62
2.25.1
27
63
28
64
diff view generated by jsdifflib
1
The cmp_vec opcode is mandatory; this symbol is unused.
1
From: Luc Michel <lmichel@kalray.eu>
2
2
3
The TCG_KICK_PERIOD macro is already defined in tcg-accel-ops-rr.h.
4
Remove it from tcg-accel-ops-rr.c.
5
6
Signed-off-by: Luc Michel <lmichel@kalray.eu>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-Id: <20210811141229.12470-1-lmichel@kalray.eu>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
11
---
6
tcg/aarch64/tcg-target.h | 1 -
12
accel/tcg/tcg-accel-ops-rr.c | 2 --
7
tcg/i386/tcg-target.h | 1 -
13
1 file changed, 2 deletions(-)
8
tcg/ppc/tcg-target.h | 1 -
9
3 files changed, 3 deletions(-)
10
14
11
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
15
diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/aarch64/tcg-target.h
17
--- a/accel/tcg/tcg-accel-ops-rr.c
14
+++ b/tcg/aarch64/tcg-target.h
18
+++ b/accel/tcg/tcg-accel-ops-rr.c
15
@@ -XXX,XX +XXX,XX @@ typedef enum {
19
@@ -XXX,XX +XXX,XX @@ void rr_kick_vcpu_thread(CPUState *unused)
16
#define TCG_TARGET_HAS_shi_vec 1
20
static QEMUTimer *rr_kick_vcpu_timer;
17
#define TCG_TARGET_HAS_shs_vec 0
21
static CPUState *rr_current_cpu;
18
#define TCG_TARGET_HAS_shv_vec 1
22
19
-#define TCG_TARGET_HAS_cmp_vec 1
23
-#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
20
#define TCG_TARGET_HAS_mul_vec 1
24
-
21
#define TCG_TARGET_HAS_sat_vec 1
25
static inline int64_t rr_next_kick_time(void)
22
#define TCG_TARGET_HAS_minmax_vec 1
26
{
23
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
27
return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD;
24
index XXXXXXX..XXXXXXX 100644
25
--- a/tcg/i386/tcg-target.h
26
+++ b/tcg/i386/tcg-target.h
27
@@ -XXX,XX +XXX,XX @@ extern bool have_avx2;
28
#define TCG_TARGET_HAS_shi_vec 1
29
#define TCG_TARGET_HAS_shs_vec 1
30
#define TCG_TARGET_HAS_shv_vec have_avx2
31
-#define TCG_TARGET_HAS_cmp_vec 1
32
#define TCG_TARGET_HAS_mul_vec 1
33
#define TCG_TARGET_HAS_sat_vec 1
34
#define TCG_TARGET_HAS_minmax_vec 1
35
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/tcg/ppc/tcg-target.h
38
+++ b/tcg/ppc/tcg-target.h
39
@@ -XXX,XX +XXX,XX @@ extern bool have_vsx;
40
#define TCG_TARGET_HAS_shi_vec 0
41
#define TCG_TARGET_HAS_shs_vec 0
42
#define TCG_TARGET_HAS_shv_vec 1
43
-#define TCG_TARGET_HAS_cmp_vec 1
44
#define TCG_TARGET_HAS_mul_vec 1
45
#define TCG_TARGET_HAS_sat_vec 1
46
#define TCG_TARGET_HAS_minmax_vec 1
47
--
28
--
48
2.25.1
29
2.25.1
49
30
50
31
diff view generated by jsdifflib
1
When the two arguments are identical, this can be reduced to
1
From: Bin Meng <bmeng.cn@gmail.com>
2
dup_vec or to mov_vec from a tcg_constant_vec.
3
2
3
Since commit 1c2adb958fc0 ("tcg: Initialize cpu_env generically"),
4
these tcg_global_reg_new_ macros are not used anywhere.
5
6
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-Id: <20210816143507.11200-1-bmeng.cn@gmail.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
10
---
6
tcg/optimize.c | 15 +++++++++++++++
11
include/tcg/tcg-op.h | 2 --
7
1 file changed, 15 insertions(+)
12
target/hppa/translate.c | 3 ---
13
2 files changed, 5 deletions(-)
8
14
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
15
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
10
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
17
--- a/include/tcg/tcg-op.h
12
+++ b/tcg/optimize.c
18
+++ b/include/tcg/tcg-op.h
13
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
19
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_plugin_cb_end(void)
14
}
20
15
goto do_default;
21
#if TARGET_LONG_BITS == 32
16
22
#define tcg_temp_new() tcg_temp_new_i32()
17
+ case INDEX_op_dup2_vec:
23
-#define tcg_global_reg_new tcg_global_reg_new_i32
18
+ assert(TCG_TARGET_REG_BITS == 32);
24
#define tcg_global_mem_new tcg_global_mem_new_i32
19
+ if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) {
25
#define tcg_temp_local_new() tcg_temp_local_new_i32()
20
+ tmp = arg_info(op->args[1])->val;
26
#define tcg_temp_free tcg_temp_free_i32
21
+ if (tmp == arg_info(op->args[2])->val) {
27
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_plugin_cb_end(void)
22
+ tcg_opt_gen_movi(s, op, op->args[0], tmp);
28
#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32
23
+ break;
29
#else
24
+ }
30
#define tcg_temp_new() tcg_temp_new_i64()
25
+ } else if (args_are_copies(op->args[1], op->args[2])) {
31
-#define tcg_global_reg_new tcg_global_reg_new_i64
26
+ op->opc = INDEX_op_dup_vec;
32
#define tcg_global_mem_new tcg_global_mem_new_i64
27
+ TCGOP_VECE(op) = MO_32;
33
#define tcg_temp_local_new() tcg_temp_local_new_i64()
28
+ nb_iargs = 1;
34
#define tcg_temp_free tcg_temp_free_i64
29
+ }
35
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
30
+ goto do_default;
36
index XXXXXXX..XXXXXXX 100644
31
+
37
--- a/target/hppa/translate.c
32
CASE_OP_32_64(not):
38
+++ b/target/hppa/translate.c
33
CASE_OP_32_64(neg):
39
@@ -XXX,XX +XXX,XX @@
34
CASE_OP_32_64(ext8s):
40
41
#undef TCGv
42
#undef tcg_temp_new
43
-#undef tcg_global_reg_new
44
#undef tcg_global_mem_new
45
#undef tcg_temp_local_new
46
#undef tcg_temp_free
47
@@ -XXX,XX +XXX,XX @@
48
#define TCGv_reg TCGv_i64
49
50
#define tcg_temp_new tcg_temp_new_i64
51
-#define tcg_global_reg_new tcg_global_reg_new_i64
52
#define tcg_global_mem_new tcg_global_mem_new_i64
53
#define tcg_temp_local_new tcg_temp_local_new_i64
54
#define tcg_temp_free tcg_temp_free_i64
55
@@ -XXX,XX +XXX,XX @@
56
#else
57
#define TCGv_reg TCGv_i32
58
#define tcg_temp_new tcg_temp_new_i32
59
-#define tcg_global_reg_new tcg_global_reg_new_i32
60
#define tcg_global_mem_new tcg_global_mem_new_i32
61
#define tcg_temp_local_new tcg_temp_local_new_i32
62
#define tcg_temp_free tcg_temp_free_i32
35
--
63
--
36
2.25.1
64
2.25.1
37
65
38
66
diff view generated by jsdifflib
1
The definition of INDEX_op_dupi_vec is that it operates on
1
All supported compilers have builtins for this.
2
units of tcg_target_ulong -- in this case 32 bits. It does
2
Drop all of the complicated system detection stuff.
3
not work to use this for a uint64_t value that happens to be
4
small enough to fit in tcg_target_ulong.
5
3
6
Fixes: d2fd745fe8b
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Fixes: db432672dc5
5
Message-Id: <20210708181743.750220-1-richard.henderson@linaro.org>
8
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
7
---
11
tcg/tcg-op-vec.c | 12 ++++++++----
8
meson.build | 6 -----
12
1 file changed, 8 insertions(+), 4 deletions(-)
9
include/qemu/bswap.h | 53 +++-----------------------------------------
10
2 files changed, 3 insertions(+), 56 deletions(-)
13
11
14
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
12
diff --git a/meson.build b/meson.build
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/tcg-op-vec.c
14
--- a/meson.build
17
+++ b/tcg/tcg-op-vec.c
15
+++ b/meson.build
18
@@ -XXX,XX +XXX,XX @@ TCGv_vec tcg_const_ones_vec_matching(TCGv_vec m)
16
@@ -XXX,XX +XXX,XX @@ config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
19
17
config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
20
void tcg_gen_dup64i_vec(TCGv_vec r, uint64_t a)
18
19
# has_header_symbol
20
-config_host_data.set('CONFIG_BYTESWAP_H',
21
- cc.has_header_symbol('byteswap.h', 'bswap_32'))
22
config_host_data.set('CONFIG_EPOLL_CREATE1',
23
cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
24
config_host_data.set('CONFIG_HAS_ENVIRON',
25
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_INOTIFY',
26
cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
27
config_host_data.set('CONFIG_INOTIFY1',
28
cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
29
-config_host_data.set('CONFIG_MACHINE_BSWAP_H',
30
- cc.has_header_symbol('machine/bswap.h', 'bswap32',
31
- prefix: '''#include <sys/endian.h>
32
- #include <sys/types.h>'''))
33
config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
34
cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
35
config_host_data.set('CONFIG_RTNETLINK',
36
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/qemu/bswap.h
39
+++ b/include/qemu/bswap.h
40
@@ -XXX,XX +XXX,XX @@
41
#ifndef BSWAP_H
42
#define BSWAP_H
43
44
-#ifdef CONFIG_MACHINE_BSWAP_H
45
-# include <sys/endian.h>
46
-# include <machine/bswap.h>
47
-#elif defined(__FreeBSD__)
48
-# include <sys/endian.h>
49
-#elif defined(__HAIKU__)
50
-# include <endian.h>
51
-#elif defined(CONFIG_BYTESWAP_H)
52
-# include <byteswap.h>
53
-#define BSWAP_FROM_BYTESWAP
54
-# else
55
-#define BSWAP_FROM_FALLBACKS
56
-#endif /* ! CONFIG_MACHINE_BSWAP_H */
57
-
58
#ifdef __cplusplus
59
extern "C" {
60
#endif
61
62
#include "fpu/softfloat-types.h"
63
64
-#ifdef BSWAP_FROM_BYTESWAP
65
static inline uint16_t bswap16(uint16_t x)
21
{
66
{
22
- if (TCG_TARGET_REG_BITS == 32 && a == deposit64(a, 32, 32, a)) {
67
- return bswap_16(x);
23
- do_dupi_vec(r, MO_32, a);
68
+ return __builtin_bswap16(x);
24
- } else if (TCG_TARGET_REG_BITS == 64 || a == (uint64_t)(int32_t)a) {
69
}
25
+ if (TCG_TARGET_REG_BITS == 64) {
70
26
do_dupi_vec(r, MO_64, a);
71
static inline uint32_t bswap32(uint32_t x)
27
+ } else if (a == dup_const(MO_32, a)) {
28
+ do_dupi_vec(r, MO_32, a);
29
} else {
30
TCGv_i64 c = tcg_const_i64(a);
31
tcg_gen_dup_i64_vec(MO_64, r, c);
32
@@ -XXX,XX +XXX,XX @@ void tcg_gen_dup8i_vec(TCGv_vec r, uint32_t a)
33
34
void tcg_gen_dupi_vec(unsigned vece, TCGv_vec r, uint64_t a)
35
{
72
{
36
- do_dupi_vec(r, MO_REG, dup_const(vece, a));
73
- return bswap_32(x);
37
+ if (vece == MO_64) {
74
+ return __builtin_bswap32(x);
38
+ tcg_gen_dup64i_vec(r, a);
39
+ } else {
40
+ do_dupi_vec(r, MO_REG, dup_const(vece, a));
41
+ }
42
}
75
}
43
76
44
void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec r, TCGv_i64 a)
77
static inline uint64_t bswap64(uint64_t x)
78
{
79
- return bswap_64(x);
80
+ return __builtin_bswap64(x);
81
}
82
-#endif
83
-
84
-#ifdef BSWAP_FROM_FALLBACKS
85
-static inline uint16_t bswap16(uint16_t x)
86
-{
87
- return (((x & 0x00ff) << 8) |
88
- ((x & 0xff00) >> 8));
89
-}
90
-
91
-static inline uint32_t bswap32(uint32_t x)
92
-{
93
- return (((x & 0x000000ffU) << 24) |
94
- ((x & 0x0000ff00U) << 8) |
95
- ((x & 0x00ff0000U) >> 8) |
96
- ((x & 0xff000000U) >> 24));
97
-}
98
-
99
-static inline uint64_t bswap64(uint64_t x)
100
-{
101
- return (((x & 0x00000000000000ffULL) << 56) |
102
- ((x & 0x000000000000ff00ULL) << 40) |
103
- ((x & 0x0000000000ff0000ULL) << 24) |
104
- ((x & 0x00000000ff000000ULL) << 8) |
105
- ((x & 0x000000ff00000000ULL) >> 8) |
106
- ((x & 0x0000ff0000000000ULL) >> 24) |
107
- ((x & 0x00ff000000000000ULL) >> 40) |
108
- ((x & 0xff00000000000000ULL) >> 56));
109
-}
110
-#endif
111
-
112
-#undef BSWAP_FROM_BYTESWAP
113
-#undef BSWAP_FROM_FALLBACKS
114
115
static inline void bswap16s(uint16_t *s)
116
{
45
--
117
--
46
2.25.1
118
2.25.1
47
119
48
120
diff view generated by jsdifflib
1
This wasn't actually used for anything, really. All variable
1
If __APPLE__, ensure that _CALL_DARWIN is set, then remove
2
operands must accept registers, and which are indicated by the
2
our local TCG_TARGET_CALL_DARWIN.
3
set in TCGArgConstraint.regs.
4
3
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
5
---
7
include/tcg/tcg.h | 1 -
6
tcg/ppc/tcg-target.c.inc | 8 ++++----
8
tcg/tcg.c | 15 ++++-----------
7
1 file changed, 4 insertions(+), 4 deletions(-)
9
tcg/aarch64/tcg-target.c.inc | 3 ---
10
tcg/arm/tcg-target.c.inc | 3 ---
11
tcg/i386/tcg-target.c.inc | 11 -----------
12
tcg/mips/tcg-target.c.inc | 3 ---
13
tcg/ppc/tcg-target.c.inc | 5 -----
14
tcg/riscv/tcg-target.c.inc | 2 --
15
tcg/s390/tcg-target.c.inc | 4 ----
16
tcg/sparc/tcg-target.c.inc | 5 -----
17
tcg/tci/tcg-target.c.inc | 1 -
18
11 files changed, 4 insertions(+), 49 deletions(-)
19
8
20
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/tcg/tcg.h
23
+++ b/include/tcg/tcg.h
24
@@ -XXX,XX +XXX,XX @@ void tcg_dump_op_count(void);
25
#define TCG_CT_ALIAS 0x80
26
#define TCG_CT_IALIAS 0x40
27
#define TCG_CT_NEWREG 0x20 /* output requires a new register */
28
-#define TCG_CT_REG 0x01
29
#define TCG_CT_CONST 0x02 /* any constant of register size */
30
31
typedef struct TCGArgConstraint {
32
diff --git a/tcg/tcg.c b/tcg/tcg.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/tcg/tcg.c
35
+++ b/tcg/tcg.c
36
@@ -XXX,XX +XXX,XX @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
37
/* we give more priority to constraints with less registers */
38
static int get_constraint_priority(const TCGOpDef *def, int k)
39
{
40
- const TCGArgConstraint *arg_ct;
41
+ const TCGArgConstraint *arg_ct = &def->args_ct[k];
42
+ int n;
43
44
- int i, n;
45
- arg_ct = &def->args_ct[k];
46
if (arg_ct->ct & TCG_CT_ALIAS) {
47
/* an alias is equivalent to a single register */
48
n = 1;
49
} else {
50
- if (!(arg_ct->ct & TCG_CT_REG))
51
- return 0;
52
- n = 0;
53
- for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
54
- if (tcg_regset_test_reg(arg_ct->regs, i))
55
- n++;
56
- }
57
+ n = ctpop64(arg_ct->regs);
58
}
59
return TCG_TARGET_NB_REGS - n + 1;
60
}
61
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
62
int oarg = *ct_str - '0';
63
tcg_debug_assert(ct_str == tdefs->args_ct_str[i]);
64
tcg_debug_assert(oarg < def->nb_oargs);
65
- tcg_debug_assert(def->args_ct[oarg].ct & TCG_CT_REG);
66
+ tcg_debug_assert(def->args_ct[oarg].regs != 0);
67
/* TCG_CT_ALIAS is for the output arguments.
68
The input is tagged with TCG_CT_IALIAS. */
69
def->args_ct[i] = def->args_ct[oarg];
70
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
71
index XXXXXXX..XXXXXXX 100644
72
--- a/tcg/aarch64/tcg-target.c.inc
73
+++ b/tcg/aarch64/tcg-target.c.inc
74
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
75
{
76
switch (*ct_str++) {
77
case 'r': /* general registers */
78
- ct->ct |= TCG_CT_REG;
79
ct->regs |= 0xffffffffu;
80
break;
81
case 'w': /* advsimd registers */
82
- ct->ct |= TCG_CT_REG;
83
ct->regs |= 0xffffffff00000000ull;
84
break;
85
case 'l': /* qemu_ld / qemu_st address, data_reg */
86
- ct->ct |= TCG_CT_REG;
87
ct->regs = 0xffffffffu;
88
#ifdef CONFIG_SOFTMMU
89
/* x0 and x1 will be overwritten when reading the tlb entry,
90
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
91
index XXXXXXX..XXXXXXX 100644
92
--- a/tcg/arm/tcg-target.c.inc
93
+++ b/tcg/arm/tcg-target.c.inc
94
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
95
break;
96
97
case 'r':
98
- ct->ct |= TCG_CT_REG;
99
ct->regs = 0xffff;
100
break;
101
102
/* qemu_ld address */
103
case 'l':
104
- ct->ct |= TCG_CT_REG;
105
ct->regs = 0xffff;
106
#ifdef CONFIG_SOFTMMU
107
/* r0-r2,lr will be overwritten when reading the tlb entry,
108
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
109
110
/* qemu_st address & data */
111
case 's':
112
- ct->ct |= TCG_CT_REG;
113
ct->regs = 0xffff;
114
/* r0-r2 will be overwritten when reading the tlb entry (softmmu only)
115
and r0-r1 doing the byte swapping, so don't use these. */
116
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
117
index XXXXXXX..XXXXXXX 100644
118
--- a/tcg/i386/tcg-target.c.inc
119
+++ b/tcg/i386/tcg-target.c.inc
120
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
121
{
122
switch(*ct_str++) {
123
case 'a':
124
- ct->ct |= TCG_CT_REG;
125
tcg_regset_set_reg(ct->regs, TCG_REG_EAX);
126
break;
127
case 'b':
128
- ct->ct |= TCG_CT_REG;
129
tcg_regset_set_reg(ct->regs, TCG_REG_EBX);
130
break;
131
case 'c':
132
- ct->ct |= TCG_CT_REG;
133
tcg_regset_set_reg(ct->regs, TCG_REG_ECX);
134
break;
135
case 'd':
136
- ct->ct |= TCG_CT_REG;
137
tcg_regset_set_reg(ct->regs, TCG_REG_EDX);
138
break;
139
case 'S':
140
- ct->ct |= TCG_CT_REG;
141
tcg_regset_set_reg(ct->regs, TCG_REG_ESI);
142
break;
143
case 'D':
144
- ct->ct |= TCG_CT_REG;
145
tcg_regset_set_reg(ct->regs, TCG_REG_EDI);
146
break;
147
case 'q':
148
/* A register that can be used as a byte operand. */
149
- ct->ct |= TCG_CT_REG;
150
ct->regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xf;
151
break;
152
case 'Q':
153
/* A register with an addressable second byte (e.g. %ah). */
154
- ct->ct |= TCG_CT_REG;
155
ct->regs = 0xf;
156
break;
157
case 'r':
158
/* A general register. */
159
- ct->ct |= TCG_CT_REG;
160
ct->regs |= ALL_GENERAL_REGS;
161
break;
162
case 'W':
163
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
164
break;
165
case 'x':
166
/* A vector register. */
167
- ct->ct |= TCG_CT_REG;
168
ct->regs |= ALL_VECTOR_REGS;
169
break;
170
171
/* qemu_ld/st address constraint */
172
case 'L':
173
- ct->ct |= TCG_CT_REG;
174
ct->regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xff;
175
tcg_regset_reset_reg(ct->regs, TCG_REG_L0);
176
tcg_regset_reset_reg(ct->regs, TCG_REG_L1);
177
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
178
index XXXXXXX..XXXXXXX 100644
179
--- a/tcg/mips/tcg-target.c.inc
180
+++ b/tcg/mips/tcg-target.c.inc
181
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
182
{
183
switch(*ct_str++) {
184
case 'r':
185
- ct->ct |= TCG_CT_REG;
186
ct->regs = 0xffffffff;
187
break;
188
case 'L': /* qemu_ld input arg constraint */
189
- ct->ct |= TCG_CT_REG;
190
ct->regs = 0xffffffff;
191
tcg_regset_reset_reg(ct->regs, TCG_REG_A0);
192
#if defined(CONFIG_SOFTMMU)
193
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
194
#endif
195
break;
196
case 'S': /* qemu_st constraint */
197
- ct->ct |= TCG_CT_REG;
198
ct->regs = 0xffffffff;
199
tcg_regset_reset_reg(ct->regs, TCG_REG_A0);
200
#if defined(CONFIG_SOFTMMU)
201
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
9
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
202
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
203
--- a/tcg/ppc/tcg-target.c.inc
11
--- a/tcg/ppc/tcg-target.c.inc
204
+++ b/tcg/ppc/tcg-target.c.inc
12
+++ b/tcg/ppc/tcg-target.c.inc
205
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
13
@@ -XXX,XX +XXX,XX @@
206
{
14
#include "elf.h"
207
switch (*ct_str++) {
15
#include "../tcg-pool.c.inc"
208
case 'A': case 'B': case 'C': case 'D':
16
209
- ct->ct |= TCG_CT_REG;
17
-#if defined _CALL_DARWIN || defined __APPLE__
210
tcg_regset_set_reg(ct->regs, 3 + ct_str[0] - 'A');
18
-#define TCG_TARGET_CALL_DARWIN
211
break;
19
+#if !defined _CALL_DARWIN && defined __APPLE__
212
case 'r':
20
+#define _CALL_DARWIN 1
213
- ct->ct |= TCG_CT_REG;
214
ct->regs = 0xffffffff;
215
break;
216
case 'v':
217
- ct->ct |= TCG_CT_REG;
218
ct->regs = 0xffffffff00000000ull;
219
break;
220
case 'L': /* qemu_ld constraint */
221
- ct->ct |= TCG_CT_REG;
222
ct->regs = 0xffffffff;
223
tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
224
#ifdef CONFIG_SOFTMMU
225
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
226
#endif
21
#endif
227
break;
22
#ifdef _CALL_SYSV
228
case 'S': /* qemu_st constraint */
23
# define TCG_TARGET_CALL_ALIGN_ARGS 1
229
- ct->ct |= TCG_CT_REG;
24
@@ -XXX,XX +XXX,XX @@ static const int tcg_target_call_oarg_regs[] = {
230
ct->regs = 0xffffffff;
25
};
231
tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
26
232
#ifdef CONFIG_SOFTMMU
27
static const int tcg_target_callee_save_regs[] = {
233
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
28
-#ifdef TCG_TARGET_CALL_DARWIN
234
index XXXXXXX..XXXXXXX 100644
29
+#ifdef _CALL_DARWIN
235
--- a/tcg/riscv/tcg-target.c.inc
30
TCG_REG_R11,
236
+++ b/tcg/riscv/tcg-target.c.inc
31
#endif
237
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
32
TCG_REG_R14,
238
{
33
@@ -XXX,XX +XXX,XX @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
239
switch (*ct_str++) {
34
# define LINK_AREA_SIZE (6 * SZR)
240
case 'r':
35
# define LR_OFFSET (1 * SZR)
241
- ct->ct |= TCG_CT_REG;
36
# define TCG_TARGET_CALL_STACK_OFFSET (LINK_AREA_SIZE + 8 * SZR)
242
ct->regs = 0xffffffff;
37
-#elif defined(TCG_TARGET_CALL_DARWIN)
243
break;
38
+#elif defined(_CALL_DARWIN)
244
case 'L':
39
# define LINK_AREA_SIZE (6 * SZR)
245
/* qemu_ld/qemu_st constraint */
40
# define LR_OFFSET (2 * SZR)
246
- ct->ct |= TCG_CT_REG;
41
#elif TCG_TARGET_REG_BITS == 64
247
ct->regs = 0xffffffff;
248
/* qemu_ld/qemu_st uses TCG_REG_TMP0 */
249
#if defined(CONFIG_SOFTMMU)
250
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
251
index XXXXXXX..XXXXXXX 100644
252
--- a/tcg/s390/tcg-target.c.inc
253
+++ b/tcg/s390/tcg-target.c.inc
254
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
255
{
256
switch (*ct_str++) {
257
case 'r': /* all registers */
258
- ct->ct |= TCG_CT_REG;
259
ct->regs = 0xffff;
260
break;
261
case 'L': /* qemu_ld/st constraint */
262
- ct->ct |= TCG_CT_REG;
263
ct->regs = 0xffff;
264
tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
265
tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
266
tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
267
break;
268
case 'a': /* force R2 for division */
269
- ct->ct |= TCG_CT_REG;
270
ct->regs = 0;
271
tcg_regset_set_reg(ct->regs, TCG_REG_R2);
272
break;
273
case 'b': /* force R3 for division */
274
- ct->ct |= TCG_CT_REG;
275
ct->regs = 0;
276
tcg_regset_set_reg(ct->regs, TCG_REG_R3);
277
break;
278
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
279
index XXXXXXX..XXXXXXX 100644
280
--- a/tcg/sparc/tcg-target.c.inc
281
+++ b/tcg/sparc/tcg-target.c.inc
282
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
283
{
284
switch (*ct_str++) {
285
case 'r':
286
- ct->ct |= TCG_CT_REG;
287
ct->regs = 0xffffffff;
288
break;
289
case 'R':
290
- ct->ct |= TCG_CT_REG;
291
ct->regs = ALL_64;
292
break;
293
case 'A': /* qemu_ld/st address constraint */
294
- ct->ct |= TCG_CT_REG;
295
ct->regs = TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff;
296
reserve_helpers:
297
tcg_regset_reset_reg(ct->regs, TCG_REG_O0);
298
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
299
tcg_regset_reset_reg(ct->regs, TCG_REG_O2);
300
break;
301
case 's': /* qemu_st data 32-bit constraint */
302
- ct->ct |= TCG_CT_REG;
303
ct->regs = 0xffffffff;
304
goto reserve_helpers;
305
case 'S': /* qemu_st data 64-bit constraint */
306
- ct->ct |= TCG_CT_REG;
307
ct->regs = ALL_64;
308
goto reserve_helpers;
309
case 'I':
310
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
311
index XXXXXXX..XXXXXXX 100644
312
--- a/tcg/tci/tcg-target.c.inc
313
+++ b/tcg/tci/tcg-target.c.inc
314
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
315
case 'r':
316
case 'L': /* qemu_ld constraint */
317
case 'S': /* qemu_st constraint */
318
- ct->ct |= TCG_CT_REG;
319
ct->regs = BIT(TCG_TARGET_NB_REGS) - 1;
320
break;
321
default:
322
--
42
--
323
2.25.1
43
2.25.1
324
44
325
45
diff view generated by jsdifflib
1
The last user of this field disappeared in f69d277ece4.
1
Clang only sets _CALL_ELF for ppc64, and nothing at all to specify
2
the ABI for ppc32. Make a good guess based on other symbols.
2
3
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reported-by: Brad Smith <brad@comstyle.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
---
6
include/tcg/tcg.h | 3 ---
7
tcg/ppc/tcg-target.c.inc | 21 ++++++++++++++++++---
7
1 file changed, 3 deletions(-)
8
1 file changed, 18 insertions(+), 3 deletions(-)
8
9
9
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
10
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
10
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
11
--- a/include/tcg/tcg.h
12
--- a/tcg/ppc/tcg-target.c.inc
12
+++ b/include/tcg/tcg.h
13
+++ b/tcg/ppc/tcg-target.c.inc
13
@@ -XXX,XX +XXX,XX @@ typedef struct TCGOpDef {
14
@@ -XXX,XX +XXX,XX @@
14
uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
15
#include "elf.h"
15
uint8_t flags;
16
#include "../tcg-pool.c.inc"
16
TCGArgConstraint *args_ct;
17
17
-#if defined(CONFIG_DEBUG_TCG)
18
-#if !defined _CALL_DARWIN && defined __APPLE__
18
- int used;
19
-#define _CALL_DARWIN 1
19
-#endif
20
-#endif
20
} TCGOpDef;
21
+/*
21
22
+ * Standardize on the _CALL_FOO symbols used by GCC:
22
extern TCGOpDef tcg_op_defs[];
23
+ * Apple XCode does not define _CALL_DARWIN.
24
+ * Clang defines _CALL_ELF (64-bit) but not _CALL_SYSV (32-bit).
25
+ */
26
+#if !defined(_CALL_SYSV) && \
27
+ !defined(_CALL_DARWIN) && \
28
+ !defined(_CALL_AIX) && \
29
+ !defined(_CALL_ELF)
30
+# if defined(__APPLE__)
31
+# define _CALL_DARWIN
32
+# elif defined(__ELF__) && TCG_TARGET_REG_BITS == 32
33
+# define _CALL_SYSV
34
+# else
35
+# error "Unknown ABI"
36
+# endif
37
+#endif
38
+
39
#ifdef _CALL_SYSV
40
# define TCG_TARGET_CALL_ALIGN_ARGS 1
41
#endif
23
--
42
--
24
2.25.1
43
2.25.1
25
44
26
45
diff view generated by jsdifflib
1
The union is unused; let "regs" appear in the main structure
1
From: "Jose R. Ziviani" <jziviani@suse.de>
2
without the "u.regs" wrapping.
3
2
3
Commit 5e8892db93 fixed several function signatures but tcg_out_vec_op
4
for arm is missing. It causes a build error on armv6 and armv7:
5
6
tcg-target.c.inc:2718:42: error: argument 5 of type 'const TCGArg *'
7
{aka 'const unsigned int *'} declared as a pointer [-Werror=array-parameter=]
8
const TCGArg *args, const int *const_args)
9
~~~~~~~~~~~~~~^~~~
10
../tcg/tcg.c:120:41: note: previously declared as an array 'const TCGArg[16]'
11
{aka 'const unsigned int[16]'}
12
const TCGArg args[TCG_MAX_OP_ARGS],
13
~~~~~~~~~~~~~~^~~~
14
15
Signed-off-by: Jose R. Ziviani <jziviani@suse.de>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-Id: <20210908185338.7927-1-jziviani@suse.de>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
19
---
7
include/tcg/tcg.h | 4 +---
20
tcg/arm/tcg-target.c.inc | 3 ++-
8
tcg/tcg.c | 22 +++++++++++-----------
21
1 file changed, 2 insertions(+), 1 deletion(-)
9
tcg/aarch64/tcg-target.c.inc | 14 +++++++-------
10
tcg/arm/tcg-target.c.inc | 26 +++++++++++++-------------
11
tcg/i386/tcg-target.c.inc | 26 +++++++++++++-------------
12
tcg/mips/tcg-target.c.inc | 18 +++++++++---------
13
tcg/ppc/tcg-target.c.inc | 24 ++++++++++++------------
14
tcg/riscv/tcg-target.c.inc | 14 +++++++-------
15
tcg/s390/tcg-target.c.inc | 18 +++++++++---------
16
tcg/sparc/tcg-target.c.inc | 16 ++++++++--------
17
tcg/tci/tcg-target.c.inc | 2 +-
18
11 files changed, 91 insertions(+), 93 deletions(-)
19
22
20
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/tcg/tcg.h
23
+++ b/include/tcg/tcg.h
24
@@ -XXX,XX +XXX,XX @@ void tcg_dump_op_count(void);
25
typedef struct TCGArgConstraint {
26
uint16_t ct;
27
uint8_t alias_index;
28
- union {
29
- TCGRegSet regs;
30
- } u;
31
+ TCGRegSet regs;
32
} TCGArgConstraint;
33
34
#define TCG_MAX_OP_ARGS 16
35
diff --git a/tcg/tcg.c b/tcg/tcg.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/tcg/tcg.c
38
+++ b/tcg/tcg.c
39
@@ -XXX,XX +XXX,XX @@ static int get_constraint_priority(const TCGOpDef *def, int k)
40
return 0;
41
n = 0;
42
for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
43
- if (tcg_regset_test_reg(arg_ct->u.regs, i))
44
+ if (tcg_regset_test_reg(arg_ct->regs, i))
45
n++;
46
}
47
}
48
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
49
/* Incomplete TCGTargetOpDef entry. */
50
tcg_debug_assert(ct_str != NULL);
51
52
- def->args_ct[i].u.regs = 0;
53
+ def->args_ct[i].regs = 0;
54
def->args_ct[i].ct = 0;
55
while (*ct_str != '\0') {
56
switch(*ct_str) {
57
@@ -XXX,XX +XXX,XX @@ static void liveness_pass_1(TCGContext *s)
58
pset = la_temp_pref(ts);
59
set = *pset;
60
61
- set &= ct->u.regs;
62
+ set &= ct->regs;
63
if (ct->ct & TCG_CT_IALIAS) {
64
set &= op->output_pref[ct->alias_index];
65
}
66
/* If the combination is not possible, restart. */
67
if (set == 0) {
68
- set = ct->u.regs;
69
+ set = ct->regs;
70
}
71
*pset = set;
72
}
73
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp *op)
74
return;
75
}
76
77
- dup_out_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[0].u.regs;
78
- dup_in_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[1].u.regs;
79
+ dup_out_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs;
80
+ dup_in_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[1].regs;
81
82
/* Allocate the output register now. */
83
if (ots->val_type != TEMP_VAL_REG) {
84
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
85
}
86
}
87
88
- temp_load(s, ts, arg_ct->u.regs, i_allocated_regs, i_preferred_regs);
89
+ temp_load(s, ts, arg_ct->regs, i_allocated_regs, i_preferred_regs);
90
reg = ts->reg;
91
92
- if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
93
+ if (tcg_regset_test_reg(arg_ct->regs, reg)) {
94
/* nothing to do : the constraint is satisfied */
95
} else {
96
allocate_in_reg:
97
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
98
and move the temporary register into it */
99
temp_load(s, ts, tcg_target_available_regs[ts->type],
100
i_allocated_regs, 0);
101
- reg = tcg_reg_alloc(s, arg_ct->u.regs, i_allocated_regs,
102
+ reg = tcg_reg_alloc(s, arg_ct->regs, i_allocated_regs,
103
o_preferred_regs, ts->indirect_base);
104
if (!tcg_out_mov(s, ts->type, reg, ts->reg)) {
105
/*
106
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
107
&& !const_args[arg_ct->alias_index]) {
108
reg = new_args[arg_ct->alias_index];
109
} else if (arg_ct->ct & TCG_CT_NEWREG) {
110
- reg = tcg_reg_alloc(s, arg_ct->u.regs,
111
+ reg = tcg_reg_alloc(s, arg_ct->regs,
112
i_allocated_regs | o_allocated_regs,
113
op->output_pref[k], ts->indirect_base);
114
} else {
115
- reg = tcg_reg_alloc(s, arg_ct->u.regs, o_allocated_regs,
116
+ reg = tcg_reg_alloc(s, arg_ct->regs, o_allocated_regs,
117
op->output_pref[k], ts->indirect_base);
118
}
119
tcg_regset_set_reg(o_allocated_regs, reg);
120
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
121
index XXXXXXX..XXXXXXX 100644
122
--- a/tcg/aarch64/tcg-target.c.inc
123
+++ b/tcg/aarch64/tcg-target.c.inc
124
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
125
switch (*ct_str++) {
126
case 'r': /* general registers */
127
ct->ct |= TCG_CT_REG;
128
- ct->u.regs |= 0xffffffffu;
129
+ ct->regs |= 0xffffffffu;
130
break;
131
case 'w': /* advsimd registers */
132
ct->ct |= TCG_CT_REG;
133
- ct->u.regs |= 0xffffffff00000000ull;
134
+ ct->regs |= 0xffffffff00000000ull;
135
break;
136
case 'l': /* qemu_ld / qemu_st address, data_reg */
137
ct->ct |= TCG_CT_REG;
138
- ct->u.regs = 0xffffffffu;
139
+ ct->regs = 0xffffffffu;
140
#ifdef CONFIG_SOFTMMU
141
/* x0 and x1 will be overwritten when reading the tlb entry,
142
and x2, and x3 for helper args, better to avoid using them. */
143
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_X0);
144
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_X1);
145
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_X2);
146
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_X3);
147
+ tcg_regset_reset_reg(ct->regs, TCG_REG_X0);
148
+ tcg_regset_reset_reg(ct->regs, TCG_REG_X1);
149
+ tcg_regset_reset_reg(ct->regs, TCG_REG_X2);
150
+ tcg_regset_reset_reg(ct->regs, TCG_REG_X3);
151
#endif
152
break;
153
case 'A': /* Valid for arithmetic immediate (positive or negative). */
154
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
23
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
155
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
156
--- a/tcg/arm/tcg-target.c.inc
25
--- a/tcg/arm/tcg-target.c.inc
157
+++ b/tcg/arm/tcg-target.c.inc
26
+++ b/tcg/arm/tcg-target.c.inc
158
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
27
@@ -XXX,XX +XXX,XX @@ static const ARMInsn vec_cmp0_insn[16] = {
159
28
160
case 'r':
29
static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
161
ct->ct |= TCG_CT_REG;
30
unsigned vecl, unsigned vece,
162
- ct->u.regs = 0xffff;
31
- const TCGArg *args, const int *const_args)
163
+ ct->regs = 0xffff;
32
+ const TCGArg args[TCG_MAX_OP_ARGS],
164
break;
33
+ const int const_args[TCG_MAX_OP_ARGS])
165
34
{
166
/* qemu_ld address */
35
TCGType type = vecl + TCG_TYPE_V64;
167
case 'l':
36
unsigned q = vecl;
168
ct->ct |= TCG_CT_REG;
169
- ct->u.regs = 0xffff;
170
+ ct->regs = 0xffff;
171
#ifdef CONFIG_SOFTMMU
172
/* r0-r2,lr will be overwritten when reading the tlb entry,
173
so don't use these. */
174
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
175
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
176
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
177
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
178
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R14);
179
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R0);
180
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R1);
181
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
182
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
183
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R14);
184
#endif
185
break;
186
187
/* qemu_st address & data */
188
case 's':
189
ct->ct |= TCG_CT_REG;
190
- ct->u.regs = 0xffff;
191
+ ct->regs = 0xffff;
192
/* r0-r2 will be overwritten when reading the tlb entry (softmmu only)
193
and r0-r1 doing the byte swapping, so don't use these. */
194
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
195
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
196
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R0);
197
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R1);
198
#if defined(CONFIG_SOFTMMU)
199
/* Avoid clashes with registers being used for helper args */
200
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
201
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
202
#if TARGET_LONG_BITS == 64
203
/* Avoid clashes with registers being used for helper args */
204
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
205
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
206
#endif
207
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R14);
208
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R14);
209
#endif
210
break;
211
212
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
213
index XXXXXXX..XXXXXXX 100644
214
--- a/tcg/i386/tcg-target.c.inc
215
+++ b/tcg/i386/tcg-target.c.inc
216
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
217
switch(*ct_str++) {
218
case 'a':
219
ct->ct |= TCG_CT_REG;
220
- tcg_regset_set_reg(ct->u.regs, TCG_REG_EAX);
221
+ tcg_regset_set_reg(ct->regs, TCG_REG_EAX);
222
break;
223
case 'b':
224
ct->ct |= TCG_CT_REG;
225
- tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
226
+ tcg_regset_set_reg(ct->regs, TCG_REG_EBX);
227
break;
228
case 'c':
229
ct->ct |= TCG_CT_REG;
230
- tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
231
+ tcg_regset_set_reg(ct->regs, TCG_REG_ECX);
232
break;
233
case 'd':
234
ct->ct |= TCG_CT_REG;
235
- tcg_regset_set_reg(ct->u.regs, TCG_REG_EDX);
236
+ tcg_regset_set_reg(ct->regs, TCG_REG_EDX);
237
break;
238
case 'S':
239
ct->ct |= TCG_CT_REG;
240
- tcg_regset_set_reg(ct->u.regs, TCG_REG_ESI);
241
+ tcg_regset_set_reg(ct->regs, TCG_REG_ESI);
242
break;
243
case 'D':
244
ct->ct |= TCG_CT_REG;
245
- tcg_regset_set_reg(ct->u.regs, TCG_REG_EDI);
246
+ tcg_regset_set_reg(ct->regs, TCG_REG_EDI);
247
break;
248
case 'q':
249
/* A register that can be used as a byte operand. */
250
ct->ct |= TCG_CT_REG;
251
- ct->u.regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xf;
252
+ ct->regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xf;
253
break;
254
case 'Q':
255
/* A register with an addressable second byte (e.g. %ah). */
256
ct->ct |= TCG_CT_REG;
257
- ct->u.regs = 0xf;
258
+ ct->regs = 0xf;
259
break;
260
case 'r':
261
/* A general register. */
262
ct->ct |= TCG_CT_REG;
263
- ct->u.regs |= ALL_GENERAL_REGS;
264
+ ct->regs |= ALL_GENERAL_REGS;
265
break;
266
case 'W':
267
/* With TZCNT/LZCNT, we can have operand-size as an input. */
268
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
269
case 'x':
270
/* A vector register. */
271
ct->ct |= TCG_CT_REG;
272
- ct->u.regs |= ALL_VECTOR_REGS;
273
+ ct->regs |= ALL_VECTOR_REGS;
274
break;
275
276
/* qemu_ld/st address constraint */
277
case 'L':
278
ct->ct |= TCG_CT_REG;
279
- ct->u.regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xff;
280
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_L0);
281
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_L1);
282
+ ct->regs = TCG_TARGET_REG_BITS == 64 ? 0xffff : 0xff;
283
+ tcg_regset_reset_reg(ct->regs, TCG_REG_L0);
284
+ tcg_regset_reset_reg(ct->regs, TCG_REG_L1);
285
break;
286
287
case 'e':
288
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
289
index XXXXXXX..XXXXXXX 100644
290
--- a/tcg/mips/tcg-target.c.inc
291
+++ b/tcg/mips/tcg-target.c.inc
292
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
293
switch(*ct_str++) {
294
case 'r':
295
ct->ct |= TCG_CT_REG;
296
- ct->u.regs = 0xffffffff;
297
+ ct->regs = 0xffffffff;
298
break;
299
case 'L': /* qemu_ld input arg constraint */
300
ct->ct |= TCG_CT_REG;
301
- ct->u.regs = 0xffffffff;
302
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
303
+ ct->regs = 0xffffffff;
304
+ tcg_regset_reset_reg(ct->regs, TCG_REG_A0);
305
#if defined(CONFIG_SOFTMMU)
306
if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
307
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
308
+ tcg_regset_reset_reg(ct->regs, TCG_REG_A2);
309
}
310
#endif
311
break;
312
case 'S': /* qemu_st constraint */
313
ct->ct |= TCG_CT_REG;
314
- ct->u.regs = 0xffffffff;
315
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
316
+ ct->regs = 0xffffffff;
317
+ tcg_regset_reset_reg(ct->regs, TCG_REG_A0);
318
#if defined(CONFIG_SOFTMMU)
319
if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
320
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
321
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
322
+ tcg_regset_reset_reg(ct->regs, TCG_REG_A2);
323
+ tcg_regset_reset_reg(ct->regs, TCG_REG_A3);
324
} else {
325
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
326
+ tcg_regset_reset_reg(ct->regs, TCG_REG_A1);
327
}
328
#endif
329
break;
330
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
331
index XXXXXXX..XXXXXXX 100644
332
--- a/tcg/ppc/tcg-target.c.inc
333
+++ b/tcg/ppc/tcg-target.c.inc
334
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
335
switch (*ct_str++) {
336
case 'A': case 'B': case 'C': case 'D':
337
ct->ct |= TCG_CT_REG;
338
- tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
339
+ tcg_regset_set_reg(ct->regs, 3 + ct_str[0] - 'A');
340
break;
341
case 'r':
342
ct->ct |= TCG_CT_REG;
343
- ct->u.regs = 0xffffffff;
344
+ ct->regs = 0xffffffff;
345
break;
346
case 'v':
347
ct->ct |= TCG_CT_REG;
348
- ct->u.regs = 0xffffffff00000000ull;
349
+ ct->regs = 0xffffffff00000000ull;
350
break;
351
case 'L': /* qemu_ld constraint */
352
ct->ct |= TCG_CT_REG;
353
- ct->u.regs = 0xffffffff;
354
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
355
+ ct->regs = 0xffffffff;
356
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
357
#ifdef CONFIG_SOFTMMU
358
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
359
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
360
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
361
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R5);
362
#endif
363
break;
364
case 'S': /* qemu_st constraint */
365
ct->ct |= TCG_CT_REG;
366
- ct->u.regs = 0xffffffff;
367
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
368
+ ct->regs = 0xffffffff;
369
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
370
#ifdef CONFIG_SOFTMMU
371
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
372
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
373
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
374
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
375
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R5);
376
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R6);
377
#endif
378
break;
379
case 'I':
380
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
381
index XXXXXXX..XXXXXXX 100644
382
--- a/tcg/riscv/tcg-target.c.inc
383
+++ b/tcg/riscv/tcg-target.c.inc
384
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
385
switch (*ct_str++) {
386
case 'r':
387
ct->ct |= TCG_CT_REG;
388
- ct->u.regs = 0xffffffff;
389
+ ct->regs = 0xffffffff;
390
break;
391
case 'L':
392
/* qemu_ld/qemu_st constraint */
393
ct->ct |= TCG_CT_REG;
394
- ct->u.regs = 0xffffffff;
395
+ ct->regs = 0xffffffff;
396
/* qemu_ld/qemu_st uses TCG_REG_TMP0 */
397
#if defined(CONFIG_SOFTMMU)
398
- tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[0]);
399
- tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[1]);
400
- tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[2]);
401
- tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[3]);
402
- tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[4]);
403
+ tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[0]);
404
+ tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[1]);
405
+ tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[2]);
406
+ tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[3]);
407
+ tcg_regset_reset_reg(ct->regs, tcg_target_call_iarg_regs[4]);
408
#endif
409
break;
410
case 'I':
411
diff --git a/tcg/s390/tcg-target.c.inc b/tcg/s390/tcg-target.c.inc
412
index XXXXXXX..XXXXXXX 100644
413
--- a/tcg/s390/tcg-target.c.inc
414
+++ b/tcg/s390/tcg-target.c.inc
415
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
416
switch (*ct_str++) {
417
case 'r': /* all registers */
418
ct->ct |= TCG_CT_REG;
419
- ct->u.regs = 0xffff;
420
+ ct->regs = 0xffff;
421
break;
422
case 'L': /* qemu_ld/st constraint */
423
ct->ct |= TCG_CT_REG;
424
- ct->u.regs = 0xffff;
425
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
426
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
427
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
428
+ ct->regs = 0xffff;
429
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R2);
430
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
431
+ tcg_regset_reset_reg(ct->regs, TCG_REG_R4);
432
break;
433
case 'a': /* force R2 for division */
434
ct->ct |= TCG_CT_REG;
435
- ct->u.regs = 0;
436
- tcg_regset_set_reg(ct->u.regs, TCG_REG_R2);
437
+ ct->regs = 0;
438
+ tcg_regset_set_reg(ct->regs, TCG_REG_R2);
439
break;
440
case 'b': /* force R3 for division */
441
ct->ct |= TCG_CT_REG;
442
- ct->u.regs = 0;
443
- tcg_regset_set_reg(ct->u.regs, TCG_REG_R3);
444
+ ct->regs = 0;
445
+ tcg_regset_set_reg(ct->regs, TCG_REG_R3);
446
break;
447
case 'A':
448
ct->ct |= TCG_CT_CONST_S33;
449
diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc
450
index XXXXXXX..XXXXXXX 100644
451
--- a/tcg/sparc/tcg-target.c.inc
452
+++ b/tcg/sparc/tcg-target.c.inc
453
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
454
switch (*ct_str++) {
455
case 'r':
456
ct->ct |= TCG_CT_REG;
457
- ct->u.regs = 0xffffffff;
458
+ ct->regs = 0xffffffff;
459
break;
460
case 'R':
461
ct->ct |= TCG_CT_REG;
462
- ct->u.regs = ALL_64;
463
+ ct->regs = ALL_64;
464
break;
465
case 'A': /* qemu_ld/st address constraint */
466
ct->ct |= TCG_CT_REG;
467
- ct->u.regs = TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff;
468
+ ct->regs = TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff;
469
reserve_helpers:
470
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
471
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
472
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
473
+ tcg_regset_reset_reg(ct->regs, TCG_REG_O0);
474
+ tcg_regset_reset_reg(ct->regs, TCG_REG_O1);
475
+ tcg_regset_reset_reg(ct->regs, TCG_REG_O2);
476
break;
477
case 's': /* qemu_st data 32-bit constraint */
478
ct->ct |= TCG_CT_REG;
479
- ct->u.regs = 0xffffffff;
480
+ ct->regs = 0xffffffff;
481
goto reserve_helpers;
482
case 'S': /* qemu_st data 64-bit constraint */
483
ct->ct |= TCG_CT_REG;
484
- ct->u.regs = ALL_64;
485
+ ct->regs = ALL_64;
486
goto reserve_helpers;
487
case 'I':
488
ct->ct |= TCG_CT_CONST_S11;
489
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
490
index XXXXXXX..XXXXXXX 100644
491
--- a/tcg/tci/tcg-target.c.inc
492
+++ b/tcg/tci/tcg-target.c.inc
493
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
494
case 'L': /* qemu_ld constraint */
495
case 'S': /* qemu_st constraint */
496
ct->ct |= TCG_CT_REG;
497
- ct->u.regs = BIT(TCG_TARGET_NB_REGS) - 1;
498
+ ct->regs = BIT(TCG_TARGET_NB_REGS) - 1;
499
break;
500
default:
501
return NULL;
502
--
37
--
503
2.25.1
38
2.25.1
504
39
505
40
diff view generated by jsdifflib
Deleted patch
1
This uses an existing hole in the TCGArgConstraint structure
2
and will be convenient for keeping the data in one place.
3
1
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
include/tcg/tcg.h | 2 +-
7
tcg/tcg.c | 35 +++++++++++++++++------------------
8
2 files changed, 18 insertions(+), 19 deletions(-)
9
10
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/include/tcg/tcg.h
13
+++ b/include/tcg/tcg.h
14
@@ -XXX,XX +XXX,XX @@ void tcg_dump_op_count(void);
15
typedef struct TCGArgConstraint {
16
uint16_t ct;
17
uint8_t alias_index;
18
+ uint8_t sort_index;
19
TCGRegSet regs;
20
} TCGArgConstraint;
21
22
@@ -XXX,XX +XXX,XX @@ typedef struct TCGOpDef {
23
uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
24
uint8_t flags;
25
TCGArgConstraint *args_ct;
26
- int *sorted_args;
27
#if defined(CONFIG_DEBUG_TCG)
28
int used;
29
#endif
30
diff --git a/tcg/tcg.c b/tcg/tcg.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/tcg/tcg.c
33
+++ b/tcg/tcg.c
34
@@ -XXX,XX +XXX,XX @@ void tcg_context_init(TCGContext *s)
35
int op, total_args, n, i;
36
TCGOpDef *def;
37
TCGArgConstraint *args_ct;
38
- int *sorted_args;
39
TCGTemp *ts;
40
41
memset(s, 0, sizeof(*s));
42
@@ -XXX,XX +XXX,XX @@ void tcg_context_init(TCGContext *s)
43
}
44
45
args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
46
- sorted_args = g_malloc(sizeof(int) * total_args);
47
48
for(op = 0; op < NB_OPS; op++) {
49
def = &tcg_op_defs[op];
50
def->args_ct = args_ct;
51
- def->sorted_args = sorted_args;
52
n = def->nb_iargs + def->nb_oargs;
53
- sorted_args += n;
54
args_ct += n;
55
}
56
57
@@ -XXX,XX +XXX,XX @@ static int get_constraint_priority(const TCGOpDef *def, int k)
58
/* sort from highest priority to lowest */
59
static void sort_constraints(TCGOpDef *def, int start, int n)
60
{
61
- int i, j, p1, p2, tmp;
62
+ int i, j;
63
+ TCGArgConstraint *a = def->args_ct;
64
65
- for(i = 0; i < n; i++)
66
- def->sorted_args[start + i] = start + i;
67
- if (n <= 1)
68
+ for (i = 0; i < n; i++) {
69
+ a[start + i].sort_index = start + i;
70
+ }
71
+ if (n <= 1) {
72
return;
73
- for(i = 0; i < n - 1; i++) {
74
- for(j = i + 1; j < n; j++) {
75
- p1 = get_constraint_priority(def, def->sorted_args[start + i]);
76
- p2 = get_constraint_priority(def, def->sorted_args[start + j]);
77
+ }
78
+ for (i = 0; i < n - 1; i++) {
79
+ for (j = i + 1; j < n; j++) {
80
+ int p1 = get_constraint_priority(def, a[start + i].sort_index);
81
+ int p2 = get_constraint_priority(def, a[start + j].sort_index);
82
if (p1 < p2) {
83
- tmp = def->sorted_args[start + i];
84
- def->sorted_args[start + i] = def->sorted_args[start + j];
85
- def->sorted_args[start + j] = tmp;
86
+ int tmp = a[start + i].sort_index;
87
+ a[start + i].sort_index = a[start + j].sort_index;
88
+ a[start + j].sort_index = tmp;
89
}
90
}
91
}
92
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
93
for (k = 0; k < nb_iargs; k++) {
94
TCGRegSet i_preferred_regs, o_preferred_regs;
95
96
- i = def->sorted_args[nb_oargs + k];
97
+ i = def->args_ct[nb_oargs + k].sort_index;
98
arg = op->args[i];
99
arg_ct = &def->args_ct[i];
100
ts = arg_temp(arg);
101
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
102
int k2, i2;
103
reg = ts->reg;
104
for (k2 = 0 ; k2 < k ; k2++) {
105
- i2 = def->sorted_args[nb_oargs + k2];
106
+ i2 = def->args_ct[nb_oargs + k2].sort_index;
107
if ((def->args_ct[i2].ct & TCG_CT_IALIAS) &&
108
reg == new_args[i2]) {
109
goto allocate_in_reg;
110
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
111
112
/* satisfy the output constraints */
113
for(k = 0; k < nb_oargs; k++) {
114
- i = def->sorted_args[k];
115
+ i = def->args_ct[k].sort_index;
116
arg = op->args[i];
117
arg_ct = &def->args_ct[i];
118
ts = arg_temp(arg);
119
--
120
2.25.1
121
122
diff view generated by jsdifflib