1
The following changes since commit 6eeea6725a70e6fcb5abba0764496bdab07ddfb3:
1
The following changes since commit 8f860d2633baf9c2b6261f703f86e394c6bc22ca:
2
2
3
Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2020-10-06' into staging (2020-10-06 21:13:34 +0100)
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-04-30' into staging (2021-04-30 16:02:00 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/rth7680/qemu.git tags/pull-tcg-20201008
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20210501
8
8
9
for you to fetch changes up to 62475e9d007d83db4d0a6ccebcda8914f392e9c9:
9
for you to fetch changes up to af93ccacc772019298be4c3e47251cdaa60d0c21:
10
10
11
accel/tcg: Fix computing of is_write for MIPS (2020-10-08 05:57:32 -0500)
11
decodetree: Extend argument set syntax to allow types (2021-05-01 11:45:35 -0700)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Extend maximum gvec vector size
14
Include cleanups.
15
Fix i386 avx2 dupi
15
Decodetree enhancements for power10.
16
Fix mips host user-only write detection
17
Misc cleanups.
18
16
19
----------------------------------------------------------------
17
----------------------------------------------------------------
20
Kele Huang (1):
18
Luis Fernando Fujita Pires (1):
21
accel/tcg: Fix computing of is_write for MIPS
19
decodetree: Add support for 64-bit instructions
22
20
23
Richard Henderson (10):
21
Philippe Mathieu-Daudé (1):
24
tcg: Adjust simd_desc size encoding
22
exec: Remove accel/tcg/ from include paths
25
tcg: Drop union from TCGArgConstraint
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
23
35
include/tcg/tcg-gvec-desc.h | 38 ++++++++++++------
24
Richard Henderson (3):
36
include/tcg/tcg.h | 22 ++++------
25
decodetree: Introduce whex and whexC helpers
37
tcg/aarch64/tcg-target.h | 1 -
26
decodetree: More use of f-strings
38
tcg/i386/tcg-target.h | 1 -
27
decodetree: Extend argument set syntax to allow types
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
28
29
docs/devel/decodetree.rst | 11 ++-
30
meson.build | 1 -
31
include/exec/helper-gen.h | 4 +-
32
include/exec/helper-proto.h | 4 +-
33
include/exec/helper-tcg.h | 4 +-
34
tests/decode/succ_argset_type1.decode | 1 +
35
scripts/decodetree.py | 172 +++++++++++++++++++---------------
36
7 files changed, 112 insertions(+), 85 deletions(-)
37
create mode 100644 tests/decode/succ_argset_type1.decode
38
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
The cmp_vec opcode is mandatory; this symbol is unused.
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
When TCG is enabled, the accel/tcg/ include path is added to the
4
project global include search list. This accel/tcg/ directory
5
contains a header named "internal.h" which, while intented to
6
be internal to accel/tcg/, is accessible by all files compiled
7
when TCG is enabled. This might lead to problem with other
8
directories using the same "internal.h" header name:
9
10
$ git ls-files | fgrep /internal.h
11
accel/tcg/internal.h
12
include/hw/ide/internal.h
13
target/hexagon/internal.h
14
target/mips/internal.h
15
target/ppc/internal.h
16
target/s390x/internal.h
17
18
As we don't need to expose accel/tcg/ internals to the rest of
19
the code base, simplify by removing it from the include search
20
list, and include the accel/tcg/ public headers relative to the
21
project root search path (which is already in the generic include
22
search path).
23
24
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Reviewed-by: Claudio Fontana <cfontana@suse.de>
26
Message-Id: <20210413081008.3409459-1-f4bug@amsat.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
27
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
28
---
6
tcg/aarch64/tcg-target.h | 1 -
29
meson.build | 1 -
7
tcg/i386/tcg-target.h | 1 -
30
include/exec/helper-gen.h | 4 ++--
8
tcg/ppc/tcg-target.h | 1 -
31
include/exec/helper-proto.h | 4 ++--
9
3 files changed, 3 deletions(-)
32
include/exec/helper-tcg.h | 4 ++--
33
4 files changed, 6 insertions(+), 7 deletions(-)
10
34
11
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
35
diff --git a/meson.build b/meson.build
12
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/aarch64/tcg-target.h
37
--- a/meson.build
14
+++ b/tcg/aarch64/tcg-target.h
38
+++ b/meson.build
15
@@ -XXX,XX +XXX,XX @@ typedef enum {
39
@@ -XXX,XX +XXX,XX @@ if not get_option('tcg').disabled()
16
#define TCG_TARGET_HAS_shi_vec 1
40
tcg_arch = 'riscv'
17
#define TCG_TARGET_HAS_shs_vec 0
41
endif
18
#define TCG_TARGET_HAS_shv_vec 1
42
add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
19
-#define TCG_TARGET_HAS_cmp_vec 1
43
- '-iquote', meson.current_source_dir() / 'accel/tcg',
20
#define TCG_TARGET_HAS_mul_vec 1
44
language: ['c', 'cpp', 'objc'])
21
#define TCG_TARGET_HAS_sat_vec 1
45
22
#define TCG_TARGET_HAS_minmax_vec 1
46
accelerators += 'CONFIG_TCG'
23
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
47
diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
24
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
25
--- a/tcg/i386/tcg-target.h
49
--- a/include/exec/helper-gen.h
26
+++ b/tcg/i386/tcg-target.h
50
+++ b/include/exec/helper-gen.h
27
@@ -XXX,XX +XXX,XX @@ extern bool have_avx2;
51
@@ -XXX,XX +XXX,XX @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
28
#define TCG_TARGET_HAS_shi_vec 1
52
#include "helper.h"
29
#define TCG_TARGET_HAS_shs_vec 1
53
#include "trace/generated-helpers.h"
30
#define TCG_TARGET_HAS_shv_vec have_avx2
54
#include "trace/generated-helpers-wrappers.h"
31
-#define TCG_TARGET_HAS_cmp_vec 1
55
-#include "tcg-runtime.h"
32
#define TCG_TARGET_HAS_mul_vec 1
56
-#include "plugin-helpers.h"
33
#define TCG_TARGET_HAS_sat_vec 1
57
+#include "accel/tcg/tcg-runtime.h"
34
#define TCG_TARGET_HAS_minmax_vec 1
58
+#include "accel/tcg/plugin-helpers.h"
35
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
59
60
#undef DEF_HELPER_FLAGS_0
61
#undef DEF_HELPER_FLAGS_1
62
diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h
36
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
37
--- a/tcg/ppc/tcg-target.h
64
--- a/include/exec/helper-proto.h
38
+++ b/tcg/ppc/tcg-target.h
65
+++ b/include/exec/helper-proto.h
39
@@ -XXX,XX +XXX,XX @@ extern bool have_vsx;
66
@@ -XXX,XX +XXX,XX @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
40
#define TCG_TARGET_HAS_shi_vec 0
67
41
#define TCG_TARGET_HAS_shs_vec 0
68
#include "helper.h"
42
#define TCG_TARGET_HAS_shv_vec 1
69
#include "trace/generated-helpers.h"
43
-#define TCG_TARGET_HAS_cmp_vec 1
70
-#include "tcg-runtime.h"
44
#define TCG_TARGET_HAS_mul_vec 1
71
-#include "plugin-helpers.h"
45
#define TCG_TARGET_HAS_sat_vec 1
72
+#include "accel/tcg/tcg-runtime.h"
46
#define TCG_TARGET_HAS_minmax_vec 1
73
+#include "accel/tcg/plugin-helpers.h"
74
75
#undef IN_HELPER_PROTO
76
77
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
78
index XXXXXXX..XXXXXXX 100644
79
--- a/include/exec/helper-tcg.h
80
+++ b/include/exec/helper-tcg.h
81
@@ -XXX,XX +XXX,XX @@
82
83
#include "helper.h"
84
#include "trace/generated-helpers.h"
85
-#include "tcg-runtime.h"
86
-#include "plugin-helpers.h"
87
+#include "accel/tcg/tcg-runtime.h"
88
+#include "accel/tcg/plugin-helpers.h"
89
90
#undef str
91
#undef DEF_HELPER_FLAGS_0
47
--
92
--
48
2.25.1
93
2.25.1
49
94
50
95
diff view generated by jsdifflib
1
When the two arguments are identical, this can be reduced to
1
Form a hex constant of the appropriate insnwidth.
2
dup_vec or to mov_vec from a tcg_constant_vec.
2
Begin using f-strings on changed lines.
3
3
4
Reviewed-by: Luis Pires <luis.pires@eldorado.org.br>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
---
6
tcg/optimize.c | 15 +++++++++++++++
7
scripts/decodetree.py | 66 +++++++++++++++++++++++++------------------
7
1 file changed, 15 insertions(+)
8
1 file changed, 38 insertions(+), 28 deletions(-)
8
9
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
10
diff --git a/scripts/decodetree.py b/scripts/decodetree.py
10
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/optimize.c
12
--- a/scripts/decodetree.py
12
+++ b/tcg/optimize.c
13
+++ b/scripts/decodetree.py
13
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
14
@@ -XXX,XX +XXX,XX @@ def str_fields(fields):
14
}
15
return r[1:]
15
goto do_default;
16
16
17
17
+ case INDEX_op_dup2_vec:
18
+def whex(val):
18
+ assert(TCG_TARGET_REG_BITS == 32);
19
+ """Return a hex string for val padded for insnwidth"""
19
+ if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) {
20
+ global insnwidth
20
+ tmp = arg_info(op->args[1])->val;
21
+ return f'0x{val:0{insnwidth // 4}x}'
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
+
22
+
32
CASE_OP_32_64(not):
23
+
33
CASE_OP_32_64(neg):
24
+def whexC(val):
34
CASE_OP_32_64(ext8s):
25
+ """Return a hex string for val padded for insnwidth,
26
+ and with the proper suffix for a C constant."""
27
+ suffix = ''
28
+ if val >= 0x80000000:
29
+ suffix = 'u'
30
+ return whex(val) + suffix
31
+
32
+
33
def str_match_bits(bits, mask):
34
"""Return a string pretty-printing BITS/MASK"""
35
global insnwidth
36
@@ -XXX,XX +XXX,XX @@ def output_code(self, i, extracted, outerbits, outermask):
37
if outermask != p.fixedmask:
38
innermask = p.fixedmask & ~outermask
39
innerbits = p.fixedbits & ~outermask
40
- output(ind, 'if ((insn & ',
41
- '0x{0:08x}) == 0x{1:08x}'.format(innermask, innerbits),
42
- ') {\n')
43
- output(ind, ' /* ',
44
- str_match_bits(p.fixedbits, p.fixedmask), ' */\n')
45
+ output(ind, f'if ((insn & {whexC(innermask)}) == {whexC(innerbits)}) {{\n')
46
+ output(ind, f' /* {str_match_bits(p.fixedbits, p.fixedmask)} */\n')
47
p.output_code(i + 4, extracted, p.fixedbits, p.fixedmask)
48
output(ind, '}\n')
49
else:
50
@@ -XXX,XX +XXX,XX @@ def __init__(self, fm, tm):
51
52
def str1(self, i):
53
ind = str_indent(i)
54
- r = '{0}{1:08x}'.format(ind, self.fixedmask)
55
+ r = ind + whex(self.fixedmask)
56
if self.format:
57
r += ' ' + self.format.name
58
r += ' [\n'
59
for (b, s) in self.subs:
60
- r += '{0} {1:08x}:\n'.format(ind, b)
61
+ r += ind + f' {whex(b)}:\n'
62
r += s.str1(i + 4) + '\n'
63
r += ind + ']'
64
return r
65
@@ -XXX,XX +XXX,XX @@ def output_code(self, i, extracted, outerbits, outermask):
66
if sh > 0:
67
# Propagate SH down into the local functions.
68
def str_switch(b, sh=sh):
69
- return '(insn >> {0}) & 0x{1:x}'.format(sh, b >> sh)
70
+ return f'(insn >> {sh}) & {b >> sh:#x}'
71
72
def str_case(b, sh=sh):
73
- return '0x{0:x}'.format(b >> sh)
74
+ return hex(b >> sh)
75
else:
76
def str_switch(b):
77
- return 'insn & 0x{0:08x}'.format(b)
78
+ return f'insn & {whexC(b)}'
79
80
def str_case(b):
81
- return '0x{0:08x}'.format(b)
82
+ return whexC(b)
83
84
output(ind, 'switch (', str_switch(self.thismask), ') {\n')
85
for b, s in sorted(self.subs):
86
@@ -XXX,XX +XXX,XX @@ def parse_generic(lineno, parent_pat, name, toks):
87
88
# Validate the masks that we have assembled.
89
if fieldmask & fixedmask:
90
- error(lineno, 'fieldmask overlaps fixedmask (0x{0:08x} & 0x{1:08x})'
91
- .format(fieldmask, fixedmask))
92
+ error(lineno, 'fieldmask overlaps fixedmask ',
93
+ f'({whex(fieldmask)} & {whex(fixedmask)})')
94
if fieldmask & undefmask:
95
- error(lineno, 'fieldmask overlaps undefmask (0x{0:08x} & 0x{1:08x})'
96
- .format(fieldmask, undefmask))
97
+ error(lineno, 'fieldmask overlaps undefmask ',
98
+ f'({whex(fieldmask)} & {whex(undefmask)})')
99
if fixedmask & undefmask:
100
- error(lineno, 'fixedmask overlaps undefmask (0x{0:08x} & 0x{1:08x})'
101
- .format(fixedmask, undefmask))
102
+ error(lineno, 'fixedmask overlaps undefmask ',
103
+ f'({whex(fixedmask)} & {whex(undefmask)})')
104
if not is_format:
105
allbits = fieldmask | fixedmask | undefmask
106
if allbits != insnmask:
107
- error(lineno, 'bits left unspecified (0x{0:08x})'
108
- .format(allbits ^ insnmask))
109
+ error(lineno, 'bits left unspecified ',
110
+ f'({whex(allbits ^ insnmask)})')
111
# end parse_general
112
113
114
@@ -XXX,XX +XXX,XX @@ def __init__(self, m, w):
115
116
def str1(self, i):
117
ind = str_indent(i)
118
- r = '{0}{1:08x}'.format(ind, self.mask)
119
- r += ' [\n'
120
+ r = ind + whex(self.mask) + ' [\n'
121
for (b, s) in self.subs:
122
- r += '{0} {1:08x}:\n'.format(ind, b)
123
+ r += ind + f' {whex(b)}:\n'
124
r += s.str1(i + 4) + '\n'
125
r += ind + ']'
126
return r
127
@@ -XXX,XX +XXX,XX @@ def output_code(self, i, extracted, outerbits, outermask):
128
if sh > 0:
129
# Propagate SH down into the local functions.
130
def str_switch(b, sh=sh):
131
- return '(insn >> {0}) & 0x{1:x}'.format(sh, b >> sh)
132
+ return f'(insn >> {sh}) & {b >> sh:#x}'
133
134
def str_case(b, sh=sh):
135
- return '0x{0:x}'.format(b >> sh)
136
+ return hex(b >> sh)
137
else:
138
def str_switch(b):
139
- return 'insn & 0x{0:08x}'.format(b)
140
+ return f'insn & {whexC(b)}'
141
142
def str_case(b):
143
- return '0x{0:08x}'.format(b)
144
+ return whexC(b)
145
146
output(ind, 'switch (', str_switch(self.mask), ') {\n')
147
for b, s in sorted(self.subs):
148
@@ -XXX,XX +XXX,XX @@ def __init__(self, m, w):
149
self.width = w
150
151
def str1(self, i):
152
- ind = str_indent(i)
153
- return '{0}{1:08x}'.format(ind, self.mask)
154
+ return str_indent(i) + whex(self.mask)
155
156
def __str__(self):
157
return self.str1(0)
35
--
158
--
36
2.25.1
159
2.25.1
37
160
38
161
diff view generated by jsdifflib
1
The definition of INDEX_op_dupi_vec is that it operates on
1
Reviewed-by: Luis Pires <luis.pires@eldorado.org.br>
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.
5
6
Fixes: d2fd745fe8b
7
Fixes: db432672dc5
8
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
3
---
11
tcg/tcg-op-vec.c | 12 ++++++++----
4
scripts/decodetree.py | 50 ++++++++++++++++++++-----------------------
12
1 file changed, 8 insertions(+), 4 deletions(-)
5
1 file changed, 23 insertions(+), 27 deletions(-)
13
6
14
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
7
diff --git a/scripts/decodetree.py b/scripts/decodetree.py
15
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/tcg-op-vec.c
9
--- a/scripts/decodetree.py
17
+++ b/tcg/tcg-op-vec.c
10
+++ b/scripts/decodetree.py
18
@@ -XXX,XX +XXX,XX @@ TCGv_vec tcg_const_ones_vec_matching(TCGv_vec m)
11
@@ -XXX,XX +XXX,XX @@ def error_with_file(file, lineno, *args):
19
12
20
void tcg_gen_dup64i_vec(TCGv_vec r, uint64_t a)
13
prefix = ''
21
{
14
if file:
22
- if (TCG_TARGET_REG_BITS == 32 && a == deposit64(a, 32, 32, a)) {
15
- prefix += '{0}:'.format(file)
23
- do_dupi_vec(r, MO_32, a);
16
+ prefix += f'{file}:'
24
- } else if (TCG_TARGET_REG_BITS == 64 || a == (uint64_t)(int32_t)a) {
17
if lineno:
25
+ if (TCG_TARGET_REG_BITS == 64) {
18
- prefix += '{0}:'.format(lineno)
26
do_dupi_vec(r, MO_64, a);
19
+ prefix += f'{lineno}:'
27
+ } else if (a == dup_const(MO_32, a)) {
20
if prefix:
28
+ do_dupi_vec(r, MO_32, a);
21
prefix += ' '
29
} else {
22
print(prefix, end='error: ', file=sys.stderr)
30
TCGv_i64 c = tcg_const_i64(a);
23
@@ -XXX,XX +XXX,XX @@ def str_extract(self):
31
tcg_gen_dup_i64_vec(MO_64, r, c);
24
extr = 'sextract32'
32
@@ -XXX,XX +XXX,XX @@ void tcg_gen_dup8i_vec(TCGv_vec r, uint32_t a)
25
else:
33
26
extr = 'extract32'
34
void tcg_gen_dupi_vec(unsigned vece, TCGv_vec r, uint64_t a)
27
- return '{0}(insn, {1}, {2})'.format(extr, self.pos, self.len)
35
{
28
+ return f'{extr}(insn, {self.pos}, {self.len})'
36
- do_dupi_vec(r, MO_REG, dup_const(vece, a));
29
37
+ if (vece == MO_64) {
30
def __eq__(self, other):
38
+ tcg_gen_dup64i_vec(r, a);
31
return self.sign == other.sign and self.mask == other.mask
39
+ } else {
32
@@ -XXX,XX +XXX,XX @@ def str_extract(self):
40
+ do_dupi_vec(r, MO_REG, dup_const(vece, a));
33
ret = '0'
41
+ }
34
pos = 0
42
}
35
for f in reversed(self.subs):
43
36
+ ext = f.str_extract()
44
void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec r, TCGv_i64 a)
37
if pos == 0:
38
- ret = f.str_extract()
39
+ ret = ext
40
else:
41
- ret = 'deposit32({0}, {1}, {2}, {3})' \
42
- .format(ret, pos, 32 - pos, f.str_extract())
43
+ ret = f'deposit32({ret}, {pos}, {32 - pos}, {ext})'
44
pos += f.len
45
return ret
46
47
@@ -XXX,XX +XXX,XX @@ def parse_field(lineno, name, toks):
48
subtoks = t.split(':')
49
sign = False
50
else:
51
- error(lineno, 'invalid field token "{0}"'.format(t))
52
+ error(lineno, f'invalid field token "{t}"')
53
po = int(subtoks[0])
54
le = int(subtoks[1])
55
if po + le > insnwidth:
56
- error(lineno, 'field {0} too large'.format(t))
57
+ error(lineno, f'field {t} too large')
58
f = Field(sign, po, le)
59
subs.append(f)
60
width += le
61
@@ -XXX,XX +XXX,XX @@ def parse_arguments(lineno, name, toks):
62
anyextern = True
63
continue
64
if not re.fullmatch(re_C_ident, t):
65
- error(lineno, 'invalid argument set token "{0}"'.format(t))
66
+ error(lineno, f'invalid argument set token "{t}"')
67
if t in flds:
68
- error(lineno, 'duplicate argument "{0}"'.format(t))
69
+ error(lineno, f'duplicate argument "{t}"')
70
flds.append(t)
71
72
if name in arguments:
73
@@ -XXX,XX +XXX,XX @@ def parse_generic(lineno, parent_pat, name, toks):
74
flen = flen[1:]
75
shift = int(flen, 10)
76
if shift + width > insnwidth:
77
- error(lineno, 'field {0} exceeds insnwidth'.format(fname))
78
+ error(lineno, f'field {fname} exceeds insnwidth')
79
f = Field(sign, insnwidth - width - shift, shift)
80
flds = add_field(lineno, flds, fname, f)
81
fixedbits <<= shift
82
fixedmask <<= shift
83
undefmask <<= shift
84
else:
85
- error(lineno, 'invalid token "{0}"'.format(t))
86
+ error(lineno, f'invalid token "{t}"')
87
width += shift
88
89
if variablewidth and width < insnwidth and width % 8 == 0:
90
@@ -XXX,XX +XXX,XX @@ def parse_generic(lineno, parent_pat, name, toks):
91
92
# We should have filled in all of the bits of the instruction.
93
elif not (is_format and width == 0) and width != insnwidth:
94
- error(lineno, 'definition has {0} bits'.format(width))
95
+ error(lineno, f'definition has {width} bits')
96
97
# Do not check for fields overlapping fields; one valid usage
98
# is to be able to duplicate fields via import.
99
@@ -XXX,XX +XXX,XX @@ def parse_generic(lineno, parent_pat, name, toks):
100
if arg:
101
for f in flds.keys():
102
if f not in arg.fields:
103
- error(lineno, 'field {0} not in argument set {1}'
104
- .format(f, arg.name))
105
+ error(lineno, f'field {f} not in argument set {arg.name}')
106
else:
107
arg = infer_argument_set(flds)
108
if name in formats:
109
@@ -XXX,XX +XXX,XX @@ def parse_generic(lineno, parent_pat, name, toks):
110
arg = fmt.base
111
for f in flds.keys():
112
if f not in arg.fields:
113
- error(lineno, 'field {0} not in argument set {1}'
114
- .format(f, arg.name))
115
+ error(lineno, f'field {f} not in argument set {arg.name}')
116
if f in fmt.fields.keys():
117
- error(lineno, 'field {0} set by format and pattern'.format(f))
118
+ error(lineno, f'field {f} set by format and pattern')
119
for f in arg.fields:
120
if f not in flds.keys() and f not in fmt.fields.keys():
121
- error(lineno, 'field {0} not initialized'.format(f))
122
+ error(lineno, f'field {f} not initialized')
123
pat = Pattern(name, lineno, fmt, fixedbits, fixedmask,
124
undefmask, fieldmask, flds, width)
125
parent_pat.pats.append(pat)
126
@@ -XXX,XX +XXX,XX @@ def parse_file(f, parent_pat):
127
elif re.fullmatch(re_pat_ident, name):
128
parse_generic(start_lineno, parent_pat, name, toks)
129
else:
130
- error(lineno, 'invalid token "{0}"'.format(name))
131
+ error(lineno, f'invalid token "{name}"')
132
toks = []
133
134
if nesting != 0:
135
@@ -XXX,XX +XXX,XX @@ def output_code(self, i, extracted, outerbits, outermask):
136
137
# If we need to load more bytes to test, do so now.
138
if extracted < self.width:
139
- output(ind, 'insn = ', decode_function,
140
- '_load_bytes(ctx, insn, {0}, {1});\n'
141
- .format(extracted // 8, self.width // 8));
142
+ output(ind, f'insn = {decode_function}_load_bytes',
143
+ f'(ctx, insn, {extracted // 8}, {self.width // 8});\n')
144
extracted = self.width
145
146
# Attempt to aid the compiler in producing compact switch statements.
147
@@ -XXX,XX +XXX,XX @@ def output_code(self, i, extracted, outerbits, outermask):
148
149
# If we need to load more bytes, do so now.
150
if extracted < self.width:
151
- output(ind, 'insn = ', decode_function,
152
- '_load_bytes(ctx, insn, {0}, {1});\n'
153
- .format(extracted // 8, self.width // 8));
154
+ output(ind, f'insn = {decode_function}_load_bytes',
155
+ f'(ctx, insn, {extracted // 8}, {self.width // 8});\n')
156
extracted = self.width
157
output(ind, 'return insn;\n')
158
# end SizeLeaf
159
@@ -XXX,XX +XXX,XX @@ def build_size_tree(pats, width, outerbits, outermask):
160
for p in pats:
161
pnames.append(p.name + ':' + p.file + ':' + str(p.lineno))
162
error_with_file(pats[0].file, pats[0].lineno,
163
- 'overlapping patterns size {0}:'.format(width), pnames)
164
+ f'overlapping patterns size {width}:', pnames)
165
166
bins = {}
167
for i in pats:
45
--
168
--
46
2.25.1
169
2.25.1
47
170
48
171
diff view generated by jsdifflib
1
The union is unused; let "regs" appear in the main structure
1
From: Luis Fernando Fujita Pires <luis.pires@eldorado.org.br>
2
without the "u.regs" wrapping.
2
3
Allow '64' to be specified for the instruction width command line params
4
and use the appropriate extract and deposit functions in that case.
5
6
This will be used to implement the new 64-bit Power ISA 3.1 instructions.
3
7
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Luis Pires <luis.pires@eldorado.org.br>
10
Message-Id: <CP2PR80MB3668E123E2EFDB0ACD3A46F1DA759@CP2PR80MB3668.lamprd80.prod.outlook.com>
11
[rth: Drop the change to the field type; use bitop_width instead of separate
12
variables for extract/deposit; use "ull" for 64-bit constants.]
13
Reviewed-by: Luis Pires <luis.pires@eldorado.org.br>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
15
---
7
include/tcg/tcg.h | 4 +---
16
scripts/decodetree.py | 21 ++++++++++++++-------
8
tcg/tcg.c | 22 +++++++++++-----------
17
1 file changed, 14 insertions(+), 7 deletions(-)
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
18
20
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
19
diff --git a/scripts/decodetree.py b/scripts/decodetree.py
21
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
22
--- a/include/tcg/tcg.h
21
--- a/scripts/decodetree.py
23
+++ b/include/tcg/tcg.h
22
+++ b/scripts/decodetree.py
24
@@ -XXX,XX +XXX,XX @@ void tcg_dump_op_count(void);
23
@@ -XXX,XX +XXX,XX @@
25
typedef struct TCGArgConstraint {
24
import getopt
26
uint16_t ct;
25
27
uint8_t alias_index;
26
insnwidth = 32
28
- union {
27
+bitop_width = 32
29
- TCGRegSet regs;
28
insnmask = 0xffffffff
30
- } u;
29
variablewidth = False
31
+ TCGRegSet regs;
30
fields = {}
32
} TCGArgConstraint;
31
@@ -XXX,XX +XXX,XX @@ def whexC(val):
33
32
"""Return a hex string for val padded for insnwidth,
34
#define TCG_MAX_OP_ARGS 16
33
and with the proper suffix for a C constant."""
35
diff --git a/tcg/tcg.c b/tcg/tcg.c
34
suffix = ''
36
index XXXXXXX..XXXXXXX 100644
35
- if val >= 0x80000000:
37
--- a/tcg/tcg.c
36
+ if val >= 0x100000000:
38
+++ b/tcg/tcg.c
37
+ suffix = 'ull'
39
@@ -XXX,XX +XXX,XX @@ static int get_constraint_priority(const TCGOpDef *def, int k)
38
+ elif val >= 0x80000000:
40
return 0;
39
suffix = 'u'
41
n = 0;
40
return whex(val) + suffix
42
for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
41
43
- if (tcg_regset_test_reg(arg_ct->u.regs, i))
42
@@ -XXX,XX +XXX,XX @@ def __str__(self):
44
+ if (tcg_regset_test_reg(arg_ct->regs, i))
43
return str(self.pos) + ':' + s + str(self.len)
45
n++;
44
46
}
45
def str_extract(self):
47
}
46
- if self.sign:
48
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
47
- extr = 'sextract32'
49
/* Incomplete TCGTargetOpDef entry. */
48
- else:
50
tcg_debug_assert(ct_str != NULL);
49
- extr = 'extract32'
51
50
- return f'{extr}(insn, {self.pos}, {self.len})'
52
- def->args_ct[i].u.regs = 0;
51
+ global bitop_width
53
+ def->args_ct[i].regs = 0;
52
+ s = 's' if self.sign else ''
54
def->args_ct[i].ct = 0;
53
+ return f'{s}extract{bitop_width}(insn, {self.pos}, {self.len})'
55
while (*ct_str != '\0') {
54
56
switch(*ct_str) {
55
def __eq__(self, other):
57
@@ -XXX,XX +XXX,XX @@ static void liveness_pass_1(TCGContext *s)
56
return self.sign == other.sign and self.mask == other.mask
58
pset = la_temp_pref(ts);
57
@@ -XXX,XX +XXX,XX @@ def __str__(self):
59
set = *pset;
58
return str(self.subs)
60
59
61
- set &= ct->u.regs;
60
def str_extract(self):
62
+ set &= ct->regs;
61
+ global bitop_width
63
if (ct->ct & TCG_CT_IALIAS) {
62
ret = '0'
64
set &= op->output_pref[ct->alias_index];
63
pos = 0
65
}
64
for f in reversed(self.subs):
66
/* If the combination is not possible, restart. */
65
@@ -XXX,XX +XXX,XX @@ def str_extract(self):
67
if (set == 0) {
66
if pos == 0:
68
- set = ct->u.regs;
67
ret = ext
69
+ set = ct->regs;
68
else:
70
}
69
- ret = f'deposit32({ret}, {pos}, {32 - pos}, {ext})'
71
*pset = set;
70
+ ret = f'deposit{bitop_width}({ret}, {pos}, {bitop_width - pos}, {ext})'
72
}
71
pos += f.len
73
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp *op)
72
return ret
74
return;
73
75
}
74
@@ -XXX,XX +XXX,XX @@ def main():
76
75
global insntype
77
- dup_out_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[0].u.regs;
76
global insnmask
78
- dup_in_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[1].u.regs;
77
global decode_function
79
+ dup_out_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs;
78
+ global bitop_width
80
+ dup_in_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[1].regs;
79
global variablewidth
81
80
global anyextern
82
/* Allocate the output register now. */
81
83
if (ots->val_type != TEMP_VAL_REG) {
82
@@ -XXX,XX +XXX,XX @@ def main():
84
@@ -XXX,XX +XXX,XX @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
83
if insnwidth == 16:
85
}
84
insntype = 'uint16_t'
86
}
85
insnmask = 0xffff
87
86
+ elif insnwidth == 64:
88
- temp_load(s, ts, arg_ct->u.regs, i_allocated_regs, i_preferred_regs);
87
+ insntype = 'uint64_t'
89
+ temp_load(s, ts, arg_ct->regs, i_allocated_regs, i_preferred_regs);
88
+ insnmask = 0xffffffffffffffff
90
reg = ts->reg;
89
+ bitop_width = 64
91
90
elif insnwidth != 32:
92
- if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
91
error(0, 'cannot handle insns of width', insnwidth)
93
+ if (tcg_regset_test_reg(arg_ct->regs, reg)) {
92
else:
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
--
93
--
503
2.25.1
94
2.25.1
504
95
505
96
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
Deleted 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.
4
1
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
Deleted 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.
5
1
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
Deleted patch
1
The last user of this field disappeared in f69d277ece4.
2
1
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
Deleted 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.
4
1
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
1
From: Kele Huang <kele.hwang@gmail.com>
1
Rather than force all structure members to be 'int',
2
allow the type of the member to be specified.
2
3
3
Detect all MIPS store instructions in cpu_signal_handler for all available
4
Reviewed-by: Luis Pires <luis.pires@eldorado.org.br>
4
MIPS versions, and set is_write if encountering such store instructions.
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
docs/devel/decodetree.rst | 11 ++++---
16
1 file changed, 39 insertions(+), 4 deletions(-)
8
tests/decode/succ_argset_type1.decode | 1 +
9
scripts/decodetree.py | 45 +++++++++++++++++----------
10
3 files changed, 36 insertions(+), 21 deletions(-)
11
create mode 100644 tests/decode/succ_argset_type1.decode
17
12
18
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
13
diff --git a/docs/devel/decodetree.rst b/docs/devel/decodetree.rst
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/accel/tcg/user-exec.c
15
--- a/docs/devel/decodetree.rst
21
+++ b/accel/tcg/user-exec.c
16
+++ b/docs/devel/decodetree.rst
22
@@ -XXX,XX +XXX,XX @@ int cpu_signal_handler(int host_signum, void *pinfo,
17
@@ -XXX,XX +XXX,XX @@ and returns an integral value extracted from there.
23
18
24
#elif defined(__mips__)
19
A field with no ``unnamed_fields`` and no ``!function`` is in error.
25
20
26
+#if defined(__misp16) || defined(__mips_micromips)
21
-FIXME: the fields of the structure into which this result will be stored
27
+#error "Unsupported encoding"
22
-is restricted to ``int``. Which means that we cannot expand 64-bit items.
28
+#endif
23
-
24
Field examples:
25
26
+---------------------------+---------------------------------------------+
27
@@ -XXX,XX +XXX,XX @@ Argument Sets
28
Syntax::
29
30
args_def := '&' identifier ( args_elt )+ ( !extern )?
31
- args_elt := identifier
32
+ args_elt := identifier (':' identifier)?
33
34
Each *args_elt* defines an argument within the argument set.
35
+If the form of the *args_elt* contains a colon, the first
36
+identifier is the argument name and the second identifier is
37
+the argument type. If the colon is missing, the argument
38
+type will be ``int``.
29
+
39
+
30
int cpu_signal_handler(int host_signum, void *pinfo,
40
Each argument set will be rendered as a C structure "arg_$name"
31
void *puc)
41
with each of the fields being one of the member arguments.
32
{
42
33
siginfo_t *info = pinfo;
43
@@ -XXX,XX +XXX,XX @@ Argument set examples::
34
ucontext_t *uc = puc;
44
35
- greg_t pc = uc->uc_mcontext.pc;
45
&reg3 ra rb rc
36
- int is_write;
46
&loadstore reg base offset
37
+ uintptr_t pc = uc->uc_mcontext.pc;
47
+ &longldst reg base offset:int64_t
38
+ uint32_t insn = *(uint32_t *)pc;
48
39
+ int is_write = 0;
49
40
+
50
Formats
41
+ /* Detect all store instructions at program counter. */
51
diff --git a/tests/decode/succ_argset_type1.decode b/tests/decode/succ_argset_type1.decode
42
+ switch((insn >> 26) & 077) {
52
new file mode 100644
43
+ case 050: /* SB */
53
index XXXXXXX..XXXXXXX
44
+ case 051: /* SH */
54
--- /dev/null
45
+ case 052: /* SWL */
55
+++ b/tests/decode/succ_argset_type1.decode
46
+ case 053: /* SW */
56
@@ -0,0 +1 @@
47
+ case 054: /* SDL */
57
+&asdf b:bool c:uint64_t a
48
+ case 055: /* SDR */
58
diff --git a/scripts/decodetree.py b/scripts/decodetree.py
49
+ case 056: /* SWR */
59
index XXXXXXX..XXXXXXX 100644
50
+ case 070: /* SC */
60
--- a/scripts/decodetree.py
51
+ case 071: /* SWC1 */
61
+++ b/scripts/decodetree.py
52
+ case 074: /* SCD */
62
@@ -XXX,XX +XXX,XX @@ def is_contiguous(bits):
53
+ case 075: /* SDC1 */
63
return -1
54
+ case 077: /* SD */
64
55
+#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
65
56
+ case 072: /* SWC2 */
66
-def eq_fields_for_args(flds_a, flds_b):
57
+ case 076: /* SDC2 */
67
- if len(flds_a) != len(flds_b):
58
+#endif
68
+def eq_fields_for_args(flds_a, arg):
59
+ is_write = 1;
69
+ if len(flds_a) != len(arg.fields):
60
+ break;
70
return False
61
+ case 023: /* COP1X */
71
+ # Only allow inference on default types
62
+ /* Required in all versions of MIPS64 since
72
+ for t in arg.types:
63
+ MIPS64r1 and subsequent versions of MIPS32r2. */
73
+ if t != 'int':
64
+ switch (insn & 077) {
74
+ return False
65
+ case 010: /* SWXC1 */
75
for k, a in flds_a.items():
66
+ case 011: /* SDXC1 */
76
- if k not in flds_b:
67
+ case 015: /* SUXC1 */
77
+ if k not in arg.fields:
68
+ is_write = 1;
78
return False
69
+ }
79
return True
70
+ break;
80
71
+ }
81
@@ -XXX,XX +XXX,XX @@ def __ne__(self, other):
72
82
73
- /* XXX: compute is_write */
83
class Arguments:
74
- is_write = 0;
84
"""Class representing the extracted fields of a format"""
75
return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
85
- def __init__(self, nm, flds, extern):
76
}
86
+ def __init__(self, nm, flds, types, extern):
87
self.name = nm
88
self.extern = extern
89
- self.fields = sorted(flds)
90
+ self.fields = flds
91
+ self.types = types
92
93
def __str__(self):
94
return self.name + ' ' + str(self.fields)
95
@@ -XXX,XX +XXX,XX @@ def struct_name(self):
96
def output_def(self):
97
if not self.extern:
98
output('typedef struct {\n')
99
- for n in self.fields:
100
- output(' int ', n, ';\n')
101
+ for (n, t) in zip(self.fields, self.types):
102
+ output(f' {t} {n};\n')
103
output('} ', self.struct_name(), ';\n\n')
104
# end Arguments
105
106
@@ -XXX,XX +XXX,XX @@ def parse_arguments(lineno, name, toks):
107
global anyextern
108
109
flds = []
110
+ types = []
111
extern = False
112
- for t in toks:
113
- if re.fullmatch('!extern', t):
114
+ for n in toks:
115
+ if re.fullmatch('!extern', n):
116
extern = True
117
anyextern = True
118
continue
119
- if not re.fullmatch(re_C_ident, t):
120
- error(lineno, f'invalid argument set token "{t}"')
121
- if t in flds:
122
- error(lineno, f'duplicate argument "{t}"')
123
- flds.append(t)
124
+ if re.fullmatch(re_C_ident + ':' + re_C_ident, n):
125
+ (n, t) = n.split(':')
126
+ elif re.fullmatch(re_C_ident, n):
127
+ t = 'int'
128
+ else:
129
+ error(lineno, f'invalid argument set token "{n}"')
130
+ if n in flds:
131
+ error(lineno, f'duplicate argument "{n}"')
132
+ flds.append(n)
133
+ types.append(t)
134
135
if name in arguments:
136
error(lineno, 'duplicate argument set', name)
137
- arguments[name] = Arguments(name, flds, extern)
138
+ arguments[name] = Arguments(name, flds, types, extern)
139
# end parse_arguments
140
141
142
@@ -XXX,XX +XXX,XX @@ def infer_argument_set(flds):
143
global decode_function
144
145
for arg in arguments.values():
146
- if eq_fields_for_args(flds, arg.fields):
147
+ if eq_fields_for_args(flds, arg):
148
return arg
149
150
name = decode_function + str(len(arguments))
151
- arg = Arguments(name, flds.keys(), False)
152
+ arg = Arguments(name, flds.keys(), ['int'] * len(flds), False)
153
arguments[name] = arg
154
return arg
77
155
78
--
156
--
79
2.25.1
157
2.25.1
80
158
81
159
diff view generated by jsdifflib