1
The following changes since commit 26d6a7c87b05017ffabffb5e16837a0fccf67e90:
1
The following changes since commit 6eeea6725a70e6fcb5abba0764496bdab07ddfb3:
2
2
3
Merge remote-tracking branch 'remotes/ericb/tags/pull-qapi-2018-04-10' into staging (2018-04-10 22:16:19 +0100)
3
Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2020-10-06' into staging (2020-10-06 21:13:34 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://github.com/rth7680/qemu.git tags/pull-tcg-20180411
7
https://github.com/rth7680/qemu.git tags/pull-tcg-20201008
8
8
9
for you to fetch changes up to afd46fcad2dceffda35c0586f5723c127b6e09d8:
9
for you to fetch changes up to 62475e9d007d83db4d0a6ccebcda8914f392e9c9:
10
10
11
icount: fix cpu_restore_state_from_tb for non-tb-exit cases (2018-04-11 09:05:22 +1000)
11
accel/tcg: Fix computing of is_write for MIPS (2020-10-08 05:57:32 -0500)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Handle read-modify-write i/o with icount
14
Extend maximum gvec vector size
15
Fix i386 avx2 dupi
16
Fix mips host user-only write detection
17
Misc cleanups.
15
18
16
----------------------------------------------------------------
19
----------------------------------------------------------------
17
Pavel Dovgalyuk (1):
20
Kele Huang (1):
18
icount: fix cpu_restore_state_from_tb for non-tb-exit cases
21
accel/tcg: Fix computing of is_write for MIPS
19
22
20
include/exec/exec-all.h | 5 ++++-
23
Richard Henderson (10):
21
accel/tcg/cpu-exec-common.c | 10 +++++-----
24
tcg: Adjust simd_desc size encoding
22
accel/tcg/cpu-exec.c | 1 -
25
tcg: Drop union from TCGArgConstraint
23
accel/tcg/translate-all.c | 27 ++++++++++++++-------------
26
tcg: Move sorted_args into TCGArgConstraint.sort_index
24
accel/tcg/user-exec.c | 2 +-
27
tcg: Remove TCG_CT_REG
25
hw/misc/mips_itu.c | 3 +--
28
tcg: Move some TCG_CT_* bits to TCGArgConstraint bitfields
26
target/alpha/helper.c | 2 +-
29
tcg: Remove TCGOpDef.used
27
target/alpha/mem_helper.c | 6 ++----
30
tcg/i386: Fix dupi for avx2 32-bit hosts
28
target/arm/op_helper.c | 6 +++---
31
tcg: Fix generation of dupi_vec for 32-bit host
29
target/cris/op_helper.c | 4 ++--
32
tcg/optimize: Fold dup2_vec
30
target/i386/helper.c | 2 +-
33
tcg: Remove TCG_TARGET_HAS_cmp_vec
31
target/i386/svm_helper.c | 2 +-
32
target/m68k/op_helper.c | 4 ++--
33
target/moxie/helper.c | 2 +-
34
target/openrisc/sys_helper.c | 8 ++++----
35
target/tricore/op_helper.c | 2 +-
36
target/xtensa/op_helper.c | 4 ++--
37
17 files changed, 45 insertions(+), 45 deletions(-)
38
34
35
include/tcg/tcg-gvec-desc.h | 38 ++++++++++++------
36
include/tcg/tcg.h | 22 ++++------
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
diff view generated by jsdifflib
New 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.
1
4
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
New patch
1
The union is unused; let "regs" appear in the main structure
2
without the "u.regs" wrapping.
1
3
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
include/tcg/tcg.h | 4 +---
8
tcg/tcg.c | 22 +++++++++++-----------
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
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
155
index XXXXXXX..XXXXXXX 100644
156
--- a/tcg/arm/tcg-target.c.inc
157
+++ b/tcg/arm/tcg-target.c.inc
158
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
159
160
case 'r':
161
ct->ct |= TCG_CT_REG;
162
- ct->u.regs = 0xffff;
163
+ ct->regs = 0xffff;
164
break;
165
166
/* qemu_ld address */
167
case 'l':
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
--
503
2.25.1
504
505
diff view generated by jsdifflib
New patch
1
This uses an existing hole in the TCGArgConstraint structure
2
and will be convenient for keeping the data in one place.
1
3
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
New patch
1
This wasn't actually used for anything, really. All variable
2
operands must accept registers, and which are indicated by the
3
set in TCGArgConstraint.regs.
1
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
include/tcg/tcg.h | 1 -
8
tcg/tcg.c | 15 ++++-----------
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
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
202
index XXXXXXX..XXXXXXX 100644
203
--- a/tcg/ppc/tcg-target.c.inc
204
+++ b/tcg/ppc/tcg-target.c.inc
205
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
206
{
207
switch (*ct_str++) {
208
case 'A': case 'B': case 'C': case 'D':
209
- ct->ct |= TCG_CT_REG;
210
tcg_regset_set_reg(ct->regs, 3 + ct_str[0] - 'A');
211
break;
212
case 'r':
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
227
break;
228
case 'S': /* qemu_st constraint */
229
- ct->ct |= TCG_CT_REG;
230
ct->regs = 0xffffffff;
231
tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
232
#ifdef CONFIG_SOFTMMU
233
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
234
index XXXXXXX..XXXXXXX 100644
235
--- a/tcg/riscv/tcg-target.c.inc
236
+++ b/tcg/riscv/tcg-target.c.inc
237
@@ -XXX,XX +XXX,XX @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
238
{
239
switch (*ct_str++) {
240
case 'r':
241
- ct->ct |= TCG_CT_REG;
242
ct->regs = 0xffffffff;
243
break;
244
case 'L':
245
/* qemu_ld/qemu_st constraint */
246
- ct->ct |= TCG_CT_REG;
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
--
323
2.25.1
324
325
diff view generated by jsdifflib
New patch
1
These are easier to set and test when they have their own fields.
2
Reduce the size of alias_index and sort_index to 4 bits, which is
3
sufficient for TCG_MAX_OP_ARGS. This leaves only the bits indicating
4
constants within the ct field.
1
5
6
Move all initialization to allocation time, rather than init
7
individual fields in process_op_defs.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
include/tcg/tcg.h | 14 +++++++-------
12
tcg/tcg.c | 28 ++++++++++++----------------
13
2 files changed, 19 insertions(+), 23 deletions(-)
14
15
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/tcg/tcg.h
18
+++ b/include/tcg/tcg.h
19
@@ -XXX,XX +XXX,XX @@ int64_t tcg_cpu_exec_time(void);
20
void tcg_dump_info(void);
21
void tcg_dump_op_count(void);
22
23
-#define TCG_CT_ALIAS 0x80
24
-#define TCG_CT_IALIAS 0x40
25
-#define TCG_CT_NEWREG 0x20 /* output requires a new register */
26
-#define TCG_CT_CONST 0x02 /* any constant of register size */
27
+#define TCG_CT_CONST 1 /* any constant of register size */
28
29
typedef struct TCGArgConstraint {
30
- uint16_t ct;
31
- uint8_t alias_index;
32
- uint8_t sort_index;
33
+ unsigned ct : 16;
34
+ unsigned alias_index : 4;
35
+ unsigned sort_index : 4;
36
+ bool oalias : 1;
37
+ bool ialias : 1;
38
+ bool newreg : 1;
39
TCGRegSet regs;
40
} TCGArgConstraint;
41
42
diff --git a/tcg/tcg.c b/tcg/tcg.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/tcg/tcg.c
45
+++ b/tcg/tcg.c
46
@@ -XXX,XX +XXX,XX @@ void tcg_context_init(TCGContext *s)
47
total_args += n;
48
}
49
50
- args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
51
+ args_ct = g_new0(TCGArgConstraint, total_args);
52
53
for(op = 0; op < NB_OPS; op++) {
54
def = &tcg_op_defs[op];
55
@@ -XXX,XX +XXX,XX @@ static int get_constraint_priority(const TCGOpDef *def, int k)
56
const TCGArgConstraint *arg_ct = &def->args_ct[k];
57
int n;
58
59
- if (arg_ct->ct & TCG_CT_ALIAS) {
60
+ if (arg_ct->oalias) {
61
/* an alias is equivalent to a single register */
62
n = 1;
63
} else {
64
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
65
/* Incomplete TCGTargetOpDef entry. */
66
tcg_debug_assert(ct_str != NULL);
67
68
- def->args_ct[i].regs = 0;
69
- def->args_ct[i].ct = 0;
70
while (*ct_str != '\0') {
71
switch(*ct_str) {
72
case '0' ... '9':
73
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
74
tcg_debug_assert(ct_str == tdefs->args_ct_str[i]);
75
tcg_debug_assert(oarg < def->nb_oargs);
76
tcg_debug_assert(def->args_ct[oarg].regs != 0);
77
- /* TCG_CT_ALIAS is for the output arguments.
78
- The input is tagged with TCG_CT_IALIAS. */
79
def->args_ct[i] = def->args_ct[oarg];
80
- def->args_ct[oarg].ct |= TCG_CT_ALIAS;
81
+ /* The output sets oalias. */
82
+ def->args_ct[oarg].oalias = true;
83
def->args_ct[oarg].alias_index = i;
84
- def->args_ct[i].ct |= TCG_CT_IALIAS;
85
+ /* The input sets ialias. */
86
+ def->args_ct[i].ialias = true;
87
def->args_ct[i].alias_index = oarg;
88
}
89
ct_str++;
90
break;
91
case '&':
92
- def->args_ct[i].ct |= TCG_CT_NEWREG;
93
+ def->args_ct[i].newreg = true;
94
ct_str++;
95
break;
96
case 'i':
97
@@ -XXX,XX +XXX,XX @@ static void liveness_pass_1(TCGContext *s)
98
set = *pset;
99
100
set &= ct->regs;
101
- if (ct->ct & TCG_CT_IALIAS) {
102
+ if (ct->ialias) {
103
set &= op->output_pref[ct->alias_index];
104
}
105
/* If the combination is not possible, restart. */
106
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
107
}
108
109
i_preferred_regs = o_preferred_regs = 0;
110
- if (arg_ct->ct & TCG_CT_IALIAS) {
111
+ if (arg_ct->ialias) {
112
o_preferred_regs = op->output_pref[arg_ct->alias_index];
113
if (ts->fixed_reg) {
114
/* if fixed register, we must allocate a new register
115
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
116
reg = ts->reg;
117
for (k2 = 0 ; k2 < k ; k2++) {
118
i2 = def->args_ct[nb_oargs + k2].sort_index;
119
- if ((def->args_ct[i2].ct & TCG_CT_IALIAS) &&
120
- reg == new_args[i2]) {
121
+ if (def->args_ct[i2].ialias && reg == new_args[i2]) {
122
goto allocate_in_reg;
123
}
124
}
125
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
126
/* ENV should not be modified. */
127
tcg_debug_assert(!ts->fixed_reg);
128
129
- if ((arg_ct->ct & TCG_CT_ALIAS)
130
- && !const_args[arg_ct->alias_index]) {
131
+ if (arg_ct->oalias && !const_args[arg_ct->alias_index]) {
132
reg = new_args[arg_ct->alias_index];
133
- } else if (arg_ct->ct & TCG_CT_NEWREG) {
134
+ } else if (arg_ct->newreg) {
135
reg = tcg_reg_alloc(s, arg_ct->regs,
136
i_allocated_regs | o_allocated_regs,
137
op->output_pref[k], ts->indirect_base);
138
--
139
2.25.1
140
141
diff view generated by jsdifflib
New patch
1
The last user of this field disappeared in f69d277ece4.
1
2
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
include/tcg/tcg.h | 3 ---
7
1 file changed, 3 deletions(-)
8
9
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
10
index XXXXXXX..XXXXXXX 100644
11
--- a/include/tcg/tcg.h
12
+++ b/include/tcg/tcg.h
13
@@ -XXX,XX +XXX,XX @@ typedef struct TCGOpDef {
14
uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
15
uint8_t flags;
16
TCGArgConstraint *args_ct;
17
-#if defined(CONFIG_DEBUG_TCG)
18
- int used;
19
-#endif
20
} TCGOpDef;
21
22
extern TCGOpDef tcg_op_defs[];
23
--
24
2.25.1
25
26
diff view generated by jsdifflib
New patch
1
The previous change wrongly stated that 32-bit avx2 should have
2
used VPBROADCASTW. But that's a 16-bit broadcast and we want a
3
32-bit broadcast.
1
4
5
Fixes: 7b60ef3264e
6
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
tcg/i386/tcg-target.c.inc | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tcg/i386/tcg-target.c.inc
15
+++ b/tcg/i386/tcg-target.c.inc
16
@@ -XXX,XX +XXX,XX @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
17
new_pool_label(s, arg, R_386_PC32, s->code_ptr - 4, -4);
18
} else {
19
if (have_avx2) {
20
- tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTW + vex_l, ret);
21
+ tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTD + vex_l, ret);
22
} else {
23
tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSS, ret);
24
}
25
--
26
2.25.1
27
28
diff view generated by jsdifflib
New patch
1
The definition of INDEX_op_dupi_vec is that it operates on
2
units of tcg_target_ulong -- in this case 32 bits. It does
3
not work to use this for a uint64_t value that happens to be
4
small enough to fit in tcg_target_ulong.
1
5
6
Fixes: d2fd745fe8b
7
Fixes: db432672dc5
8
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
tcg/tcg-op-vec.c | 12 ++++++++----
12
1 file changed, 8 insertions(+), 4 deletions(-)
13
14
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/tcg-op-vec.c
17
+++ b/tcg/tcg-op-vec.c
18
@@ -XXX,XX +XXX,XX @@ TCGv_vec tcg_const_ones_vec_matching(TCGv_vec m)
19
20
void tcg_gen_dup64i_vec(TCGv_vec r, uint64_t a)
21
{
22
- if (TCG_TARGET_REG_BITS == 32 && a == deposit64(a, 32, 32, a)) {
23
- do_dupi_vec(r, MO_32, a);
24
- } else if (TCG_TARGET_REG_BITS == 64 || a == (uint64_t)(int32_t)a) {
25
+ if (TCG_TARGET_REG_BITS == 64) {
26
do_dupi_vec(r, MO_64, a);
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
{
36
- do_dupi_vec(r, MO_REG, dup_const(vece, a));
37
+ if (vece == MO_64) {
38
+ tcg_gen_dup64i_vec(r, a);
39
+ } else {
40
+ do_dupi_vec(r, MO_REG, dup_const(vece, a));
41
+ }
42
}
43
44
void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec r, TCGv_i64 a)
45
--
46
2.25.1
47
48
diff view generated by jsdifflib
New patch
1
When the two arguments are identical, this can be reduced to
2
dup_vec or to mov_vec from a tcg_constant_vec.
1
3
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/optimize.c | 15 +++++++++++++++
7
1 file changed, 15 insertions(+)
8
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
+++ b/tcg/optimize.c
13
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
14
}
15
goto do_default;
16
17
+ case INDEX_op_dup2_vec:
18
+ assert(TCG_TARGET_REG_BITS == 32);
19
+ if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) {
20
+ tmp = arg_info(op->args[1])->val;
21
+ if (tmp == arg_info(op->args[2])->val) {
22
+ tcg_opt_gen_movi(s, op, op->args[0], tmp);
23
+ break;
24
+ }
25
+ } else if (args_are_copies(op->args[1], op->args[2])) {
26
+ op->opc = INDEX_op_dup_vec;
27
+ TCGOP_VECE(op) = MO_32;
28
+ nb_iargs = 1;
29
+ }
30
+ goto do_default;
31
+
32
CASE_OP_32_64(not):
33
CASE_OP_32_64(neg):
34
CASE_OP_32_64(ext8s):
35
--
36
2.25.1
37
38
diff view generated by jsdifflib
New patch
1
The cmp_vec opcode is mandatory; this symbol is unused.
1
2
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
tcg/aarch64/tcg-target.h | 1 -
7
tcg/i386/tcg-target.h | 1 -
8
tcg/ppc/tcg-target.h | 1 -
9
3 files changed, 3 deletions(-)
10
11
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/aarch64/tcg-target.h
14
+++ b/tcg/aarch64/tcg-target.h
15
@@ -XXX,XX +XXX,XX @@ typedef enum {
16
#define TCG_TARGET_HAS_shi_vec 1
17
#define TCG_TARGET_HAS_shs_vec 0
18
#define TCG_TARGET_HAS_shv_vec 1
19
-#define TCG_TARGET_HAS_cmp_vec 1
20
#define TCG_TARGET_HAS_mul_vec 1
21
#define TCG_TARGET_HAS_sat_vec 1
22
#define TCG_TARGET_HAS_minmax_vec 1
23
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
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
--
48
2.25.1
49
50
diff view generated by jsdifflib
1
From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
1
From: Kele Huang <kele.hwang@gmail.com>
2
2
3
In icount mode, instructions that access io memory spaces in the middle
3
Detect all MIPS store instructions in cpu_signal_handler for all available
4
of the translation block invoke TB recompilation. After recompilation,
4
MIPS versions, and set is_write if encountering such store instructions.
5
such instructions become last in the TB and are allowed to access io
6
memory spaces.
7
5
8
When the code includes instruction like i386 'xchg eax, 0xffffd080'
6
This fixed the error while dealing with self-modified code for MIPS.
9
which accesses APIC, QEMU goes into an infinite loop of the recompilation.
10
7
11
This instruction includes two memory accesses - one read and one write.
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
After the first access, APIC calls cpu_report_tpr_access, which restores
9
Signed-off-by: Kele Huang <kele.hwang@gmail.com>
13
the CPU state to get the current eip. But cpu_restore_state_from_tb
10
Signed-off-by: Xu Zou <iwatchnima@gmail.com>
14
resets the cpu->can_do_io flag which makes the second memory access invalid.
11
Message-Id: <20201002081420.10814-1-kele.hwang@gmail.com>
15
Therefore the second memory access causes a recompilation of the block.
12
[rth: Use uintptr_t for pc to fix n32 build error.]
16
Then these operations repeat again and again.
17
18
This patch moves resetting cpu->can_do_io flag from
19
cpu_restore_state_from_tb to cpu_loop_exit* functions.
20
21
It also adds a parameter for cpu_restore_state which controls restoring
22
icount. There is no need to restore icount when we only query CPU state
23
without breaking the TB. Restoring it in such cases leads to the
24
incorrect flow of the virtual time.
25
26
In most cases new parameter is true (icount should be recalculated).
27
But there are two cases in i386 and openrisc when the CPU state is only
28
queried without the need to break the TB. This patch fixes both of
29
these cases.
30
31
Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
32
Message-Id: <20180409091320.12504.35329.stgit@pasha-VirtualBox>
33
[rth: Make can_do_io setting unconditional; move from cpu_exec;
34
make cpu_loop_exit_{noexc,restore} call cpu_loop_exit.]
35
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
36
---
14
---
37
include/exec/exec-all.h | 5 ++++-
15
accel/tcg/user-exec.c | 43 +++++++++++++++++++++++++++++++++++++++----
38
accel/tcg/cpu-exec-common.c | 10 +++++-----
16
1 file changed, 39 insertions(+), 4 deletions(-)
39
accel/tcg/cpu-exec.c | 1 -
40
accel/tcg/translate-all.c | 27 ++++++++++++++-------------
41
accel/tcg/user-exec.c | 2 +-
42
hw/misc/mips_itu.c | 3 +--
43
target/alpha/helper.c | 2 +-
44
target/alpha/mem_helper.c | 6 ++----
45
target/arm/op_helper.c | 6 +++---
46
target/cris/op_helper.c | 4 ++--
47
target/i386/helper.c | 2 +-
48
target/i386/svm_helper.c | 2 +-
49
target/m68k/op_helper.c | 4 ++--
50
target/moxie/helper.c | 2 +-
51
target/openrisc/sys_helper.c | 8 ++++----
52
target/tricore/op_helper.c | 2 +-
53
target/xtensa/op_helper.c | 4 ++--
54
17 files changed, 45 insertions(+), 45 deletions(-)
55
17
56
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/include/exec/exec-all.h
59
+++ b/include/exec/exec-all.h
60
@@ -XXX,XX +XXX,XX @@ void cpu_gen_init(void);
61
* cpu_restore_state:
62
* @cpu: the vCPU state is to be restore to
63
* @searched_pc: the host PC the fault occurred at
64
+ * @will_exit: true if the TB executed will be interrupted after some
65
+ cpu adjustments. Required for maintaining the correct
66
+ icount valus
67
* @return: true if state was restored, false otherwise
68
*
69
* Attempt to restore the state for a fault occurring in translated
70
* code. If the searched_pc is not in translated code no state is
71
* restored and the function returns false.
72
*/
73
-bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc);
74
+bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit);
75
76
void QEMU_NORETURN cpu_loop_exit_noexc(CPUState *cpu);
77
void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
78
diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/accel/tcg/cpu-exec-common.c
81
+++ b/accel/tcg/cpu-exec-common.c
82
@@ -XXX,XX +XXX,XX @@ bool tcg_allowed;
83
/* exit the current TB, but without causing any exception to be raised */
84
void cpu_loop_exit_noexc(CPUState *cpu)
85
{
86
- /* XXX: restore cpu registers saved in host registers */
87
-
88
cpu->exception_index = -1;
89
- siglongjmp(cpu->jmp_env, 1);
90
+ cpu_loop_exit(cpu);
91
}
92
93
#if defined(CONFIG_SOFTMMU)
94
@@ -XXX,XX +XXX,XX @@ void cpu_reloading_memory_map(void)
95
96
void cpu_loop_exit(CPUState *cpu)
97
{
98
+ /* Undo the setting in cpu_tb_exec. */
99
+ cpu->can_do_io = 1;
100
siglongjmp(cpu->jmp_env, 1);
101
}
102
103
void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc)
104
{
105
if (pc) {
106
- cpu_restore_state(cpu, pc);
107
+ cpu_restore_state(cpu, pc, true);
108
}
109
- siglongjmp(cpu->jmp_env, 1);
110
+ cpu_loop_exit(cpu);
111
}
112
113
void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc)
114
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/accel/tcg/cpu-exec.c
117
+++ b/accel/tcg/cpu-exec.c
118
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
119
g_assert(cpu == current_cpu);
120
g_assert(cc == CPU_GET_CLASS(cpu));
121
#endif /* buggy compiler */
122
- cpu->can_do_io = 1;
123
tb_lock_reset();
124
if (qemu_mutex_iothread_locked()) {
125
qemu_mutex_unlock_iothread();
126
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/accel/tcg/translate-all.c
129
+++ b/accel/tcg/translate-all.c
130
@@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
131
132
/* The cpu state corresponding to 'searched_pc' is restored.
133
* Called with tb_lock held.
134
+ * When reset_icount is true, current TB will be interrupted and
135
+ * icount should be recalculated.
136
*/
137
static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
138
- uintptr_t searched_pc)
139
+ uintptr_t searched_pc, bool reset_icount)
140
{
141
target_ulong data[TARGET_INSN_START_WORDS] = { tb->pc };
142
uintptr_t host_pc = (uintptr_t)tb->tc.ptr;
143
@@ -XXX,XX +XXX,XX @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
144
return -1;
145
146
found:
147
- if (tb->cflags & CF_USE_ICOUNT) {
148
+ if (reset_icount && (tb->cflags & CF_USE_ICOUNT)) {
149
assert(use_icount);
150
- /* Reset the cycle counter to the start of the block. */
151
- cpu->icount_decr.u16.low += num_insns;
152
- /* Clear the IO flag. */
153
- cpu->can_do_io = 0;
154
+ /* Reset the cycle counter to the start of the block
155
+ and shift if to the number of actually executed instructions */
156
+ cpu->icount_decr.u16.low += num_insns - i;
157
}
158
- cpu->icount_decr.u16.low -= i;
159
restore_state_to_opc(env, tb, data);
160
161
#ifdef CONFIG_PROFILER
162
@@ -XXX,XX +XXX,XX @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
163
return 0;
164
}
165
166
-bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
167
+bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit)
168
{
169
TranslationBlock *tb;
170
bool r = false;
171
@@ -XXX,XX +XXX,XX @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
172
tb_lock();
173
tb = tb_find_pc(host_pc);
174
if (tb) {
175
- cpu_restore_state_from_tb(cpu, tb, host_pc);
176
+ cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit);
177
if (tb->cflags & CF_NOCACHE) {
178
/* one-shot translation, invalidate it immediately */
179
tb_phys_invalidate(tb, -1);
180
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
181
restore the CPU state */
182
183
current_tb_modified = 1;
184
- cpu_restore_state_from_tb(cpu, current_tb, cpu->mem_io_pc);
185
+ cpu_restore_state_from_tb(cpu, current_tb,
186
+ cpu->mem_io_pc, true);
187
cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
188
&current_flags);
189
}
190
@@ -XXX,XX +XXX,XX @@ static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc)
191
restore the CPU state */
192
193
current_tb_modified = 1;
194
- cpu_restore_state_from_tb(cpu, current_tb, pc);
195
+ cpu_restore_state_from_tb(cpu, current_tb, pc, true);
196
cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
197
&current_flags);
198
}
199
@@ -XXX,XX +XXX,XX @@ void tb_check_watchpoint(CPUState *cpu)
200
tb = tb_find_pc(cpu->mem_io_pc);
201
if (tb) {
202
/* We can use retranslation to find the PC. */
203
- cpu_restore_state_from_tb(cpu, tb, cpu->mem_io_pc);
204
+ cpu_restore_state_from_tb(cpu, tb, cpu->mem_io_pc, true);
205
tb_phys_invalidate(tb, -1);
206
} else {
207
/* The exception probably happened in a helper. The CPU state should
208
@@ -XXX,XX +XXX,XX @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
209
cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p",
210
(void *)retaddr);
211
}
212
- cpu_restore_state_from_tb(cpu, tb, retaddr);
213
+ cpu_restore_state_from_tb(cpu, tb, retaddr, true);
214
215
/* On MIPS and SH, delay slot instructions can only be restarted if
216
they were already the first instruction in the TB. If this is not
217
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
18
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
218
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
219
--- a/accel/tcg/user-exec.c
20
--- a/accel/tcg/user-exec.c
220
+++ b/accel/tcg/user-exec.c
21
+++ b/accel/tcg/user-exec.c
221
@@ -XXX,XX +XXX,XX @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
22
@@ -XXX,XX +XXX,XX @@ int cpu_signal_handler(int host_signum, void *pinfo,
222
}
23
223
24
#elif defined(__mips__)
224
/* Now we have a real cpu fault. */
25
225
- cpu_restore_state(cpu, pc);
26
+#if defined(__misp16) || defined(__mips_micromips)
226
+ cpu_restore_state(cpu, pc, true);
27
+#error "Unsupported encoding"
227
28
+#endif
228
sigprocmask(SIG_SETMASK, old_set, NULL);
29
+
229
cpu_loop_exit(cpu);
30
int cpu_signal_handler(int host_signum, void *pinfo,
230
diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
31
void *puc)
231
index XXXXXXX..XXXXXXX 100644
232
--- a/hw/misc/mips_itu.c
233
+++ b/hw/misc/mips_itu.c
234
@@ -XXX,XX +XXX,XX @@ static void wake_blocked_threads(ITCStorageCell *c)
235
static void QEMU_NORETURN block_thread_and_exit(ITCStorageCell *c)
236
{
32
{
237
c->blocked_threads |= 1ULL << current_cpu->cpu_index;
33
siginfo_t *info = pinfo;
238
- cpu_restore_state(current_cpu, current_cpu->mem_io_pc);
34
ucontext_t *uc = puc;
239
current_cpu->halted = 1;
35
- greg_t pc = uc->uc_mcontext.pc;
240
current_cpu->exception_index = EXCP_HLT;
36
- int is_write;
241
- cpu_loop_exit(current_cpu);
37
+ uintptr_t pc = uc->uc_mcontext.pc;
242
+ cpu_loop_exit_restore(current_cpu, current_cpu->mem_io_pc);
38
+ uint32_t insn = *(uint32_t *)pc;
39
+ int is_write = 0;
40
+
41
+ /* Detect all store instructions at program counter. */
42
+ switch((insn >> 26) & 077) {
43
+ case 050: /* SB */
44
+ case 051: /* SH */
45
+ case 052: /* SWL */
46
+ case 053: /* SW */
47
+ case 054: /* SDL */
48
+ case 055: /* SDR */
49
+ case 056: /* SWR */
50
+ case 070: /* SC */
51
+ case 071: /* SWC1 */
52
+ case 074: /* SCD */
53
+ case 075: /* SDC1 */
54
+ case 077: /* SD */
55
+#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
56
+ case 072: /* SWC2 */
57
+ case 076: /* SDC2 */
58
+#endif
59
+ is_write = 1;
60
+ break;
61
+ case 023: /* COP1X */
62
+ /* Required in all versions of MIPS64 since
63
+ MIPS64r1 and subsequent versions of MIPS32r2. */
64
+ switch (insn & 077) {
65
+ case 010: /* SWXC1 */
66
+ case 011: /* SDXC1 */
67
+ case 015: /* SUXC1 */
68
+ is_write = 1;
69
+ }
70
+ break;
71
+ }
72
73
- /* XXX: compute is_write */
74
- is_write = 0;
75
return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
243
}
76
}
244
77
245
/* ITC Bypass View */
246
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/target/alpha/helper.c
249
+++ b/target/alpha/helper.c
250
@@ -XXX,XX +XXX,XX @@ void QEMU_NORETURN dynamic_excp(CPUAlphaState *env, uintptr_t retaddr,
251
cs->exception_index = excp;
252
env->error_code = error;
253
if (retaddr) {
254
- cpu_restore_state(cs, retaddr);
255
+ cpu_restore_state(cs, retaddr, true);
256
/* Floating-point exceptions (our only users) point to the next PC. */
257
env->pc += 4;
258
}
259
diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c
260
index XXXXXXX..XXXXXXX 100644
261
--- a/target/alpha/mem_helper.c
262
+++ b/target/alpha/mem_helper.c
263
@@ -XXX,XX +XXX,XX @@ void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
264
uint64_t pc;
265
uint32_t insn;
266
267
- cpu_restore_state(cs, retaddr);
268
+ cpu_restore_state(cs, retaddr, true);
269
270
pc = env->pc;
271
insn = cpu_ldl_code(env, pc);
272
@@ -XXX,XX +XXX,XX @@ void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
273
AlphaCPU *cpu = ALPHA_CPU(cs);
274
CPUAlphaState *env = &cpu->env;
275
276
- cpu_restore_state(cs, retaddr);
277
-
278
env->trap_arg0 = addr;
279
env->trap_arg1 = access_type == MMU_DATA_STORE ? 1 : 0;
280
cs->exception_index = EXCP_MCHK;
281
env->error_code = 0;
282
- cpu_loop_exit(cs);
283
+ cpu_loop_exit_restore(cs, retaddr);
284
}
285
286
/* try to fill the TLB and return an exception if error. If retaddr is
287
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
288
index XXXXXXX..XXXXXXX 100644
289
--- a/target/arm/op_helper.c
290
+++ b/target/arm/op_helper.c
291
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, int size,
292
ARMCPU *cpu = ARM_CPU(cs);
293
294
/* now we have a real cpu fault */
295
- cpu_restore_state(cs, retaddr);
296
+ cpu_restore_state(cs, retaddr, true);
297
298
deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
299
}
300
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
301
ARMMMUFaultInfo fi = {};
302
303
/* now we have a real cpu fault */
304
- cpu_restore_state(cs, retaddr);
305
+ cpu_restore_state(cs, retaddr, true);
306
307
fi.type = ARMFault_Alignment;
308
deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
309
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
310
ARMMMUFaultInfo fi = {};
311
312
/* now we have a real cpu fault */
313
- cpu_restore_state(cs, retaddr);
314
+ cpu_restore_state(cs, retaddr, true);
315
316
fi.ea = arm_extabort_type(response);
317
fi.type = ARMFault_SyncExternal;
318
diff --git a/target/cris/op_helper.c b/target/cris/op_helper.c
319
index XXXXXXX..XXXXXXX 100644
320
--- a/target/cris/op_helper.c
321
+++ b/target/cris/op_helper.c
322
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, int size,
323
if (unlikely(ret)) {
324
if (retaddr) {
325
/* now we have a real cpu fault */
326
- if (cpu_restore_state(cs, retaddr)) {
327
-        /* Evaluate flags after retranslation. */
328
+ if (cpu_restore_state(cs, retaddr, true)) {
329
+ /* Evaluate flags after retranslation. */
330
helper_top_evaluate_flags(env);
331
}
332
}
333
diff --git a/target/i386/helper.c b/target/i386/helper.c
334
index XXXXXXX..XXXXXXX 100644
335
--- a/target/i386/helper.c
336
+++ b/target/i386/helper.c
337
@@ -XXX,XX +XXX,XX @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
338
339
cpu_interrupt(cs, CPU_INTERRUPT_TPR);
340
} else if (tcg_enabled()) {
341
- cpu_restore_state(cs, cs->mem_io_pc);
342
+ cpu_restore_state(cs, cs->mem_io_pc, false);
343
344
apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
345
}
346
diff --git a/target/i386/svm_helper.c b/target/i386/svm_helper.c
347
index XXXXXXX..XXXXXXX 100644
348
--- a/target/i386/svm_helper.c
349
+++ b/target/i386/svm_helper.c
350
@@ -XXX,XX +XXX,XX @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
351
{
352
CPUState *cs = CPU(x86_env_get_cpu(env));
353
354
- cpu_restore_state(cs, retaddr);
355
+ cpu_restore_state(cs, retaddr, true);
356
357
qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016"
358
PRIx64 ", " TARGET_FMT_lx ")!\n",
359
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
360
index XXXXXXX..XXXXXXX 100644
361
--- a/target/m68k/op_helper.c
362
+++ b/target/m68k/op_helper.c
363
@@ -XXX,XX +XXX,XX @@ void HELPER(chk)(CPUM68KState *env, int32_t val, int32_t ub)
364
CPUState *cs = CPU(m68k_env_get_cpu(env));
365
366
/* Recover PC and CC_OP for the beginning of the insn. */
367
- cpu_restore_state(cs, GETPC());
368
+ cpu_restore_state(cs, GETPC(), true);
369
370
/* flags have been modified by gen_flush_flags() */
371
env->cc_op = CC_OP_FLAGS;
372
@@ -XXX,XX +XXX,XX @@ void HELPER(chk2)(CPUM68KState *env, int32_t val, int32_t lb, int32_t ub)
373
CPUState *cs = CPU(m68k_env_get_cpu(env));
374
375
/* Recover PC and CC_OP for the beginning of the insn. */
376
- cpu_restore_state(cs, GETPC());
377
+ cpu_restore_state(cs, GETPC(), true);
378
379
/* flags have been modified by gen_flush_flags() */
380
env->cc_op = CC_OP_FLAGS;
381
diff --git a/target/moxie/helper.c b/target/moxie/helper.c
382
index XXXXXXX..XXXXXXX 100644
383
--- a/target/moxie/helper.c
384
+++ b/target/moxie/helper.c
385
@@ -XXX,XX +XXX,XX @@ void helper_raise_exception(CPUMoxieState *env, int ex)
386
/* Stash the exception type. */
387
env->sregs[2] = ex;
388
/* Stash the address where the exception occurred. */
389
- cpu_restore_state(cs, GETPC());
390
+ cpu_restore_state(cs, GETPC(), true);
391
env->sregs[5] = env->pc;
392
/* Jump to the exception handline routine. */
393
env->pc = env->sregs[1];
394
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
395
index XXXXXXX..XXXXXXX 100644
396
--- a/target/openrisc/sys_helper.c
397
+++ b/target/openrisc/sys_helper.c
398
@@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env,
399
break;
400
401
case TO_SPR(0, 16): /* NPC */
402
- cpu_restore_state(cs, GETPC());
403
+ cpu_restore_state(cs, GETPC(), true);
404
/* ??? Mirror or1ksim in not trashing delayed branch state
405
when "jumping" to the current instruction. */
406
if (env->pc != rb) {
407
@@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env,
408
case TO_SPR(8, 0): /* PMR */
409
env->pmr = rb;
410
if (env->pmr & PMR_DME || env->pmr & PMR_SME) {
411
- cpu_restore_state(cs, GETPC());
412
+ cpu_restore_state(cs, GETPC(), true);
413
env->pc += 4;
414
cs->halted = 1;
415
raise_exception(cpu, EXCP_HALTED);
416
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
417
return env->evbar;
418
419
case TO_SPR(0, 16): /* NPC (equals PC) */
420
- cpu_restore_state(cs, GETPC());
421
+ cpu_restore_state(cs, GETPC(), false);
422
return env->pc;
423
424
case TO_SPR(0, 17): /* SR */
425
return cpu_get_sr(env);
426
427
case TO_SPR(0, 18): /* PPC */
428
- cpu_restore_state(cs, GETPC());
429
+ cpu_restore_state(cs, GETPC(), false);
430
return env->ppc;
431
432
case TO_SPR(0, 32): /* EPCR */
433
diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c
434
index XXXXXXX..XXXXXXX 100644
435
--- a/target/tricore/op_helper.c
436
+++ b/target/tricore/op_helper.c
437
@@ -XXX,XX +XXX,XX @@ raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin,
438
{
439
CPUState *cs = CPU(tricore_env_get_cpu(env));
440
/* in case we come from a helper-call we need to restore the PC */
441
- cpu_restore_state(cs, pc);
442
+ cpu_restore_state(cs, pc, true);
443
444
/* Tin is loaded into d[15] */
445
env->gpr_d[15] = tin;
446
diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c
447
index XXXXXXX..XXXXXXX 100644
448
--- a/target/xtensa/op_helper.c
449
+++ b/target/xtensa/op_helper.c
450
@@ -XXX,XX +XXX,XX @@ void xtensa_cpu_do_unaligned_access(CPUState *cs,
451
452
if (xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) &&
453
!xtensa_option_enabled(env->config, XTENSA_OPTION_HW_ALIGNMENT)) {
454
- cpu_restore_state(CPU(cpu), retaddr);
455
+ cpu_restore_state(CPU(cpu), retaddr, true);
456
HELPER(exception_cause_vaddr)(env,
457
env->pc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
458
}
459
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong vaddr, int size,
460
paddr & TARGET_PAGE_MASK,
461
access, mmu_idx, page_size);
462
} else {
463
- cpu_restore_state(cs, retaddr);
464
+ cpu_restore_state(cs, retaddr, true);
465
HELPER(exception_cause_vaddr)(env, env->pc, ret, vaddr);
466
}
467
}
468
--
78
--
469
2.14.3
79
2.25.1
470
80
471
81
diff view generated by jsdifflib