1
The following changes since commit 3284aa128153750f14a61e8a96fd085e6f2999b6:
1
The following changes since commit 6eeea6725a70e6fcb5abba0764496bdab07ddfb3:
2
2
3
Merge remote-tracking branch 'remotes/lersek/tags/edk2-pull-2019-04-22' into staging (2019-04-24 13:19:41 +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
https://github.com/rth7680/qemu.git tags/pull-tcg-20190426
7
https://github.com/rth7680/qemu.git tags/pull-tcg-20201008
8
8
9
for you to fetch changes up to ef5dae6805cce7b59d129d801bdc5db71bcbd60d:
9
for you to fetch changes up to 62475e9d007d83db4d0a6ccebcda8914f392e9c9:
10
10
11
cputlb: Fix io_readx() to respect the access_type (2019-04-25 10:40:06 -0700)
11
accel/tcg: Fix computing of is_write for MIPS (2020-10-08 05:57:32 -0500)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Add tcg_gen_extract2_*.
14
Extend maximum gvec vector size
15
Deal with overflow of TranslationBlocks.
15
Fix i386 avx2 dupi
16
Respect access_type in io_readx.
16
Fix mips host user-only write detection
17
Misc cleanups.
17
18
18
----------------------------------------------------------------
19
----------------------------------------------------------------
19
David Hildenbrand (1):
20
Kele Huang (1):
20
tcg: Implement tcg_gen_extract2_{i32,i64}
21
accel/tcg: Fix computing of is_write for MIPS
21
22
22
Richard Henderson (13):
23
Richard Henderson (10):
23
tcg: Add INDEX_op_extract2_{i32,i64}
24
tcg: Adjust simd_desc size encoding
24
tcg: Use deposit and extract2 in tcg_gen_shifti_i64
25
tcg: Drop union from TCGArgConstraint
25
tcg: Use extract2 in tcg_gen_deposit_{i32,i64}
26
tcg: Move sorted_args into TCGArgConstraint.sort_index
26
tcg/i386: Support INDEX_op_extract2_{i32,i64}
27
tcg: Remove TCG_CT_REG
27
tcg/arm: Support INDEX_op_extract2_i32
28
tcg: Move some TCG_CT_* bits to TCGArgConstraint bitfields
28
tcg/aarch64: Support INDEX_op_extract2_{i32,i64}
29
tcg: Remove TCGOpDef.used
29
tcg: Hoist max_insns computation to tb_gen_code
30
tcg/i386: Fix dupi for avx2 32-bit hosts
30
tcg: Restart after TB code generation overflow
31
tcg: Fix generation of dupi_vec for 32-bit host
31
tcg: Restart TB generation after relocation overflow
32
tcg/optimize: Fold dup2_vec
32
tcg: Restart TB generation after constant pool overflow
33
tcg: Remove TCG_TARGET_HAS_cmp_vec
33
tcg: Restart TB generation after out-of-line ldst overflow
34
tcg/ppc: Allow the constant pool to overflow at 32k
35
tcg/arm: Restrict constant pool displacement to 12 bits
36
34
37
Shahab Vahedi (1):
35
include/tcg/tcg-gvec-desc.h | 38 ++++++++++++------
38
cputlb: Fix io_readx() to respect the access_type
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(-)
39
55
40
include/exec/exec-all.h | 4 +-
41
include/exec/translator.h | 3 +-
42
tcg/aarch64/tcg-target.h | 2 +
43
tcg/arm/tcg-target.h | 1 +
44
tcg/i386/tcg-target.h | 2 +
45
tcg/mips/tcg-target.h | 2 +
46
tcg/ppc/tcg-target.h | 2 +
47
tcg/riscv/tcg-target.h | 2 +
48
tcg/s390/tcg-target.h | 2 +
49
tcg/sparc/tcg-target.h | 2 +
50
tcg/tcg-op.h | 6 ++
51
tcg/tcg-opc.h | 2 +
52
tcg/tcg.h | 16 +++---
53
tcg/tci/tcg-target.h | 2 +
54
accel/tcg/cputlb.c | 5 +-
55
accel/tcg/translate-all.c | 53 ++++++++++++++---
56
accel/tcg/translator.c | 15 +----
57
target/alpha/translate.c | 4 +-
58
target/arm/translate.c | 4 +-
59
target/cris/translate.c | 10 +---
60
target/hppa/translate.c | 5 +-
61
target/i386/translate.c | 4 +-
62
target/lm32/translate.c | 10 +---
63
target/m68k/translate.c | 4 +-
64
target/microblaze/translate.c | 10 +---
65
target/mips/translate.c | 4 +-
66
target/moxie/translate.c | 11 +---
67
target/nios2/translate.c | 14 +----
68
target/openrisc/translate.c | 4 +-
69
target/ppc/translate.c | 4 +-
70
target/riscv/translate.c | 4 +-
71
target/s390x/translate.c | 4 +-
72
target/sh4/translate.c | 4 +-
73
target/sparc/translate.c | 4 +-
74
target/tilegx/translate.c | 12 +---
75
target/tricore/translate.c | 16 +-----
76
target/unicore32/translate.c | 10 +---
77
target/xtensa/translate.c | 4 +-
78
tcg/aarch64/tcg-target.inc.c | 27 +++++++--
79
tcg/arm/tcg-target.inc.c | 98 ++++++++++++++++++--------------
80
tcg/i386/tcg-target.inc.c | 17 +++++-
81
tcg/mips/tcg-target.inc.c | 6 +-
82
tcg/optimize.c | 16 ++++++
83
tcg/ppc/tcg-target.inc.c | 42 +++++++-------
84
tcg/riscv/tcg-target.inc.c | 16 ++++--
85
tcg/s390/tcg-target.inc.c | 20 ++++---
86
tcg/tcg-ldst.inc.c | 18 +++---
87
tcg/tcg-op.c | 129 +++++++++++++++++++++++++++++++++---------
88
tcg/tcg-pool.inc.c | 12 ++--
89
tcg/tcg.c | 85 +++++++++++++++-------------
90
tcg/README | 7 +++
91
51 files changed, 451 insertions(+), 309 deletions(-)
92
diff view generated by jsdifflib
Deleted patch
1
From: David Hildenbrand <david@redhat.com>
2
1
3
Will be helpful for s390x. Input 128 bit and output 64 bit only,
4
which is sufficient for now.
5
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: David Hildenbrand <david@redhat.com>
9
Message-Id: <20190225154204.26751-1-david@redhat.com>
10
[rth: Add matching tcg_gen_extract2_i32.]
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
13
tcg/tcg-op.h | 6 ++++++
14
tcg/tcg-op.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 50 insertions(+)
16
17
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/tcg/tcg-op.h
20
+++ b/tcg/tcg-op.h
21
@@ -XXX,XX +XXX,XX @@ void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
22
unsigned int ofs, unsigned int len);
23
void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
24
unsigned int ofs, unsigned int len);
25
+void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
26
+ unsigned int ofs);
27
void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *);
28
void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *);
29
void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
30
@@ -XXX,XX +XXX,XX @@ void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
31
unsigned int ofs, unsigned int len);
32
void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
33
unsigned int ofs, unsigned int len);
34
+void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
35
+ unsigned int ofs);
36
void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *);
37
void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *);
38
void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
39
@@ -XXX,XX +XXX,XX @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
40
#define tcg_gen_deposit_z_tl tcg_gen_deposit_z_i64
41
#define tcg_gen_extract_tl tcg_gen_extract_i64
42
#define tcg_gen_sextract_tl tcg_gen_sextract_i64
43
+#define tcg_gen_extract2_tl tcg_gen_extract2_i64
44
#define tcg_const_tl tcg_const_i64
45
#define tcg_const_local_tl tcg_const_local_i64
46
#define tcg_gen_movcond_tl tcg_gen_movcond_i64
47
@@ -XXX,XX +XXX,XX @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
48
#define tcg_gen_deposit_z_tl tcg_gen_deposit_z_i32
49
#define tcg_gen_extract_tl tcg_gen_extract_i32
50
#define tcg_gen_sextract_tl tcg_gen_sextract_i32
51
+#define tcg_gen_extract2_tl tcg_gen_extract2_i32
52
#define tcg_const_tl tcg_const_i32
53
#define tcg_const_local_tl tcg_const_local_i32
54
#define tcg_gen_movcond_tl tcg_gen_movcond_i32
55
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/tcg/tcg-op.c
58
+++ b/tcg/tcg-op.c
59
@@ -XXX,XX +XXX,XX @@ void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
60
tcg_gen_sari_i32(ret, ret, 32 - len);
61
}
62
63
+/*
64
+ * Extract 32-bits from a 64-bit input, ah:al, starting from ofs.
65
+ * Unlike tcg_gen_extract_i32 above, len is fixed at 32.
66
+ */
67
+void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
68
+ unsigned int ofs)
69
+{
70
+ tcg_debug_assert(ofs <= 32);
71
+ if (ofs == 0) {
72
+ tcg_gen_mov_i32(ret, al);
73
+ } else if (ofs == 32) {
74
+ tcg_gen_mov_i32(ret, ah);
75
+ } else if (al == ah) {
76
+ tcg_gen_rotri_i32(ret, al, ofs);
77
+ } else {
78
+ TCGv_i32 t0 = tcg_temp_new_i32();
79
+ tcg_gen_shri_i32(t0, al, ofs);
80
+ tcg_gen_deposit_i32(ret, t0, ah, 32 - ofs, ofs);
81
+ tcg_temp_free_i32(t0);
82
+ }
83
+}
84
+
85
void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
86
TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2)
87
{
88
@@ -XXX,XX +XXX,XX @@ void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
89
tcg_gen_sari_i64(ret, ret, 64 - len);
90
}
91
92
+/*
93
+ * Extract 64 bits from a 128-bit input, ah:al, starting from ofs.
94
+ * Unlike tcg_gen_extract_i64 above, len is fixed at 64.
95
+ */
96
+void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
97
+ unsigned int ofs)
98
+{
99
+ tcg_debug_assert(ofs <= 64);
100
+ if (ofs == 0) {
101
+ tcg_gen_mov_i64(ret, al);
102
+ } else if (ofs == 64) {
103
+ tcg_gen_mov_i64(ret, ah);
104
+ } else if (al == ah) {
105
+ tcg_gen_rotri_i64(ret, al, ofs);
106
+ } else {
107
+ TCGv_i64 t0 = tcg_temp_new_i64();
108
+ tcg_gen_shri_i64(t0, al, ofs);
109
+ tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs);
110
+ tcg_temp_free_i64(t0);
111
+ }
112
+}
113
+
114
void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
115
TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2)
116
{
117
--
118
2.17.1
119
120
diff view generated by jsdifflib
1
This will not necessarily restrict the size of the TB, since for v7
1
With larger vector sizes, it turns out oprsz == maxsz, and we only
2
the majority of constant pool usage is for calls from the out-of-line
2
need to represent mismatch for oprsz <= 32. We do, however, need
3
ldst code, which is already at the end of the TB. But this does
3
to represent larger oprsz and do so without reducing SIMD_DATA_BITS.
4
allow us to save one insn per reference on the off-chance.
5
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>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
12
---
8
tcg/arm/tcg-target.inc.c | 57 +++++++++++++++-------------------------
13
include/tcg/tcg-gvec-desc.h | 38 ++++++++++++++++++++++++-------------
9
1 file changed, 21 insertions(+), 36 deletions(-)
14
tcg/tcg-op-gvec.c | 35 ++++++++++++++++++++++++++--------
15
2 files changed, 52 insertions(+), 21 deletions(-)
10
16
11
diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
17
diff --git a/include/tcg/tcg-gvec-desc.h b/include/tcg/tcg-gvec-desc.h
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/tcg/arm/tcg-target.inc.c
19
--- a/include/tcg/tcg-gvec-desc.h
14
+++ b/tcg/arm/tcg-target.inc.c
20
+++ b/include/tcg/tcg-gvec-desc.h
15
@@ -XXX,XX +XXX,XX @@ static inline bool reloc_pc24(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
21
@@ -XXX,XX +XXX,XX @@
16
return false;
22
#ifndef TCG_TCG_GVEC_DESC_H
17
}
23
#define TCG_TCG_GVEC_DESC_H
18
24
19
+static inline bool reloc_pc13(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
25
-/* ??? These bit widths are set for ARM SVE, maxing out at 256 byte vectors. */
20
+{
26
-#define SIMD_OPRSZ_SHIFT 0
21
+ ptrdiff_t offset = tcg_ptr_byte_diff(target, code_ptr) - 8;
27
-#define SIMD_OPRSZ_BITS 5
22
+
28
+/*
23
+ if (offset >= -0xfff && offset <= 0xfff) {
29
+ * This configuration allows MAXSZ to represent 2048 bytes, and
24
+ tcg_insn_unit insn = *code_ptr;
30
+ * OPRSZ to match MAXSZ, or represent the smaller values 8, 16, or 32.
25
+ bool u = (offset >= 0);
31
+ *
26
+ if (!u) {
32
+ * Encode this with:
27
+ offset = -offset;
33
+ * 0, 1, 3 -> 8, 16, 32
28
+ }
34
+ * 2 -> maxsz
29
+ insn = deposit32(insn, 23, 1, u);
35
+ *
30
+ insn = deposit32(insn, 0, 12, offset);
36
+ * This steals the input that would otherwise map to 24 to match maxsz.
31
+ *code_ptr = insn;
37
+ */
32
+ return true;
38
+#define SIMD_MAXSZ_SHIFT 0
33
+ }
39
+#define SIMD_MAXSZ_BITS 8
34
+ return false;
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;
35
+}
64
+}
36
+
65
+
37
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
66
+/* Extract the operation size from a descriptor. */
38
intptr_t value, intptr_t addend)
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)
39
{
83
{
40
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
84
- uint32_t opr_align = oprsz >= 16 ? 15 : 7;
41
if (type == R_ARM_PC24) {
85
- uint32_t max_align = maxsz >= 16 || oprsz >= 16 ? 15 : 7;
42
return reloc_pc24(code_ptr, (tcg_insn_unit *)value);
86
- tcg_debug_assert(oprsz > 0);
43
} else if (type == R_ARM_PC13) {
87
- tcg_debug_assert(oprsz <= maxsz);
44
- intptr_t diff = value - (uintptr_t)(code_ptr + 2);
88
- tcg_debug_assert((oprsz & opr_align) == 0);
45
- tcg_insn_unit insn = *code_ptr;
89
+ uint32_t max_align;
46
- bool u;
90
+
47
-
91
+ switch (oprsz) {
48
- if (diff >= -0xfff && diff <= 0xfff) {
92
+ case 8:
49
- u = (diff >= 0);
93
+ case 16:
50
- if (!u) {
94
+ case 32:
51
- diff = -diff;
95
+ tcg_debug_assert(oprsz <= maxsz);
52
- }
96
+ break;
53
- } else {
97
+ default:
54
- int rd = extract32(insn, 12, 4);
98
+ tcg_debug_assert(oprsz == maxsz);
55
- int rt = rd == TCG_REG_PC ? TCG_REG_TMP : rd;
99
+ break;
56
-
100
+ }
57
- if (diff < 0x1000 || diff >= 0x100000) {
101
+ tcg_debug_assert(maxsz <= (8 << SIMD_MAXSZ_BITS));
58
- return false;
102
+
59
- }
103
+ max_align = maxsz >= 16 ? 15 : 7;
60
-
104
tcg_debug_assert((maxsz & max_align) == 0);
61
- /* add rt, pc, #high */
105
tcg_debug_assert((ofs & max_align) == 0);
62
- *code_ptr++ = ((insn & 0xf0000000) | (1 << 25) | ARITH_ADD
63
- | (TCG_REG_PC << 16) | (rt << 12)
64
- | (20 << 7) | (diff >> 12));
65
- /* ldr rd, [rt, #low] */
66
- insn = deposit32(insn, 12, 4, rt);
67
- diff &= 0xfff;
68
- u = 1;
69
- }
70
- insn = deposit32(insn, 23, 1, u);
71
- insn = deposit32(insn, 0, 12, diff);
72
- *code_ptr = insn;
73
+ return reloc_pc13(code_ptr, (tcg_insn_unit *)value);
74
} else {
75
g_assert_not_reached();
76
}
77
- return true;
78
}
106
}
79
107
@@ -XXX,XX +XXX,XX @@ uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t data)
80
#define TCG_CT_CONST_ARM 0x100
81
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_ld8s_r(TCGContext *s, int cond, TCGReg rt,
82
83
static void tcg_out_movi_pool(TCGContext *s, int cond, int rd, uint32_t arg)
84
{
108
{
85
- /* The 12-bit range on the ldr insn is sometimes a bit too small.
109
uint32_t desc = 0;
86
- In order to get around that we require two insns, one of which
110
87
- will usually be a nop, but may be replaced in patch_reloc. */
111
- assert(oprsz % 8 == 0 && oprsz <= (8 << SIMD_OPRSZ_BITS));
88
new_pool_label(s, arg, R_ARM_PC13, s->code_ptr, 0);
112
- assert(maxsz % 8 == 0 && maxsz <= (8 << SIMD_MAXSZ_BITS));
89
tcg_out_ld32_12(s, cond, rd, TCG_REG_PC, 0);
113
- assert(data == sextract32(data, 0, SIMD_DATA_BITS));
90
- tcg_out_nop(s);
114
+ check_size_align(oprsz, maxsz, 0);
91
}
115
+ tcg_debug_assert(data == sextract32(data, 0, SIMD_DATA_BITS));
92
116
93
static void tcg_out_movi32(TCGContext *s, int cond, int rd, uint32_t arg)
117
oprsz = (oprsz / 8) - 1;
94
@@ -XXX,XX +XXX,XX @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit *addr)
118
maxsz = (maxsz / 8) - 1;
95
tcg_out_movi32(s, COND_AL, TCG_REG_TMP, addri);
119
+
96
tcg_out_blx(s, COND_AL, TCG_REG_TMP);
120
+ /*
97
} else {
121
+ * We have just asserted in check_size_align that either
98
- /* ??? Know that movi_pool emits exactly 2 insns. */
122
+ * oprsz is {8,16,32} or matches maxsz. Encode the final
99
- tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R14, TCG_REG_PC, 4);
123
+ * case with '2', as that would otherwise map to 24.
100
+ /* ??? Know that movi_pool emits exactly 1 insn. */
124
+ */
101
+ tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R14, TCG_REG_PC, 0);
125
+ if (oprsz == maxsz) {
102
tcg_out_movi_pool(s, COND_AL, TCG_REG_PC, addri);
126
+ oprsz = 2;
103
}
127
+ }
104
}
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);
105
--
132
--
106
2.17.1
133
2.25.1
107
134
108
135
diff view generated by jsdifflib
1
If a TB generates too much code, try again with fewer insns.
1
The union is unused; let "regs" appear in the main structure
2
without the "u.regs" wrapping.
2
3
3
Fixes: https://bugs.launchpad.net/bugs/1824853
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
6
---
7
accel/tcg/translate-all.c | 38 ++++++++++++++++++++++++++++++++------
7
include/tcg/tcg.h | 4 +---
8
tcg/tcg.c | 4 ++++
8
tcg/tcg.c | 22 +++++++++++-----------
9
2 files changed, 36 insertions(+), 6 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(-)
10
19
11
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
20
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/translate-all.c
22
--- a/include/tcg/tcg.h
14
+++ b/accel/tcg/translate-all.c
23
+++ b/include/tcg/tcg.h
15
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
24
@@ -XXX,XX +XXX,XX @@ void tcg_dump_op_count(void);
16
tb->cflags = cflags;
25
typedef struct TCGArgConstraint {
17
tb->trace_vcpu_dstate = *cpu->trace_dstate;
26
uint16_t ct;
18
tcg_ctx->tb_cflags = cflags;
27
uint8_t alias_index;
19
+ tb_overflow:
28
- union {
20
29
- TCGRegSet regs;
21
#ifdef CONFIG_PROFILER
30
- } u;
22
/* includes aborted translations because of exceptions */
31
+ TCGRegSet regs;
23
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
32
} TCGArgConstraint;
24
ti = profile_getclock();
33
25
#endif
34
#define TCG_MAX_OP_ARGS 16
26
27
- /* ??? Overflow could be handled better here. In particular, we
28
- don't need to re-do gen_intermediate_code, nor should we re-do
29
- the tcg optimization currently hidden inside tcg_gen_code. All
30
- that should be required is to flush the TBs, allocate a new TB,
31
- re-initialize it per above, and re-do the actual code generation. */
32
gen_code_size = tcg_gen_code(tcg_ctx, tb);
33
if (unlikely(gen_code_size < 0)) {
34
- goto buffer_overflow;
35
+ switch (gen_code_size) {
36
+ case -1:
37
+ /*
38
+ * Overflow of code_gen_buffer, or the current slice of it.
39
+ *
40
+ * TODO: We don't need to re-do gen_intermediate_code, nor
41
+ * should we re-do the tcg optimization currently hidden
42
+ * inside tcg_gen_code. All that should be required is to
43
+ * flush the TBs, allocate a new TB, re-initialize it per
44
+ * above, and re-do the actual code generation.
45
+ */
46
+ goto buffer_overflow;
47
+
48
+ case -2:
49
+ /*
50
+ * The code generated for the TranslationBlock is too large.
51
+ * The maximum size allowed by the unwind info is 64k.
52
+ * There may be stricter constraints from relocations
53
+ * in the tcg backend.
54
+ *
55
+ * Try again with half as many insns as we attempted this time.
56
+ * If a single insn overflows, there's a bug somewhere...
57
+ */
58
+ max_insns = tb->icount;
59
+ assert(max_insns > 1);
60
+ max_insns /= 2;
61
+ goto tb_overflow;
62
+
63
+ default:
64
+ g_assert_not_reached();
65
+ }
66
}
67
search_size = encode_search(tb, (void *)gen_code_buf + gen_code_size);
68
if (unlikely(search_size < 0)) {
69
diff --git a/tcg/tcg.c b/tcg/tcg.c
35
diff --git a/tcg/tcg.c b/tcg/tcg.c
70
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
71
--- a/tcg/tcg.c
37
--- a/tcg/tcg.c
72
+++ b/tcg/tcg.c
38
+++ b/tcg/tcg.c
73
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
39
@@ -XXX,XX +XXX,XX @@ static int get_constraint_priority(const TCGOpDef *def, int k)
74
if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
40
return 0;
75
return -1;
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++;
76
}
46
}
77
+ /* Test for TB overflow, as seen by gen_insn_end_off. */
78
+ if (unlikely(tcg_current_code_size(s) > UINT16_MAX)) {
79
+ return -2;
80
+ }
81
}
47
}
82
tcg_debug_assert(num_insns >= 0);
48
@@ -XXX,XX +XXX,XX @@ static void process_op_defs(TCGContext *s)
83
s->gen_insn_end_off[num_insns] = tcg_current_code_size(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;
84
--
502
--
85
2.17.1
503
2.25.1
86
504
87
505
diff view generated by jsdifflib
1
This is part c of relocation overflow handling.
1
This uses an existing hole in the TCGArgConstraint structure
2
and will be convenient for keeping the data in one place.
2
3
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
5
---
5
tcg/aarch64/tcg-target.inc.c | 16 ++++++++++------
6
include/tcg/tcg.h | 2 +-
6
tcg/arm/tcg-target.inc.c | 16 ++++++++++------
7
tcg/tcg.c | 35 +++++++++++++++++------------------
7
tcg/i386/tcg-target.inc.c | 6 ++++--
8
2 files changed, 18 insertions(+), 19 deletions(-)
8
tcg/mips/tcg-target.inc.c | 6 ++++--
9
tcg/ppc/tcg-target.inc.c | 14 ++++++++++----
10
tcg/riscv/tcg-target.inc.c | 16 ++++++++++++----
11
tcg/s390/tcg-target.inc.c | 20 ++++++++++++--------
12
tcg/tcg-ldst.inc.c | 18 +++++++++---------
13
tcg/tcg.c | 7 ++++---
14
9 files changed, 75 insertions(+), 44 deletions(-)
15
9
16
diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
10
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/tcg/aarch64/tcg-target.inc.c
12
--- a/include/tcg/tcg.h
19
+++ b/tcg/aarch64/tcg-target.inc.c
13
+++ b/include/tcg/tcg.h
20
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_adr(TCGContext *s, TCGReg rd, void *target)
14
@@ -XXX,XX +XXX,XX @@ void tcg_dump_op_count(void);
21
tcg_out_insn(s, 3406, ADR, rd, offset);
15
typedef struct TCGArgConstraint {
22
}
16
uint16_t ct;
23
17
uint8_t alias_index;
24
-static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
18
+ uint8_t sort_index;
25
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
19
TCGRegSet regs;
26
{
20
} TCGArgConstraint;
27
TCGMemOpIdx oi = lb->oi;
21
28
TCGMemOp opc = get_memop(oi);
22
@@ -XXX,XX +XXX,XX @@ typedef struct TCGOpDef {
29
TCGMemOp size = opc & MO_SIZE;
23
uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
30
24
uint8_t flags;
31
- bool ok = reloc_pc19(lb->label_ptr[0], s->code_ptr);
25
TCGArgConstraint *args_ct;
32
- tcg_debug_assert(ok);
26
- int *sorted_args;
33
+ if (!reloc_pc19(lb->label_ptr[0], s->code_ptr)) {
27
#if defined(CONFIG_DEBUG_TCG)
34
+ return false;
28
int used;
35
+ }
36
37
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0);
38
tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X1, lb->addrlo_reg);
39
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
40
}
41
42
tcg_out_goto(s, lb->raddr);
43
+ return true;
44
}
45
46
-static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
47
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
48
{
49
TCGMemOpIdx oi = lb->oi;
50
TCGMemOp opc = get_memop(oi);
51
TCGMemOp size = opc & MO_SIZE;
52
53
- bool ok = reloc_pc19(lb->label_ptr[0], s->code_ptr);
54
- tcg_debug_assert(ok);
55
+ if (!reloc_pc19(lb->label_ptr[0], s->code_ptr)) {
56
+ return false;
57
+ }
58
59
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0);
60
tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X1, lb->addrlo_reg);
61
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
62
tcg_out_adr(s, TCG_REG_X4, lb->raddr);
63
tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
64
tcg_out_goto(s, lb->raddr);
65
+ return true;
66
}
67
68
static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
69
diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/tcg/arm/tcg-target.inc.c
72
+++ b/tcg/arm/tcg-target.inc.c
73
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
74
label->label_ptr[0] = label_ptr;
75
}
76
77
-static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
78
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
79
{
80
TCGReg argreg, datalo, datahi;
81
TCGMemOpIdx oi = lb->oi;
82
TCGMemOp opc = get_memop(oi);
83
void *func;
84
85
- bool ok = reloc_pc24(lb->label_ptr[0], s->code_ptr);
86
- tcg_debug_assert(ok);
87
+ if (!reloc_pc24(lb->label_ptr[0], s->code_ptr)) {
88
+ return false;
89
+ }
90
91
argreg = tcg_out_arg_reg32(s, TCG_REG_R0, TCG_AREG0);
92
if (TARGET_LONG_BITS == 64) {
93
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
94
}
95
96
tcg_out_goto(s, COND_AL, lb->raddr);
97
+ return true;
98
}
99
100
-static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
101
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
102
{
103
TCGReg argreg, datalo, datahi;
104
TCGMemOpIdx oi = lb->oi;
105
TCGMemOp opc = get_memop(oi);
106
107
- bool ok = reloc_pc24(lb->label_ptr[0], s->code_ptr);
108
- tcg_debug_assert(ok);
109
+ if (!reloc_pc24(lb->label_ptr[0], s->code_ptr)) {
110
+ return false;
111
+ }
112
113
argreg = TCG_REG_R0;
114
argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
115
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
116
117
/* Tail-call to the helper, which will return to the fast path. */
118
tcg_out_goto(s, COND_AL, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
119
+ return true;
120
}
121
#endif /* SOFTMMU */
122
123
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/tcg/i386/tcg-target.inc.c
126
+++ b/tcg/i386/tcg-target.inc.c
127
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, bool is_64,
128
/*
129
* Generate code for the slow path for a load at the end of block
130
*/
131
-static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
132
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
133
{
134
TCGMemOpIdx oi = l->oi;
135
TCGMemOp opc = get_memop(oi);
136
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
137
138
/* Jump to the code corresponding to next IR of qemu_st */
139
tcg_out_jmp(s, l->raddr);
140
+ return true;
141
}
142
143
/*
144
* Generate code for the slow path for a store at the end of block
145
*/
146
-static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
147
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
148
{
149
TCGMemOpIdx oi = l->oi;
150
TCGMemOp opc = get_memop(oi);
151
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
152
/* "Tail call" to the helper, with the return address back inline. */
153
tcg_out_push(s, retaddr);
154
tcg_out_jmp(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
155
+ return true;
156
}
157
#elif TCG_TARGET_REG_BITS == 32
158
# define x86_guest_base_seg 0
159
diff --git a/tcg/mips/tcg-target.inc.c b/tcg/mips/tcg-target.inc.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/tcg/mips/tcg-target.inc.c
162
+++ b/tcg/mips/tcg-target.inc.c
163
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
164
}
165
}
166
167
-static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
168
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
169
{
170
TCGMemOpIdx oi = l->oi;
171
TCGMemOp opc = get_memop(oi);
172
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
173
} else {
174
tcg_out_opc_reg(s, OPC_OR, v0, TCG_REG_V0, TCG_REG_ZERO);
175
}
176
+ return true;
177
}
178
179
-static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
180
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
181
{
182
TCGMemOpIdx oi = l->oi;
183
TCGMemOp opc = get_memop(oi);
184
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
185
tcg_out_call_int(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)], true);
186
/* delay slot */
187
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
188
+ return true;
189
}
190
#endif
29
#endif
191
192
diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/tcg/ppc/tcg-target.inc.c
195
+++ b/tcg/ppc/tcg-target.inc.c
196
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
197
label->label_ptr[0] = lptr;
198
}
199
200
-static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
201
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
202
{
203
TCGMemOpIdx oi = lb->oi;
204
TCGMemOp opc = get_memop(oi);
205
TCGReg hi, lo, arg = TCG_REG_R3;
206
207
- **lb->label_ptr |= reloc_pc14_val(*lb->label_ptr, s->code_ptr);
208
+ if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
209
+ return false;
210
+ }
211
212
tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
213
214
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
215
}
216
217
tcg_out_b(s, 0, lb->raddr);
218
+ return true;
219
}
220
221
-static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
222
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
223
{
224
TCGMemOpIdx oi = lb->oi;
225
TCGMemOp opc = get_memop(oi);
226
TCGMemOp s_bits = opc & MO_SIZE;
227
TCGReg hi, lo, arg = TCG_REG_R3;
228
229
- **lb->label_ptr |= reloc_pc14_val(*lb->label_ptr, s->code_ptr);
230
+ if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
231
+ return false;
232
+ }
233
234
tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
235
236
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
237
tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
238
239
tcg_out_b(s, 0, lb->raddr);
240
+ return true;
241
}
242
#endif /* SOFTMMU */
243
244
diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
245
index XXXXXXX..XXXXXXX 100644
246
--- a/tcg/riscv/tcg-target.inc.c
247
+++ b/tcg/riscv/tcg-target.inc.c
248
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
249
label->label_ptr[0] = label_ptr[0];
250
}
251
252
-static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
253
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
254
{
255
TCGMemOpIdx oi = l->oi;
256
TCGMemOp opc = get_memop(oi);
257
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
258
}
259
260
/* resolve label address */
261
- patch_reloc(l->label_ptr[0], R_RISCV_BRANCH, (intptr_t) s->code_ptr, 0);
262
+ if (!patch_reloc(l->label_ptr[0], R_RISCV_BRANCH,
263
+ (intptr_t) s->code_ptr, 0)) {
264
+ return false;
265
+ }
266
267
/* call load helper */
268
tcg_out_mov(s, TCG_TYPE_PTR, a0, TCG_AREG0);
269
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
270
tcg_out_mov(s, (opc & MO_SIZE) == MO_64, l->datalo_reg, a0);
271
272
tcg_out_goto(s, l->raddr);
273
+ return true;
274
}
275
276
-static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
277
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
278
{
279
TCGMemOpIdx oi = l->oi;
280
TCGMemOp opc = get_memop(oi);
281
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
282
}
283
284
/* resolve label address */
285
- patch_reloc(l->label_ptr[0], R_RISCV_BRANCH, (intptr_t) s->code_ptr, 0);
286
+ if (!patch_reloc(l->label_ptr[0], R_RISCV_BRANCH,
287
+ (intptr_t) s->code_ptr, 0)) {
288
+ return false;
289
+ }
290
291
/* call store helper */
292
tcg_out_mov(s, TCG_TYPE_PTR, a0, TCG_AREG0);
293
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
294
tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SSIZE)]);
295
296
tcg_out_goto(s, l->raddr);
297
+ return true;
298
}
299
#endif /* CONFIG_SOFTMMU */
300
301
diff --git a/tcg/s390/tcg-target.inc.c b/tcg/s390/tcg-target.inc.c
302
index XXXXXXX..XXXXXXX 100644
303
--- a/tcg/s390/tcg-target.inc.c
304
+++ b/tcg/s390/tcg-target.inc.c
305
@@ -XXX,XX +XXX,XX @@ static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
306
label->label_ptr[0] = label_ptr;
307
}
308
309
-static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
310
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
311
{
312
TCGReg addr_reg = lb->addrlo_reg;
313
TCGReg data_reg = lb->datalo_reg;
314
TCGMemOpIdx oi = lb->oi;
315
TCGMemOp opc = get_memop(oi);
316
317
- bool ok = patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
318
- (intptr_t)s->code_ptr, 2);
319
- tcg_debug_assert(ok);
320
+ if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
321
+ (intptr_t)s->code_ptr, 2)) {
322
+ return false;
323
+ }
324
325
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
326
if (TARGET_LONG_BITS == 64) {
327
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
328
tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_R2);
329
330
tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
331
+ return true;
332
}
333
334
-static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
335
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
336
{
337
TCGReg addr_reg = lb->addrlo_reg;
338
TCGReg data_reg = lb->datalo_reg;
339
TCGMemOpIdx oi = lb->oi;
340
TCGMemOp opc = get_memop(oi);
341
342
- bool ok = patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
343
- (intptr_t)s->code_ptr, 2);
344
- tcg_debug_assert(ok);
345
+ if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
346
+ (intptr_t)s->code_ptr, 2)) {
347
+ return false;
348
+ }
349
350
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
351
if (TARGET_LONG_BITS == 64) {
352
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
353
tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
354
355
tgen_gotoi(s, S390_CC_ALWAYS, lb->raddr);
356
+ return true;
357
}
358
#else
359
static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
360
diff --git a/tcg/tcg-ldst.inc.c b/tcg/tcg-ldst.inc.c
361
index XXXXXXX..XXXXXXX 100644
362
--- a/tcg/tcg-ldst.inc.c
363
+++ b/tcg/tcg-ldst.inc.c
364
@@ -XXX,XX +XXX,XX @@ typedef struct TCGLabelQemuLdst {
365
* Generate TB finalization at the end of block
366
*/
367
368
-static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l);
369
-static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l);
370
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l);
371
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l);
372
373
-static bool tcg_out_ldst_finalize(TCGContext *s)
374
+static int tcg_out_ldst_finalize(TCGContext *s)
375
{
376
TCGLabelQemuLdst *lb;
377
378
/* qemu_ld/st slow paths */
379
QSIMPLEQ_FOREACH(lb, &s->ldst_labels, next) {
380
- if (lb->is_ld) {
381
- tcg_out_qemu_ld_slow_path(s, lb);
382
- } else {
383
- tcg_out_qemu_st_slow_path(s, lb);
384
+ if (lb->is_ld
385
+ ? !tcg_out_qemu_ld_slow_path(s, lb)
386
+ : !tcg_out_qemu_st_slow_path(s, lb)) {
387
+ return -2;
388
}
389
390
/* Test for (pending) buffer overflow. The assumption is that any
391
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_ldst_finalize(TCGContext *s)
392
the buffer completely. Thus we can test for overflow after
393
generating code without having to check during generation. */
394
if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
395
- return false;
396
+ return -1;
397
}
398
}
399
- return true;
400
+ return 0;
401
}
402
403
/*
404
diff --git a/tcg/tcg.c b/tcg/tcg.c
30
diff --git a/tcg/tcg.c b/tcg/tcg.c
405
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
406
--- a/tcg/tcg.c
32
--- a/tcg/tcg.c
407
+++ b/tcg/tcg.c
33
+++ b/tcg/tcg.c
408
@@ -XXX,XX +XXX,XX @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit *target);
34
@@ -XXX,XX +XXX,XX @@ void tcg_context_init(TCGContext *s)
409
static int tcg_target_const_match(tcg_target_long val, TCGType type,
35
int op, total_args, n, i;
410
const TCGArgConstraint *arg_ct);
36
TCGOpDef *def;
411
#ifdef TCG_TARGET_NEED_LDST_LABELS
37
TCGArgConstraint *args_ct;
412
-static bool tcg_out_ldst_finalize(TCGContext *s);
38
- int *sorted_args;
413
+static int tcg_out_ldst_finalize(TCGContext *s);
39
TCGTemp *ts;
414
#endif
40
415
41
memset(s, 0, sizeof(*s));
416
#define TCG_HIGHWATER 1024
42
@@ -XXX,XX +XXX,XX @@ void tcg_context_init(TCGContext *s)
417
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
418
419
/* Generate TB finalization at the end of block */
420
#ifdef TCG_TARGET_NEED_LDST_LABELS
421
- if (!tcg_out_ldst_finalize(s)) {
422
- return -1;
423
+ i = tcg_out_ldst_finalize(s);
424
+ if (i < 0) {
425
+ return i;
426
}
43
}
427
#endif
44
428
#ifdef TCG_TARGET_NEED_POOL_LABELS
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);
429
--
119
--
430
2.17.1
120
2.25.1
431
121
432
122
diff view generated by jsdifflib
1
This is part b of relocation overflow handling.
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.
2
4
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
---
6
---
5
tcg/tcg-pool.inc.c | 12 +++++++-----
7
include/tcg/tcg.h | 1 -
6
tcg/tcg.c | 9 +++++----
8
tcg/tcg.c | 15 ++++-----------
7
2 files changed, 12 insertions(+), 9 deletions(-)
9
tcg/aarch64/tcg-target.c.inc | 3 ---
10
tcg/arm/tcg-target.c.inc | 3 ---
11
tcg/i386/tcg-target.c.inc | 11 -----------
12
tcg/mips/tcg-target.c.inc | 3 ---
13
tcg/ppc/tcg-target.c.inc | 5 -----
14
tcg/riscv/tcg-target.c.inc | 2 --
15
tcg/s390/tcg-target.c.inc | 4 ----
16
tcg/sparc/tcg-target.c.inc | 5 -----
17
tcg/tci/tcg-target.c.inc | 1 -
18
11 files changed, 4 insertions(+), 49 deletions(-)
8
19
9
diff --git a/tcg/tcg-pool.inc.c b/tcg/tcg-pool.inc.c
20
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
10
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
11
--- a/tcg/tcg-pool.inc.c
22
--- a/include/tcg/tcg.h
12
+++ b/tcg/tcg-pool.inc.c
23
+++ b/include/tcg/tcg.h
13
@@ -XXX,XX +XXX,XX @@ static inline void new_pool_l8(TCGContext *s, int rtype, tcg_insn_unit *label,
24
@@ -XXX,XX +XXX,XX @@ void tcg_dump_op_count(void);
14
/* To be provided by cpu/tcg-target.inc.c. */
25
#define TCG_CT_ALIAS 0x80
15
static void tcg_out_nop_fill(tcg_insn_unit *p, int count);
26
#define TCG_CT_IALIAS 0x40
16
27
#define TCG_CT_NEWREG 0x20 /* output requires a new register */
17
-static bool tcg_out_pool_finalize(TCGContext *s)
28
-#define TCG_CT_REG 0x01
18
+static int tcg_out_pool_finalize(TCGContext *s)
29
#define TCG_CT_CONST 0x02 /* any constant of register size */
19
{
30
20
TCGLabelPoolData *p = s->pool_labels;
31
typedef struct TCGArgConstraint {
21
TCGLabelPoolData *l = NULL;
22
void *a;
23
24
if (p == NULL) {
25
- return true;
26
+ return 0;
27
}
28
29
/* ??? Round up to qemu_icache_linesize, but then do not round
30
@@ -XXX,XX +XXX,XX @@ static bool tcg_out_pool_finalize(TCGContext *s)
31
size_t size = sizeof(tcg_target_ulong) * p->nlong;
32
if (!l || l->nlong != p->nlong || memcmp(l->data, p->data, size)) {
33
if (unlikely(a > s->code_gen_highwater)) {
34
- return false;
35
+ return -1;
36
}
37
memcpy(a, p->data, size);
38
a += size;
39
l = p;
40
}
41
- patch_reloc(p->label, p->rtype, (intptr_t)a - size, p->addend);
42
+ if (!patch_reloc(p->label, p->rtype, (intptr_t)a - size, p->addend)) {
43
+ return -2;
44
+ }
45
}
46
47
s->code_ptr = a;
48
- return true;
49
+ return 0;
50
}
51
diff --git a/tcg/tcg.c b/tcg/tcg.c
32
diff --git a/tcg/tcg.c b/tcg/tcg.c
52
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
53
--- a/tcg/tcg.c
34
--- a/tcg/tcg.c
54
+++ b/tcg/tcg.c
35
+++ b/tcg/tcg.c
55
@@ -XXX,XX +XXX,XX @@ void tcg_prologue_init(TCGContext *s)
36
@@ -XXX,XX +XXX,XX @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs)
56
#ifdef TCG_TARGET_NEED_POOL_LABELS
37
/* we give more priority to constraints with less registers */
57
/* Allow the prologue to put e.g. guest_base into a pool entry. */
38
static int get_constraint_priority(const TCGOpDef *def, int k)
58
{
39
{
59
- bool ok = tcg_out_pool_finalize(s);
40
- const TCGArgConstraint *arg_ct;
60
- tcg_debug_assert(ok);
41
+ const TCGArgConstraint *arg_ct = &def->args_ct[k];
61
+ int result = tcg_out_pool_finalize(s);
42
+ int n;
62
+ tcg_debug_assert(result == 0);
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);
63
}
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,
64
#endif
194
#endif
65
195
break;
66
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
196
case 'S': /* qemu_st constraint */
67
}
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,
68
#endif
226
#endif
69
#ifdef TCG_TARGET_NEED_POOL_LABELS
227
break;
70
- if (!tcg_out_pool_finalize(s)) {
228
case 'S': /* qemu_st constraint */
71
- return -1;
229
- ct->ct |= TCG_CT_REG;
72
+ i = tcg_out_pool_finalize(s);
230
ct->regs = 0xffffffff;
73
+ if (i < 0) {
231
tcg_regset_reset_reg(ct->regs, TCG_REG_R3);
74
+ return i;
232
#ifdef CONFIG_SOFTMMU
75
}
233
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
76
#endif
234
index XXXXXXX..XXXXXXX 100644
77
if (!tcg_resolve_relocs(s)) {
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:
78
--
322
--
79
2.17.1
323
2.25.1
80
324
81
325
diff view generated by jsdifflib
1
If the TB generates too much code, such that backend relocations
1
These are easier to set and test when they have their own fields.
2
overflow, try again with a smaller TB. In support of this, move
2
Reduce the size of alias_index and sort_index to 4 bits, which is
3
relocation processing from a random place within tcg_out_op, in
3
sufficient for TCG_MAX_OP_ARGS. This leaves only the bits indicating
4
the handling of branch opcodes, to a new function at the end of
4
constants within the ct field.
5
tcg_gen_code.
6
5
7
This is not a complete solution, as there are additional relocs
6
Move all initialization to allocation time, rather than init
8
generated for out-of-line ldst handling and constant pools.
7
individual fields in process_op_defs.
9
8
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
10
---
12
tcg/tcg.h | 15 +++++++-------
11
include/tcg/tcg.h | 14 +++++++-------
13
tcg/tcg.c | 61 ++++++++++++++++++++++++++-----------------------------
12
tcg/tcg.c | 28 ++++++++++++----------------
14
2 files changed, 36 insertions(+), 40 deletions(-)
13
2 files changed, 19 insertions(+), 23 deletions(-)
15
14
16
diff --git a/tcg/tcg.h b/tcg/tcg.h
15
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/tcg/tcg.h
17
--- a/include/tcg/tcg.h
19
+++ b/tcg/tcg.h
18
+++ b/include/tcg/tcg.h
20
@@ -XXX,XX +XXX,XX @@ typedef uint64_t tcg_insn_unit;
19
@@ -XXX,XX +XXX,XX @@ int64_t tcg_cpu_exec_time(void);
21
do { if (!(X)) { __builtin_unreachable(); } } while (0)
20
void tcg_dump_info(void);
22
#endif
21
void tcg_dump_op_count(void);
23
22
24
-typedef struct TCGRelocation {
23
-#define TCG_CT_ALIAS 0x80
25
- struct TCGRelocation *next;
24
-#define TCG_CT_IALIAS 0x40
26
- int type;
25
-#define TCG_CT_NEWREG 0x20 /* output requires a new register */
27
+typedef struct TCGRelocation TCGRelocation;
26
-#define TCG_CT_CONST 0x02 /* any constant of register size */
28
+struct TCGRelocation {
27
+#define TCG_CT_CONST 1 /* any constant of register size */
29
+ QSIMPLEQ_ENTRY(TCGRelocation) next;
28
30
tcg_insn_unit *ptr;
29
typedef struct TCGArgConstraint {
31
intptr_t addend;
30
- uint16_t ct;
32
-} TCGRelocation;
31
- uint8_t alias_index;
33
+ int type;
32
- uint8_t sort_index;
34
+};
33
+ unsigned ct : 16;
35
34
+ unsigned alias_index : 4;
36
typedef struct TCGLabel TCGLabel;
35
+ unsigned sort_index : 4;
37
struct TCGLabel {
36
+ bool oalias : 1;
38
@@ -XXX,XX +XXX,XX @@ struct TCGLabel {
37
+ bool ialias : 1;
39
union {
38
+ bool newreg : 1;
40
uintptr_t value;
39
TCGRegSet regs;
41
tcg_insn_unit *value_ptr;
40
} TCGArgConstraint;
42
- TCGRelocation *first_reloc;
41
43
} u;
44
-#ifdef CONFIG_DEBUG_TCG
45
+ QSIMPLEQ_HEAD(, TCGRelocation) relocs;
46
QSIMPLEQ_ENTRY(TCGLabel) next;
47
-#endif
48
};
49
50
typedef struct TCGPool {
51
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
52
#endif
53
54
#ifdef CONFIG_DEBUG_TCG
55
- QSIMPLEQ_HEAD(, TCGLabel) labels;
56
int temps_in_use;
57
int goto_tb_issue_mask;
58
#endif
59
@@ -XXX,XX +XXX,XX @@ struct TCGContext {
60
TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
61
62
QTAILQ_HEAD(, TCGOp) ops, free_ops;
63
+ QSIMPLEQ_HEAD(, TCGLabel) labels;
64
65
/* Tells which temporary holds a given register.
66
It does not take into account fixed registers */
67
diff --git a/tcg/tcg.c b/tcg/tcg.c
42
diff --git a/tcg/tcg.c b/tcg/tcg.c
68
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
69
--- a/tcg/tcg.c
44
--- a/tcg/tcg.c
70
+++ b/tcg/tcg.c
45
+++ b/tcg/tcg.c
71
@@ -XXX,XX +XXX,XX @@ static __attribute__((unused)) inline void tcg_patch64(tcg_insn_unit *p,
46
@@ -XXX,XX +XXX,XX @@ void tcg_context_init(TCGContext *s)
72
static void tcg_out_reloc(TCGContext *s, tcg_insn_unit *code_ptr, int type,
47
total_args += n;
73
TCGLabel *l, intptr_t addend)
74
{
75
- TCGRelocation *r;
76
+ TCGRelocation *r = tcg_malloc(sizeof(TCGRelocation));
77
78
- if (l->has_value) {
79
- /* FIXME: This may break relocations on RISC targets that
80
- modify instruction fields in place. The caller may not have
81
- written the initial value. */
82
- bool ok = patch_reloc(code_ptr, type, l->u.value, addend);
83
- tcg_debug_assert(ok);
84
- } else {
85
- /* add a new relocation entry */
86
- r = tcg_malloc(sizeof(TCGRelocation));
87
- r->type = type;
88
- r->ptr = code_ptr;
89
- r->addend = addend;
90
- r->next = l->u.first_reloc;
91
- l->u.first_reloc = r;
92
- }
93
+ r->type = type;
94
+ r->ptr = code_ptr;
95
+ r->addend = addend;
96
+ QSIMPLEQ_INSERT_TAIL(&l->relocs, r, next);
97
}
98
99
static void tcg_out_label(TCGContext *s, TCGLabel *l, tcg_insn_unit *ptr)
100
{
101
- intptr_t value = (intptr_t)ptr;
102
- TCGRelocation *r;
103
-
104
tcg_debug_assert(!l->has_value);
105
-
106
- for (r = l->u.first_reloc; r != NULL; r = r->next) {
107
- bool ok = patch_reloc(r->ptr, r->type, value, r->addend);
108
- tcg_debug_assert(ok);
109
- }
110
-
111
l->has_value = 1;
112
l->u.value_ptr = ptr;
113
}
114
@@ -XXX,XX +XXX,XX @@ TCGLabel *gen_new_label(void)
115
TCGContext *s = tcg_ctx;
116
TCGLabel *l = tcg_malloc(sizeof(TCGLabel));
117
118
- *l = (TCGLabel){
119
- .id = s->nb_labels++
120
- };
121
-#ifdef CONFIG_DEBUG_TCG
122
+ memset(l, 0, sizeof(TCGLabel));
123
+ l->id = s->nb_labels++;
124
+ QSIMPLEQ_INIT(&l->relocs);
125
+
126
QSIMPLEQ_INSERT_TAIL(&s->labels, l, next);
127
-#endif
128
129
return l;
130
}
131
132
+static bool tcg_resolve_relocs(TCGContext *s)
133
+{
134
+ TCGLabel *l;
135
+
136
+ QSIMPLEQ_FOREACH(l, &s->labels, next) {
137
+ TCGRelocation *r;
138
+ uintptr_t value = l->u.value;
139
+
140
+ QSIMPLEQ_FOREACH(r, &l->relocs, next) {
141
+ if (!patch_reloc(r->ptr, r->type, value, r->addend)) {
142
+ return false;
143
+ }
144
+ }
145
+ }
146
+ return true;
147
+}
148
+
149
static void set_jmp_reset_offset(TCGContext *s, int which)
150
{
151
size_t off = tcg_current_code_size(s);
152
@@ -XXX,XX +XXX,XX @@ void tcg_func_start(TCGContext *s)
153
154
QTAILQ_INIT(&s->ops);
155
QTAILQ_INIT(&s->free_ops);
156
-#ifdef CONFIG_DEBUG_TCG
157
QSIMPLEQ_INIT(&s->labels);
158
-#endif
159
}
160
161
static inline TCGTemp *tcg_temp_alloc(TCGContext *s)
162
@@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
163
return -1;
164
}
48
}
165
#endif
49
166
+ if (!tcg_resolve_relocs(s)) {
50
- args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
167
+ return -2;
51
+ args_ct = g_new0(TCGArgConstraint, total_args);
168
+ }
52
169
53
for(op = 0; op < NB_OPS; op++) {
170
/* flush instruction cache */
54
def = &tcg_op_defs[op];
171
flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
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);
172
--
138
--
173
2.17.1
139
2.25.1
174
140
175
141
diff view generated by jsdifflib
1
The last user of this field disappeared in f69d277ece4.
2
1
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
5
---
4
tcg/arm/tcg-target.h | 2 +-
6
include/tcg/tcg.h | 3 ---
5
tcg/arm/tcg-target.inc.c | 25 +++++++++++++++++++++++++
7
1 file changed, 3 deletions(-)
6
2 files changed, 26 insertions(+), 1 deletion(-)
7
8
8
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
9
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
9
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
10
--- a/tcg/arm/tcg-target.h
11
--- a/include/tcg/tcg.h
11
+++ b/tcg/arm/tcg-target.h
12
+++ b/include/tcg/tcg.h
12
@@ -XXX,XX +XXX,XX @@ extern bool use_idiv_instructions;
13
@@ -XXX,XX +XXX,XX @@ typedef struct TCGOpDef {
13
#define TCG_TARGET_HAS_deposit_i32 use_armv7_instructions
14
uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
14
#define TCG_TARGET_HAS_extract_i32 use_armv7_instructions
15
uint8_t flags;
15
#define TCG_TARGET_HAS_sextract_i32 use_armv7_instructions
16
TCGArgConstraint *args_ct;
16
-#define TCG_TARGET_HAS_extract2_i32 0
17
-#if defined(CONFIG_DEBUG_TCG)
17
+#define TCG_TARGET_HAS_extract2_i32 1
18
- int used;
18
#define TCG_TARGET_HAS_movcond_i32 1
19
-#endif
19
#define TCG_TARGET_HAS_mulu2_i32 1
20
} TCGOpDef;
20
#define TCG_TARGET_HAS_muls2_i32 1
21
21
diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
22
extern TCGOpDef tcg_op_defs[];
22
index XXXXXXX..XXXXXXX 100644
23
--- a/tcg/arm/tcg-target.inc.c
24
+++ b/tcg/arm/tcg-target.inc.c
25
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
26
case INDEX_op_sextract_i32:
27
tcg_out_sextract(s, COND_AL, args[0], args[1], args[2], args[3]);
28
break;
29
+ case INDEX_op_extract2_i32:
30
+ /* ??? These optimization vs zero should be generic. */
31
+ /* ??? But we can't substitute 2 for 1 in the opcode stream yet. */
32
+ if (const_args[1]) {
33
+ if (const_args[2]) {
34
+ tcg_out_movi(s, TCG_TYPE_REG, args[0], 0);
35
+ } else {
36
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0,
37
+ args[2], SHIFT_IMM_LSL(32 - args[3]));
38
+ }
39
+ } else if (const_args[2]) {
40
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0,
41
+ args[1], SHIFT_IMM_LSR(args[3]));
42
+ } else {
43
+ /* We can do extract2 in 2 insns, vs the 3 required otherwise. */
44
+ tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP, 0,
45
+ args[2], SHIFT_IMM_LSL(32 - args[3]));
46
+ tcg_out_dat_reg(s, COND_AL, ARITH_ORR, args[0], TCG_REG_TMP,
47
+ args[1], SHIFT_IMM_LSR(args[3]));
48
+ }
49
+ break;
50
51
case INDEX_op_div_i32:
52
tcg_out_sdiv(s, COND_AL, args[0], args[1], args[2]);
53
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
54
= { .args_ct_str = { "s", "s", "s", "s" } };
55
static const TCGTargetOpDef br
56
= { .args_ct_str = { "r", "rIN" } };
57
+ static const TCGTargetOpDef ext2
58
+ = { .args_ct_str = { "r", "rZ", "rZ" } };
59
static const TCGTargetOpDef dep
60
= { .args_ct_str = { "r", "0", "rZ" } };
61
static const TCGTargetOpDef movc
62
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
63
return &br;
64
case INDEX_op_deposit_i32:
65
return &dep;
66
+ case INDEX_op_extract2_i32:
67
+ return &ext2;
68
case INDEX_op_movcond_i32:
69
return &movc;
70
case INDEX_op_add2_i32:
71
--
23
--
72
2.17.1
24
2.25.1
73
25
74
26
diff view generated by jsdifflib
1
From: Shahab Vahedi <shahab.vahedi@gmail.com>
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.
2
4
3
This change adapts io_readx() to its input access_type. Currently
5
Fixes: 7b60ef3264e
4
io_readx() treats any memory access as a read, although it has an
6
Cc: qemu-stable@nongnu.org
5
input argument "MMUAccessType access_type". This results in:
6
7
1) Calling the tlb_fill() only with MMU_DATA_LOAD
8
2) Considering only entry->addr_read as the tlb_addr
9
10
Buglink: https://bugs.launchpad.net/qemu/+bug/1825359
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Shahab Vahedi <shahab.vahedi@gmail.com>
13
Message-Id: <20190420072236.12347-1-shahab.vahedi@gmail.com>
14
[rth: Remove assert; fix expression formatting.]
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
---
8
---
17
accel/tcg/cputlb.c | 5 +++--
9
tcg/i386/tcg-target.c.inc | 2 +-
18
1 file changed, 3 insertions(+), 2 deletions(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
19
11
20
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
12
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/accel/tcg/cputlb.c
14
--- a/tcg/i386/tcg-target.c.inc
23
+++ b/accel/tcg/cputlb.c
15
+++ b/tcg/i386/tcg-target.c.inc
24
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
16
@@ -XXX,XX +XXX,XX @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
25
CPUTLBEntry *entry;
17
new_pool_label(s, arg, R_386_PC32, s->code_ptr - 4, -4);
26
target_ulong tlb_addr;
18
} else {
27
19
if (have_avx2) {
28
- tlb_fill(cpu, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
20
- tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTW + vex_l, ret);
29
+ tlb_fill(cpu, addr, size, access_type, mmu_idx, retaddr);
21
+ tcg_out_vex_modrm_pool(s, OPC_VPBROADCASTD + vex_l, ret);
30
22
} else {
31
entry = tlb_entry(env, mmu_idx, addr);
23
tcg_out_vex_modrm_pool(s, OPC_VBROADCASTSS, ret);
32
- tlb_addr = entry->addr_read;
24
}
33
+ tlb_addr = (access_type == MMU_DATA_LOAD ?
34
+ entry->addr_read : entry->addr_code);
35
if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
36
/* RAM access */
37
uintptr_t haddr = addr + entry->addend;
38
--
25
--
39
2.17.1
26
2.25.1
40
27
41
28
diff view generated by jsdifflib
1
In order to handle TB's that translate to too much code, we
1
The definition of INDEX_op_dupi_vec is that it operates on
2
need to place the control of the length of the translation
2
units of tcg_target_ulong -- in this case 32 bits. It does
3
in the hands of the code gen master loop.
3
not work to use this for a uint64_t value that happens to be
4
small enough to fit in tcg_target_ulong.
4
5
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Fixes: d2fd745fe8b
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Fixes: db432672dc5
8
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
10
---
9
include/exec/exec-all.h | 4 ++--
11
tcg/tcg-op-vec.c | 12 ++++++++----
10
include/exec/translator.h | 3 ++-
12
1 file changed, 8 insertions(+), 4 deletions(-)
11
accel/tcg/translate-all.c | 15 +++++++++++++--
12
accel/tcg/translator.c | 15 ++-------------
13
target/alpha/translate.c | 4 ++--
14
target/arm/translate.c | 4 ++--
15
target/cris/translate.c | 10 +---------
16
target/hppa/translate.c | 5 ++---
17
target/i386/translate.c | 4 ++--
18
target/lm32/translate.c | 10 +---------
19
target/m68k/translate.c | 4 ++--
20
target/microblaze/translate.c | 10 +---------
21
target/mips/translate.c | 4 ++--
22
target/moxie/translate.c | 11 ++---------
23
target/nios2/translate.c | 14 ++------------
24
target/openrisc/translate.c | 4 ++--
25
target/ppc/translate.c | 4 ++--
26
target/riscv/translate.c | 4 ++--
27
target/s390x/translate.c | 4 ++--
28
target/sh4/translate.c | 4 ++--
29
target/sparc/translate.c | 4 ++--
30
target/tilegx/translate.c | 12 +-----------
31
target/tricore/translate.c | 16 ++--------------
32
target/unicore32/translate.c | 10 +---------
33
target/xtensa/translate.c | 4 ++--
34
25 files changed, 56 insertions(+), 127 deletions(-)
35
13
36
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
14
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
37
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
38
--- a/include/exec/exec-all.h
16
--- a/tcg/tcg-op-vec.c
39
+++ b/include/exec/exec-all.h
17
+++ b/tcg/tcg-op-vec.c
40
@@ -XXX,XX +XXX,XX @@ typedef ram_addr_t tb_page_addr_t;
18
@@ -XXX,XX +XXX,XX @@ TCGv_vec tcg_const_ones_vec_matching(TCGv_vec m)
41
19
42
#include "qemu/log.h"
20
void tcg_gen_dup64i_vec(TCGv_vec r, uint64_t a)
43
21
{
44
-void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb);
22
- if (TCG_TARGET_REG_BITS == 32 && a == deposit64(a, 32, 32, a)) {
45
-void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
23
- do_dupi_vec(r, MO_32, a);
46
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns);
24
- } else if (TCG_TARGET_REG_BITS == 64 || a == (uint64_t)(int32_t)a) {
47
+void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb,
25
+ if (TCG_TARGET_REG_BITS == 64) {
48
target_ulong *data);
26
do_dupi_vec(r, MO_64, a);
49
27
+ } else if (a == dup_const(MO_32, a)) {
50
void cpu_gen_init(void);
28
+ do_dupi_vec(r, MO_32, a);
51
diff --git a/include/exec/translator.h b/include/exec/translator.h
29
} else {
52
index XXXXXXX..XXXXXXX 100644
30
TCGv_i64 c = tcg_const_i64(a);
53
--- a/include/exec/translator.h
31
tcg_gen_dup_i64_vec(MO_64, r, c);
54
+++ b/include/exec/translator.h
32
@@ -XXX,XX +XXX,XX @@ void tcg_gen_dup8i_vec(TCGv_vec r, uint32_t a)
55
@@ -XXX,XX +XXX,XX @@ typedef struct TranslatorOps {
33
56
* @db: Disassembly context.
34
void tcg_gen_dupi_vec(unsigned vece, TCGv_vec r, uint64_t a)
57
* @cpu: Target vCPU.
35
{
58
* @tb: Translation block.
36
- do_dupi_vec(r, MO_REG, dup_const(vece, a));
59
+ * @max_insns: Maximum number of insns to translate.
37
+ if (vece == MO_64) {
60
*
38
+ tcg_gen_dup64i_vec(r, a);
61
* Generic translator loop.
39
+ } else {
62
*
40
+ do_dupi_vec(r, MO_REG, dup_const(vece, a));
63
@@ -XXX,XX +XXX,XX @@ typedef struct TranslatorOps {
64
* - When too many instructions have been translated.
65
*/
66
void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
67
- CPUState *cpu, TranslationBlock *tb);
68
+ CPUState *cpu, TranslationBlock *tb, int max_insns);
69
70
void translator_loop_temp_check(DisasContextBase *db);
71
72
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/accel/tcg/translate-all.c
75
+++ b/accel/tcg/translate-all.c
76
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
77
tb_page_addr_t phys_pc, phys_page2;
78
target_ulong virt_page2;
79
tcg_insn_unit *gen_code_buf;
80
- int gen_code_size, search_size;
81
+ int gen_code_size, search_size, max_insns;
82
#ifdef CONFIG_PROFILER
83
TCGProfile *prof = &tcg_ctx->prof;
84
int64_t ti;
85
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
86
cflags &= ~CF_CLUSTER_MASK;
87
cflags |= cpu->cluster_index << CF_CLUSTER_SHIFT;
88
89
+ max_insns = cflags & CF_COUNT_MASK;
90
+ if (max_insns == 0) {
91
+ max_insns = CF_COUNT_MASK;
92
+ }
41
+ }
93
+ if (max_insns > TCG_MAX_INSNS) {
94
+ max_insns = TCG_MAX_INSNS;
95
+ }
96
+ if (cpu->singlestep_enabled || singlestep) {
97
+ max_insns = 1;
98
+ }
99
+
100
buffer_overflow:
101
tb = tb_alloc(pc);
102
if (unlikely(!tb)) {
103
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
104
tcg_func_start(tcg_ctx);
105
106
tcg_ctx->cpu = ENV_GET_CPU(env);
107
- gen_intermediate_code(cpu, tb);
108
+ gen_intermediate_code(cpu, tb, max_insns);
109
tcg_ctx->cpu = NULL;
110
111
trace_translate_block(tb, tb->pc, tb->tc.ptr);
112
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/accel/tcg/translator.c
115
+++ b/accel/tcg/translator.c
116
@@ -XXX,XX +XXX,XX @@ void translator_loop_temp_check(DisasContextBase *db)
117
}
42
}
118
43
119
void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
44
void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec r, TCGv_i64 a)
120
- CPUState *cpu, TranslationBlock *tb)
121
+ CPUState *cpu, TranslationBlock *tb, int max_insns)
122
{
123
int bp_insn = 0;
124
125
@@ -XXX,XX +XXX,XX @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
126
db->pc_next = db->pc_first;
127
db->is_jmp = DISAS_NEXT;
128
db->num_insns = 0;
129
+ db->max_insns = max_insns;
130
db->singlestep_enabled = cpu->singlestep_enabled;
131
132
- /* Instruction counting */
133
- db->max_insns = tb_cflags(db->tb) & CF_COUNT_MASK;
134
- if (db->max_insns == 0) {
135
- db->max_insns = CF_COUNT_MASK;
136
- }
137
- if (db->max_insns > TCG_MAX_INSNS) {
138
- db->max_insns = TCG_MAX_INSNS;
139
- }
140
- if (db->singlestep_enabled || singlestep) {
141
- db->max_insns = 1;
142
- }
143
-
144
ops->init_disas_context(db, cpu);
145
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
146
147
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/target/alpha/translate.c
150
+++ b/target/alpha/translate.c
151
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps alpha_tr_ops = {
152
.disas_log = alpha_tr_disas_log,
153
};
154
155
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
156
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
157
{
158
DisasContext dc;
159
- translator_loop(&alpha_tr_ops, &dc.base, cpu, tb);
160
+ translator_loop(&alpha_tr_ops, &dc.base, cpu, tb, max_insns);
161
}
162
163
void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb,
164
diff --git a/target/arm/translate.c b/target/arm/translate.c
165
index XXXXXXX..XXXXXXX 100644
166
--- a/target/arm/translate.c
167
+++ b/target/arm/translate.c
168
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps thumb_translator_ops = {
169
};
170
171
/* generate intermediate code for basic block 'tb'. */
172
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
173
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
174
{
175
DisasContext dc;
176
const TranslatorOps *ops = &arm_translator_ops;
177
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
178
}
179
#endif
180
181
- translator_loop(ops, &dc.base, cpu, tb);
182
+ translator_loop(ops, &dc.base, cpu, tb, max_insns);
183
}
184
185
void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
186
diff --git a/target/cris/translate.c b/target/cris/translate.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/target/cris/translate.c
189
+++ b/target/cris/translate.c
190
@@ -XXX,XX +XXX,XX @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
191
*/
192
193
/* generate intermediate code for basic block 'tb'. */
194
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
195
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
196
{
197
CPUCRISState *env = cs->env_ptr;
198
uint32_t pc_start;
199
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
200
uint32_t page_start;
201
target_ulong npc;
202
int num_insns;
203
- int max_insns;
204
205
if (env->pregs[PR_VR] == 32) {
206
dc->decoder = crisv32_decoder;
207
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
208
209
page_start = pc_start & TARGET_PAGE_MASK;
210
num_insns = 0;
211
- max_insns = tb_cflags(tb) & CF_COUNT_MASK;
212
- if (max_insns == 0) {
213
- max_insns = CF_COUNT_MASK;
214
- }
215
- if (max_insns > TCG_MAX_INSNS) {
216
- max_insns = TCG_MAX_INSNS;
217
- }
218
219
gen_tb_start(tb);
220
do {
221
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
222
index XXXXXXX..XXXXXXX 100644
223
--- a/target/hppa/translate.c
224
+++ b/target/hppa/translate.c
225
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hppa_tr_ops = {
226
.disas_log = hppa_tr_disas_log,
227
};
228
229
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
230
-
231
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
232
{
233
DisasContext ctx;
234
- translator_loop(&hppa_tr_ops, &ctx.base, cs, tb);
235
+ translator_loop(&hppa_tr_ops, &ctx.base, cs, tb, max_insns);
236
}
237
238
void restore_state_to_opc(CPUHPPAState *env, TranslationBlock *tb,
239
diff --git a/target/i386/translate.c b/target/i386/translate.c
240
index XXXXXXX..XXXXXXX 100644
241
--- a/target/i386/translate.c
242
+++ b/target/i386/translate.c
243
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps i386_tr_ops = {
244
};
245
246
/* generate intermediate code for basic block 'tb'. */
247
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
248
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
249
{
250
DisasContext dc;
251
252
- translator_loop(&i386_tr_ops, &dc.base, cpu, tb);
253
+ translator_loop(&i386_tr_ops, &dc.base, cpu, tb, max_insns);
254
}
255
256
void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
257
diff --git a/target/lm32/translate.c b/target/lm32/translate.c
258
index XXXXXXX..XXXXXXX 100644
259
--- a/target/lm32/translate.c
260
+++ b/target/lm32/translate.c
261
@@ -XXX,XX +XXX,XX @@ static inline void decode(DisasContext *dc, uint32_t ir)
262
}
263
264
/* generate intermediate code for basic block 'tb'. */
265
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
266
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
267
{
268
CPULM32State *env = cs->env_ptr;
269
LM32CPU *cpu = lm32_env_get_cpu(env);
270
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
271
uint32_t pc_start;
272
uint32_t page_start;
273
int num_insns;
274
- int max_insns;
275
276
pc_start = tb->pc;
277
dc->features = cpu->features;
278
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
279
280
page_start = pc_start & TARGET_PAGE_MASK;
281
num_insns = 0;
282
- max_insns = tb_cflags(tb) & CF_COUNT_MASK;
283
- if (max_insns == 0) {
284
- max_insns = CF_COUNT_MASK;
285
- }
286
- if (max_insns > TCG_MAX_INSNS) {
287
- max_insns = TCG_MAX_INSNS;
288
- }
289
290
gen_tb_start(tb);
291
do {
292
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
293
index XXXXXXX..XXXXXXX 100644
294
--- a/target/m68k/translate.c
295
+++ b/target/m68k/translate.c
296
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps m68k_tr_ops = {
297
.disas_log = m68k_tr_disas_log,
298
};
299
300
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
301
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
302
{
303
DisasContext dc;
304
- translator_loop(&m68k_tr_ops, &dc.base, cpu, tb);
305
+ translator_loop(&m68k_tr_ops, &dc.base, cpu, tb, max_insns);
306
}
307
308
static double floatx80_to_double(CPUM68KState *env, uint16_t high, uint64_t low)
309
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
310
index XXXXXXX..XXXXXXX 100644
311
--- a/target/microblaze/translate.c
312
+++ b/target/microblaze/translate.c
313
@@ -XXX,XX +XXX,XX @@ static inline void decode(DisasContext *dc, uint32_t ir)
314
}
315
316
/* generate intermediate code for basic block 'tb'. */
317
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
318
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
319
{
320
CPUMBState *env = cs->env_ptr;
321
MicroBlazeCPU *cpu = mb_env_get_cpu(env);
322
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
323
uint32_t page_start, org_flags;
324
uint32_t npc;
325
int num_insns;
326
- int max_insns;
327
328
pc_start = tb->pc;
329
dc->cpu = cpu;
330
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
331
332
page_start = pc_start & TARGET_PAGE_MASK;
333
num_insns = 0;
334
- max_insns = tb_cflags(tb) & CF_COUNT_MASK;
335
- if (max_insns == 0) {
336
- max_insns = CF_COUNT_MASK;
337
- }
338
- if (max_insns > TCG_MAX_INSNS) {
339
- max_insns = TCG_MAX_INSNS;
340
- }
341
342
gen_tb_start(tb);
343
do
344
diff --git a/target/mips/translate.c b/target/mips/translate.c
345
index XXXXXXX..XXXXXXX 100644
346
--- a/target/mips/translate.c
347
+++ b/target/mips/translate.c
348
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mips_tr_ops = {
349
.disas_log = mips_tr_disas_log,
350
};
351
352
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
353
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
354
{
355
DisasContext ctx;
356
357
- translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
358
+ translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
359
}
360
361
static void fpu_dump_state(CPUMIPSState *env, FILE *f, int flags)
362
diff --git a/target/moxie/translate.c b/target/moxie/translate.c
363
index XXXXXXX..XXXXXXX 100644
364
--- a/target/moxie/translate.c
365
+++ b/target/moxie/translate.c
366
@@ -XXX,XX +XXX,XX @@ static int decode_opc(MoxieCPU *cpu, DisasContext *ctx)
367
}
368
369
/* generate intermediate code for basic block 'tb'. */
370
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
371
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
372
{
373
CPUMoxieState *env = cs->env_ptr;
374
MoxieCPU *cpu = moxie_env_get_cpu(env);
375
DisasContext ctx;
376
target_ulong pc_start;
377
- int num_insns, max_insns;
378
+ int num_insns;
379
380
pc_start = tb->pc;
381
ctx.pc = pc_start;
382
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
383
ctx.singlestep_enabled = 0;
384
ctx.bstate = BS_NONE;
385
num_insns = 0;
386
- max_insns = tb_cflags(tb) & CF_COUNT_MASK;
387
- if (max_insns == 0) {
388
- max_insns = CF_COUNT_MASK;
389
- }
390
- if (max_insns > TCG_MAX_INSNS) {
391
- max_insns = TCG_MAX_INSNS;
392
- }
393
394
gen_tb_start(tb);
395
do {
396
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
397
index XXXXXXX..XXXXXXX 100644
398
--- a/target/nios2/translate.c
399
+++ b/target/nios2/translate.c
400
@@ -XXX,XX +XXX,XX @@ static void gen_exception(DisasContext *dc, uint32_t excp)
401
}
402
403
/* generate intermediate code for basic block 'tb'. */
404
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
405
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
406
{
407
CPUNios2State *env = cs->env_ptr;
408
DisasContext dc1, *dc = &dc1;
409
int num_insns;
410
- int max_insns;
411
412
/* Initialize DC */
413
dc->cpu_env = cpu_env;
414
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
415
416
/* Set up instruction counts */
417
num_insns = 0;
418
- if (cs->singlestep_enabled || singlestep) {
419
- max_insns = 1;
420
- } else {
421
+ if (max_insns > 1) {
422
int page_insns = (TARGET_PAGE_SIZE - (tb->pc & TARGET_PAGE_MASK)) / 4;
423
- max_insns = tb_cflags(tb) & CF_COUNT_MASK;
424
- if (max_insns == 0) {
425
- max_insns = CF_COUNT_MASK;
426
- }
427
if (max_insns > page_insns) {
428
max_insns = page_insns;
429
}
430
- if (max_insns > TCG_MAX_INSNS) {
431
- max_insns = TCG_MAX_INSNS;
432
- }
433
}
434
435
gen_tb_start(tb);
436
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
437
index XXXXXXX..XXXXXXX 100644
438
--- a/target/openrisc/translate.c
439
+++ b/target/openrisc/translate.c
440
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps openrisc_tr_ops = {
441
.disas_log = openrisc_tr_disas_log,
442
};
443
444
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
445
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
446
{
447
DisasContext ctx;
448
449
- translator_loop(&openrisc_tr_ops, &ctx.base, cs, tb);
450
+ translator_loop(&openrisc_tr_ops, &ctx.base, cs, tb, max_insns);
451
}
452
453
void openrisc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
454
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
455
index XXXXXXX..XXXXXXX 100644
456
--- a/target/ppc/translate.c
457
+++ b/target/ppc/translate.c
458
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps ppc_tr_ops = {
459
.disas_log = ppc_tr_disas_log,
460
};
461
462
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
463
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
464
{
465
DisasContext ctx;
466
467
- translator_loop(&ppc_tr_ops, &ctx.base, cs, tb);
468
+ translator_loop(&ppc_tr_ops, &ctx.base, cs, tb, max_insns);
469
}
470
471
void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb,
472
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
473
index XXXXXXX..XXXXXXX 100644
474
--- a/target/riscv/translate.c
475
+++ b/target/riscv/translate.c
476
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps riscv_tr_ops = {
477
.disas_log = riscv_tr_disas_log,
478
};
479
480
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
481
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
482
{
483
DisasContext ctx;
484
485
- translator_loop(&riscv_tr_ops, &ctx.base, cs, tb);
486
+ translator_loop(&riscv_tr_ops, &ctx.base, cs, tb, max_insns);
487
}
488
489
void riscv_translate_init(void)
490
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
491
index XXXXXXX..XXXXXXX 100644
492
--- a/target/s390x/translate.c
493
+++ b/target/s390x/translate.c
494
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps s390x_tr_ops = {
495
.disas_log = s390x_tr_disas_log,
496
};
497
498
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
499
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
500
{
501
DisasContext dc;
502
503
- translator_loop(&s390x_tr_ops, &dc.base, cs, tb);
504
+ translator_loop(&s390x_tr_ops, &dc.base, cs, tb, max_insns);
505
}
506
507
void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb,
508
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
509
index XXXXXXX..XXXXXXX 100644
510
--- a/target/sh4/translate.c
511
+++ b/target/sh4/translate.c
512
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sh4_tr_ops = {
513
.disas_log = sh4_tr_disas_log,
514
};
515
516
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
517
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
518
{
519
DisasContext ctx;
520
521
- translator_loop(&sh4_tr_ops, &ctx.base, cs, tb);
522
+ translator_loop(&sh4_tr_ops, &ctx.base, cs, tb, max_insns);
523
}
524
525
void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb,
526
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
527
index XXXXXXX..XXXXXXX 100644
528
--- a/target/sparc/translate.c
529
+++ b/target/sparc/translate.c
530
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sparc_tr_ops = {
531
.disas_log = sparc_tr_disas_log,
532
};
533
534
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
535
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
536
{
537
DisasContext dc = {};
538
539
- translator_loop(&sparc_tr_ops, &dc.base, cs, tb);
540
+ translator_loop(&sparc_tr_ops, &dc.base, cs, tb, max_insns);
541
}
542
543
void sparc_tcg_init(void)
544
diff --git a/target/tilegx/translate.c b/target/tilegx/translate.c
545
index XXXXXXX..XXXXXXX 100644
546
--- a/target/tilegx/translate.c
547
+++ b/target/tilegx/translate.c
548
@@ -XXX,XX +XXX,XX @@ static void translate_one_bundle(DisasContext *dc, uint64_t bundle)
549
}
550
}
551
552
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
553
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
554
{
555
CPUTLGState *env = cs->env_ptr;
556
DisasContext ctx;
557
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
558
uint64_t pc_start = tb->pc;
559
uint64_t page_start = pc_start & TARGET_PAGE_MASK;
560
int num_insns = 0;
561
- int max_insns = tb_cflags(tb) & CF_COUNT_MASK;
562
563
dc->pc = pc_start;
564
dc->mmuidx = 0;
565
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
566
qemu_log_lock();
567
qemu_log("IN: %s\n", lookup_symbol(pc_start));
568
}
569
- if (!max_insns) {
570
- max_insns = CF_COUNT_MASK;
571
- }
572
- if (cs->singlestep_enabled || singlestep) {
573
- max_insns = 1;
574
- }
575
- if (max_insns > TCG_MAX_INSNS) {
576
- max_insns = TCG_MAX_INSNS;
577
- }
578
gen_tb_start(tb);
579
580
while (1) {
581
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
582
index XXXXXXX..XXXXXXX 100644
583
--- a/target/tricore/translate.c
584
+++ b/target/tricore/translate.c
585
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch)
586
}
587
}
588
589
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
590
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
591
{
592
CPUTriCoreState *env = cs->env_ptr;
593
DisasContext ctx;
594
target_ulong pc_start;
595
- int num_insns, max_insns;
596
-
597
- num_insns = 0;
598
- max_insns = tb_cflags(tb) & CF_COUNT_MASK;
599
- if (max_insns == 0) {
600
- max_insns = CF_COUNT_MASK;
601
- }
602
- if (singlestep) {
603
- max_insns = 1;
604
- }
605
- if (max_insns > TCG_MAX_INSNS) {
606
- max_insns = TCG_MAX_INSNS;
607
- }
608
+ int num_insns = 0;
609
610
pc_start = tb->pc;
611
ctx.pc = pc_start;
612
diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c
613
index XXXXXXX..XXXXXXX 100644
614
--- a/target/unicore32/translate.c
615
+++ b/target/unicore32/translate.c
616
@@ -XXX,XX +XXX,XX @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
617
}
618
619
/* generate intermediate code for basic block 'tb'. */
620
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
621
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
622
{
623
CPUUniCore32State *env = cs->env_ptr;
624
DisasContext dc1, *dc = &dc1;
625
target_ulong pc_start;
626
uint32_t page_start;
627
int num_insns;
628
- int max_insns;
629
630
/* generate intermediate code */
631
num_temps = 0;
632
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
633
cpu_F1d = tcg_temp_new_i64();
634
page_start = pc_start & TARGET_PAGE_MASK;
635
num_insns = 0;
636
- max_insns = tb_cflags(tb) & CF_COUNT_MASK;
637
- if (max_insns == 0) {
638
- max_insns = CF_COUNT_MASK;
639
- }
640
- if (max_insns > TCG_MAX_INSNS) {
641
- max_insns = TCG_MAX_INSNS;
642
- }
643
644
#ifndef CONFIG_USER_ONLY
645
if ((env->uncached_asr & ASR_M) == ASR_MODE_USER) {
646
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
647
index XXXXXXX..XXXXXXX 100644
648
--- a/target/xtensa/translate.c
649
+++ b/target/xtensa/translate.c
650
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps xtensa_translator_ops = {
651
.disas_log = xtensa_tr_disas_log,
652
};
653
654
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
655
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
656
{
657
DisasContext dc = {};
658
- translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb);
659
+ translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb, max_insns);
660
}
661
662
void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
663
--
45
--
664
2.17.1
46
2.25.1
665
47
666
48
diff view generated by jsdifflib
1
This will let backends implement the double-word shift operation.
1
When the two arguments are identical, this can be reduced to
2
dup_vec or to mov_vec from a tcg_constant_vec.
2
3
3
Reviewed-by: David Hildenbrand <david@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
5
---
6
tcg/aarch64/tcg-target.h | 2 ++
6
tcg/optimize.c | 15 +++++++++++++++
7
tcg/arm/tcg-target.h | 1 +
7
1 file changed, 15 insertions(+)
8
tcg/i386/tcg-target.h | 2 ++
9
tcg/mips/tcg-target.h | 2 ++
10
tcg/ppc/tcg-target.h | 2 ++
11
tcg/riscv/tcg-target.h | 2 ++
12
tcg/s390/tcg-target.h | 2 ++
13
tcg/sparc/tcg-target.h | 2 ++
14
tcg/tcg-opc.h | 2 ++
15
tcg/tcg.h | 1 +
16
tcg/tci/tcg-target.h | 2 ++
17
tcg/optimize.c | 16 ++++++++++++++++
18
tcg/tcg-op.c | 4 ++++
19
tcg/tcg.c | 4 ++++
20
tcg/README | 7 +++++++
21
15 files changed, 51 insertions(+)
22
8
23
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/tcg/aarch64/tcg-target.h
26
+++ b/tcg/aarch64/tcg-target.h
27
@@ -XXX,XX +XXX,XX @@ typedef enum {
28
#define TCG_TARGET_HAS_deposit_i32 1
29
#define TCG_TARGET_HAS_extract_i32 1
30
#define TCG_TARGET_HAS_sextract_i32 1
31
+#define TCG_TARGET_HAS_extract2_i32 0
32
#define TCG_TARGET_HAS_movcond_i32 1
33
#define TCG_TARGET_HAS_add2_i32 1
34
#define TCG_TARGET_HAS_sub2_i32 1
35
@@ -XXX,XX +XXX,XX @@ typedef enum {
36
#define TCG_TARGET_HAS_deposit_i64 1
37
#define TCG_TARGET_HAS_extract_i64 1
38
#define TCG_TARGET_HAS_sextract_i64 1
39
+#define TCG_TARGET_HAS_extract2_i64 0
40
#define TCG_TARGET_HAS_movcond_i64 1
41
#define TCG_TARGET_HAS_add2_i64 1
42
#define TCG_TARGET_HAS_sub2_i64 1
43
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/tcg/arm/tcg-target.h
46
+++ b/tcg/arm/tcg-target.h
47
@@ -XXX,XX +XXX,XX @@ extern bool use_idiv_instructions;
48
#define TCG_TARGET_HAS_deposit_i32 use_armv7_instructions
49
#define TCG_TARGET_HAS_extract_i32 use_armv7_instructions
50
#define TCG_TARGET_HAS_sextract_i32 use_armv7_instructions
51
+#define TCG_TARGET_HAS_extract2_i32 0
52
#define TCG_TARGET_HAS_movcond_i32 1
53
#define TCG_TARGET_HAS_mulu2_i32 1
54
#define TCG_TARGET_HAS_muls2_i32 1
55
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/tcg/i386/tcg-target.h
58
+++ b/tcg/i386/tcg-target.h
59
@@ -XXX,XX +XXX,XX @@ extern bool have_avx2;
60
#define TCG_TARGET_HAS_deposit_i32 1
61
#define TCG_TARGET_HAS_extract_i32 1
62
#define TCG_TARGET_HAS_sextract_i32 1
63
+#define TCG_TARGET_HAS_extract2_i32 0
64
#define TCG_TARGET_HAS_movcond_i32 1
65
#define TCG_TARGET_HAS_add2_i32 1
66
#define TCG_TARGET_HAS_sub2_i32 1
67
@@ -XXX,XX +XXX,XX @@ extern bool have_avx2;
68
#define TCG_TARGET_HAS_deposit_i64 1
69
#define TCG_TARGET_HAS_extract_i64 1
70
#define TCG_TARGET_HAS_sextract_i64 0
71
+#define TCG_TARGET_HAS_extract2_i64 0
72
#define TCG_TARGET_HAS_movcond_i64 1
73
#define TCG_TARGET_HAS_add2_i64 1
74
#define TCG_TARGET_HAS_sub2_i64 1
75
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
76
index XXXXXXX..XXXXXXX 100644
77
--- a/tcg/mips/tcg-target.h
78
+++ b/tcg/mips/tcg-target.h
79
@@ -XXX,XX +XXX,XX @@ extern bool use_mips32r2_instructions;
80
#define TCG_TARGET_HAS_deposit_i32 use_mips32r2_instructions
81
#define TCG_TARGET_HAS_extract_i32 use_mips32r2_instructions
82
#define TCG_TARGET_HAS_sextract_i32 0
83
+#define TCG_TARGET_HAS_extract2_i32 0
84
#define TCG_TARGET_HAS_ext8s_i32 use_mips32r2_instructions
85
#define TCG_TARGET_HAS_ext16s_i32 use_mips32r2_instructions
86
#define TCG_TARGET_HAS_rot_i32 use_mips32r2_instructions
87
@@ -XXX,XX +XXX,XX @@ extern bool use_mips32r2_instructions;
88
#define TCG_TARGET_HAS_deposit_i64 use_mips32r2_instructions
89
#define TCG_TARGET_HAS_extract_i64 use_mips32r2_instructions
90
#define TCG_TARGET_HAS_sextract_i64 0
91
+#define TCG_TARGET_HAS_extract2_i64 0
92
#define TCG_TARGET_HAS_ext8s_i64 use_mips32r2_instructions
93
#define TCG_TARGET_HAS_ext16s_i64 use_mips32r2_instructions
94
#define TCG_TARGET_HAS_rot_i64 use_mips32r2_instructions
95
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
96
index XXXXXXX..XXXXXXX 100644
97
--- a/tcg/ppc/tcg-target.h
98
+++ b/tcg/ppc/tcg-target.h
99
@@ -XXX,XX +XXX,XX @@ extern bool have_isa_3_00;
100
#define TCG_TARGET_HAS_deposit_i32 1
101
#define TCG_TARGET_HAS_extract_i32 1
102
#define TCG_TARGET_HAS_sextract_i32 0
103
+#define TCG_TARGET_HAS_extract2_i32 0
104
#define TCG_TARGET_HAS_movcond_i32 1
105
#define TCG_TARGET_HAS_mulu2_i32 0
106
#define TCG_TARGET_HAS_muls2_i32 0
107
@@ -XXX,XX +XXX,XX @@ extern bool have_isa_3_00;
108
#define TCG_TARGET_HAS_deposit_i64 1
109
#define TCG_TARGET_HAS_extract_i64 1
110
#define TCG_TARGET_HAS_sextract_i64 0
111
+#define TCG_TARGET_HAS_extract2_i64 0
112
#define TCG_TARGET_HAS_movcond_i64 1
113
#define TCG_TARGET_HAS_add2_i64 1
114
#define TCG_TARGET_HAS_sub2_i64 1
115
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
116
index XXXXXXX..XXXXXXX 100644
117
--- a/tcg/riscv/tcg-target.h
118
+++ b/tcg/riscv/tcg-target.h
119
@@ -XXX,XX +XXX,XX @@ typedef enum {
120
#define TCG_TARGET_HAS_deposit_i32 0
121
#define TCG_TARGET_HAS_extract_i32 0
122
#define TCG_TARGET_HAS_sextract_i32 0
123
+#define TCG_TARGET_HAS_extract2_i32 0
124
#define TCG_TARGET_HAS_add2_i32 1
125
#define TCG_TARGET_HAS_sub2_i32 1
126
#define TCG_TARGET_HAS_mulu2_i32 0
127
@@ -XXX,XX +XXX,XX @@ typedef enum {
128
#define TCG_TARGET_HAS_deposit_i64 0
129
#define TCG_TARGET_HAS_extract_i64 0
130
#define TCG_TARGET_HAS_sextract_i64 0
131
+#define TCG_TARGET_HAS_extract2_i64 0
132
#define TCG_TARGET_HAS_extrl_i64_i32 1
133
#define TCG_TARGET_HAS_extrh_i64_i32 1
134
#define TCG_TARGET_HAS_ext8s_i64 1
135
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
136
index XXXXXXX..XXXXXXX 100644
137
--- a/tcg/s390/tcg-target.h
138
+++ b/tcg/s390/tcg-target.h
139
@@ -XXX,XX +XXX,XX @@ extern uint64_t s390_facilities;
140
#define TCG_TARGET_HAS_deposit_i32 (s390_facilities & FACILITY_GEN_INST_EXT)
141
#define TCG_TARGET_HAS_extract_i32 (s390_facilities & FACILITY_GEN_INST_EXT)
142
#define TCG_TARGET_HAS_sextract_i32 0
143
+#define TCG_TARGET_HAS_extract2_i32 0
144
#define TCG_TARGET_HAS_movcond_i32 1
145
#define TCG_TARGET_HAS_add2_i32 1
146
#define TCG_TARGET_HAS_sub2_i32 1
147
@@ -XXX,XX +XXX,XX @@ extern uint64_t s390_facilities;
148
#define TCG_TARGET_HAS_deposit_i64 (s390_facilities & FACILITY_GEN_INST_EXT)
149
#define TCG_TARGET_HAS_extract_i64 (s390_facilities & FACILITY_GEN_INST_EXT)
150
#define TCG_TARGET_HAS_sextract_i64 0
151
+#define TCG_TARGET_HAS_extract2_i64 0
152
#define TCG_TARGET_HAS_movcond_i64 1
153
#define TCG_TARGET_HAS_add2_i64 1
154
#define TCG_TARGET_HAS_sub2_i64 1
155
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
156
index XXXXXXX..XXXXXXX 100644
157
--- a/tcg/sparc/tcg-target.h
158
+++ b/tcg/sparc/tcg-target.h
159
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
160
#define TCG_TARGET_HAS_deposit_i32 0
161
#define TCG_TARGET_HAS_extract_i32 0
162
#define TCG_TARGET_HAS_sextract_i32 0
163
+#define TCG_TARGET_HAS_extract2_i32 0
164
#define TCG_TARGET_HAS_movcond_i32 1
165
#define TCG_TARGET_HAS_add2_i32 1
166
#define TCG_TARGET_HAS_sub2_i32 1
167
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
168
#define TCG_TARGET_HAS_deposit_i64 0
169
#define TCG_TARGET_HAS_extract_i64 0
170
#define TCG_TARGET_HAS_sextract_i64 0
171
+#define TCG_TARGET_HAS_extract2_i64 0
172
#define TCG_TARGET_HAS_movcond_i64 1
173
#define TCG_TARGET_HAS_add2_i64 1
174
#define TCG_TARGET_HAS_sub2_i64 1
175
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
176
index XXXXXXX..XXXXXXX 100644
177
--- a/tcg/tcg-opc.h
178
+++ b/tcg/tcg-opc.h
179
@@ -XXX,XX +XXX,XX @@ DEF(rotr_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32))
180
DEF(deposit_i32, 1, 2, 2, IMPL(TCG_TARGET_HAS_deposit_i32))
181
DEF(extract_i32, 1, 1, 2, IMPL(TCG_TARGET_HAS_extract_i32))
182
DEF(sextract_i32, 1, 1, 2, IMPL(TCG_TARGET_HAS_sextract_i32))
183
+DEF(extract2_i32, 1, 2, 1, IMPL(TCG_TARGET_HAS_extract2_i32))
184
185
DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END)
186
187
@@ -XXX,XX +XXX,XX @@ DEF(rotr_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
188
DEF(deposit_i64, 1, 2, 2, IMPL64 | IMPL(TCG_TARGET_HAS_deposit_i64))
189
DEF(extract_i64, 1, 1, 2, IMPL64 | IMPL(TCG_TARGET_HAS_extract_i64))
190
DEF(sextract_i64, 1, 1, 2, IMPL64 | IMPL(TCG_TARGET_HAS_sextract_i64))
191
+DEF(extract2_i64, 1, 2, 1, IMPL64 | IMPL(TCG_TARGET_HAS_extract2_i64))
192
193
/* size changing ops */
194
DEF(ext_i32_i64, 1, 1, 0, IMPL64)
195
diff --git a/tcg/tcg.h b/tcg/tcg.h
196
index XXXXXXX..XXXXXXX 100644
197
--- a/tcg/tcg.h
198
+++ b/tcg/tcg.h
199
@@ -XXX,XX +XXX,XX @@ typedef uint64_t TCGRegSet;
200
#define TCG_TARGET_HAS_deposit_i64 0
201
#define TCG_TARGET_HAS_extract_i64 0
202
#define TCG_TARGET_HAS_sextract_i64 0
203
+#define TCG_TARGET_HAS_extract2_i64 0
204
#define TCG_TARGET_HAS_movcond_i64 0
205
#define TCG_TARGET_HAS_add2_i64 0
206
#define TCG_TARGET_HAS_sub2_i64 0
207
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
208
index XXXXXXX..XXXXXXX 100644
209
--- a/tcg/tci/tcg-target.h
210
+++ b/tcg/tci/tcg-target.h
211
@@ -XXX,XX +XXX,XX @@
212
#define TCG_TARGET_HAS_deposit_i32 1
213
#define TCG_TARGET_HAS_extract_i32 0
214
#define TCG_TARGET_HAS_sextract_i32 0
215
+#define TCG_TARGET_HAS_extract2_i32 0
216
#define TCG_TARGET_HAS_eqv_i32 0
217
#define TCG_TARGET_HAS_nand_i32 0
218
#define TCG_TARGET_HAS_nor_i32 0
219
@@ -XXX,XX +XXX,XX @@
220
#define TCG_TARGET_HAS_deposit_i64 1
221
#define TCG_TARGET_HAS_extract_i64 0
222
#define TCG_TARGET_HAS_sextract_i64 0
223
+#define TCG_TARGET_HAS_extract2_i64 0
224
#define TCG_TARGET_HAS_div_i64 0
225
#define TCG_TARGET_HAS_rem_i64 0
226
#define TCG_TARGET_HAS_ext8s_i64 1
227
diff --git a/tcg/optimize.c b/tcg/optimize.c
9
diff --git a/tcg/optimize.c b/tcg/optimize.c
228
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
229
--- a/tcg/optimize.c
11
--- a/tcg/optimize.c
230
+++ b/tcg/optimize.c
12
+++ b/tcg/optimize.c
231
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
13
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
232
}
14
}
233
goto do_default;
15
goto do_default;
234
16
235
+ CASE_OP_32_64(extract2):
17
+ case INDEX_op_dup2_vec:
18
+ assert(TCG_TARGET_REG_BITS == 32);
236
+ if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) {
19
+ if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) {
237
+ TCGArg v1 = arg_info(op->args[1])->val;
20
+ tmp = arg_info(op->args[1])->val;
238
+ TCGArg v2 = arg_info(op->args[2])->val;
21
+ if (tmp == arg_info(op->args[2])->val) {
239
+
22
+ tcg_opt_gen_movi(s, op, op->args[0], tmp);
240
+ if (opc == INDEX_op_extract2_i64) {
23
+ break;
241
+ tmp = (v1 >> op->args[3]) | (v2 << (64 - op->args[3]));
242
+ } else {
243
+ tmp = (v1 >> op->args[3]) | (v2 << (32 - op->args[3]));
244
+ tmp = (int32_t)tmp;
245
+ }
24
+ }
246
+ tcg_opt_gen_movi(s, op, op->args[0], tmp);
25
+ } else if (args_are_copies(op->args[1], op->args[2])) {
247
+ break;
26
+ op->opc = INDEX_op_dup_vec;
27
+ TCGOP_VECE(op) = MO_32;
28
+ nb_iargs = 1;
248
+ }
29
+ }
249
+ goto do_default;
30
+ goto do_default;
250
+
31
+
251
CASE_OP_32_64(setcond):
32
CASE_OP_32_64(not):
252
tmp = do_constant_folding_cond(opc, op->args[1],
33
CASE_OP_32_64(neg):
253
op->args[2], op->args[3]);
34
CASE_OP_32_64(ext8s):
254
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
255
index XXXXXXX..XXXXXXX 100644
256
--- a/tcg/tcg-op.c
257
+++ b/tcg/tcg-op.c
258
@@ -XXX,XX +XXX,XX @@ void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
259
tcg_gen_mov_i32(ret, ah);
260
} else if (al == ah) {
261
tcg_gen_rotri_i32(ret, al, ofs);
262
+ } else if (TCG_TARGET_HAS_extract2_i32) {
263
+ tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs);
264
} else {
265
TCGv_i32 t0 = tcg_temp_new_i32();
266
tcg_gen_shri_i32(t0, al, ofs);
267
@@ -XXX,XX +XXX,XX @@ void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
268
tcg_gen_mov_i64(ret, ah);
269
} else if (al == ah) {
270
tcg_gen_rotri_i64(ret, al, ofs);
271
+ } else if (TCG_TARGET_HAS_extract2_i64) {
272
+ tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs);
273
} else {
274
TCGv_i64 t0 = tcg_temp_new_i64();
275
tcg_gen_shri_i64(t0, al, ofs);
276
diff --git a/tcg/tcg.c b/tcg/tcg.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/tcg/tcg.c
279
+++ b/tcg/tcg.c
280
@@ -XXX,XX +XXX,XX @@ bool tcg_op_supported(TCGOpcode op)
281
return TCG_TARGET_HAS_extract_i32;
282
case INDEX_op_sextract_i32:
283
return TCG_TARGET_HAS_sextract_i32;
284
+ case INDEX_op_extract2_i32:
285
+ return TCG_TARGET_HAS_extract2_i32;
286
case INDEX_op_add2_i32:
287
return TCG_TARGET_HAS_add2_i32;
288
case INDEX_op_sub2_i32:
289
@@ -XXX,XX +XXX,XX @@ bool tcg_op_supported(TCGOpcode op)
290
return TCG_TARGET_HAS_extract_i64;
291
case INDEX_op_sextract_i64:
292
return TCG_TARGET_HAS_sextract_i64;
293
+ case INDEX_op_extract2_i64:
294
+ return TCG_TARGET_HAS_extract2_i64;
295
case INDEX_op_extrl_i64_i32:
296
return TCG_TARGET_HAS_extrl_i64_i32;
297
case INDEX_op_extrh_i64_i32:
298
diff --git a/tcg/README b/tcg/README
299
index XXXXXXX..XXXXXXX 100644
300
--- a/tcg/README
301
+++ b/tcg/README
302
@@ -XXX,XX +XXX,XX @@ at bit 8. This operation would be equivalent to
303
304
(using an arithmetic right shift).
305
306
+* extract2_i32/i64 dest, t1, t2, pos
307
+
308
+For N = {32,64}, extract an N-bit quantity from the concatenation
309
+of t2:t1, beginning at pos. The tcg_gen_extract2_{i32,i64} expander
310
+accepts 0 <= pos <= N as inputs. The backend code generator will
311
+not see either 0 or N as inputs for these opcodes.
312
+
313
* extrl_i64_i32 t0, t1
314
315
For 64-bit hosts only, extract the low 32-bits of input T1 and place it
316
--
35
--
317
2.17.1
36
2.25.1
318
37
319
38
diff view generated by jsdifflib
1
The cmp_vec opcode is mandatory; this symbol is unused.
2
1
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
---
5
---
4
tcg/aarch64/tcg-target.h | 4 ++--
6
tcg/aarch64/tcg-target.h | 1 -
5
tcg/aarch64/tcg-target.inc.c | 11 +++++++++++
7
tcg/i386/tcg-target.h | 1 -
6
2 files changed, 13 insertions(+), 2 deletions(-)
8
tcg/ppc/tcg-target.h | 1 -
9
3 files changed, 3 deletions(-)
7
10
8
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
11
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
9
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
10
--- a/tcg/aarch64/tcg-target.h
13
--- a/tcg/aarch64/tcg-target.h
11
+++ b/tcg/aarch64/tcg-target.h
14
+++ b/tcg/aarch64/tcg-target.h
12
@@ -XXX,XX +XXX,XX @@ typedef enum {
15
@@ -XXX,XX +XXX,XX @@ typedef enum {
13
#define TCG_TARGET_HAS_deposit_i32 1
16
#define TCG_TARGET_HAS_shi_vec 1
14
#define TCG_TARGET_HAS_extract_i32 1
17
#define TCG_TARGET_HAS_shs_vec 0
15
#define TCG_TARGET_HAS_sextract_i32 1
18
#define TCG_TARGET_HAS_shv_vec 1
16
-#define TCG_TARGET_HAS_extract2_i32 0
19
-#define TCG_TARGET_HAS_cmp_vec 1
17
+#define TCG_TARGET_HAS_extract2_i32 1
20
#define TCG_TARGET_HAS_mul_vec 1
18
#define TCG_TARGET_HAS_movcond_i32 1
21
#define TCG_TARGET_HAS_sat_vec 1
19
#define TCG_TARGET_HAS_add2_i32 1
22
#define TCG_TARGET_HAS_minmax_vec 1
20
#define TCG_TARGET_HAS_sub2_i32 1
23
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
21
@@ -XXX,XX +XXX,XX @@ typedef enum {
22
#define TCG_TARGET_HAS_deposit_i64 1
23
#define TCG_TARGET_HAS_extract_i64 1
24
#define TCG_TARGET_HAS_sextract_i64 1
25
-#define TCG_TARGET_HAS_extract2_i64 0
26
+#define TCG_TARGET_HAS_extract2_i64 1
27
#define TCG_TARGET_HAS_movcond_i64 1
28
#define TCG_TARGET_HAS_add2_i64 1
29
#define TCG_TARGET_HAS_sub2_i64 1
30
diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
31
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
32
--- a/tcg/aarch64/tcg-target.inc.c
25
--- a/tcg/i386/tcg-target.h
33
+++ b/tcg/aarch64/tcg-target.inc.c
26
+++ b/tcg/i386/tcg-target.h
34
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
27
@@ -XXX,XX +XXX,XX @@ extern bool have_avx2;
35
tcg_out_sbfm(s, ext, a0, a1, a2, a2 + args[3] - 1);
28
#define TCG_TARGET_HAS_shi_vec 1
36
break;
29
#define TCG_TARGET_HAS_shs_vec 1
37
30
#define TCG_TARGET_HAS_shv_vec have_avx2
38
+ case INDEX_op_extract2_i64:
31
-#define TCG_TARGET_HAS_cmp_vec 1
39
+ case INDEX_op_extract2_i32:
32
#define TCG_TARGET_HAS_mul_vec 1
40
+ tcg_out_extr(s, ext, a0, a1, a2, args[3]);
33
#define TCG_TARGET_HAS_sat_vec 1
41
+ break;
34
#define TCG_TARGET_HAS_minmax_vec 1
42
+
35
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
43
case INDEX_op_add2_i32:
36
index XXXXXXX..XXXXXXX 100644
44
tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, REG0(2), REG0(3),
37
--- a/tcg/ppc/tcg-target.h
45
(int32_t)args[4], args[5], const_args[4],
38
+++ b/tcg/ppc/tcg-target.h
46
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
39
@@ -XXX,XX +XXX,XX @@ extern bool have_vsx;
47
= { .args_ct_str = { "r", "r", "rAL" } };
40
#define TCG_TARGET_HAS_shi_vec 0
48
static const TCGTargetOpDef dep
41
#define TCG_TARGET_HAS_shs_vec 0
49
= { .args_ct_str = { "r", "0", "rZ" } };
42
#define TCG_TARGET_HAS_shv_vec 1
50
+ static const TCGTargetOpDef ext2
43
-#define TCG_TARGET_HAS_cmp_vec 1
51
+ = { .args_ct_str = { "r", "rZ", "rZ" } };
44
#define TCG_TARGET_HAS_mul_vec 1
52
static const TCGTargetOpDef movc
45
#define TCG_TARGET_HAS_sat_vec 1
53
= { .args_ct_str = { "r", "r", "rA", "rZ", "rZ" } };
46
#define TCG_TARGET_HAS_minmax_vec 1
54
static const TCGTargetOpDef add2
55
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
56
case INDEX_op_deposit_i64:
57
return &dep;
58
59
+ case INDEX_op_extract2_i32:
60
+ case INDEX_op_extract2_i64:
61
+ return &ext2;
62
+
63
case INDEX_op_add2_i32:
64
case INDEX_op_add2_i64:
65
case INDEX_op_sub2_i32:
66
--
47
--
67
2.17.1
48
2.25.1
68
49
69
50
diff view generated by jsdifflib
1
From: Kele Huang <kele.hwang@gmail.com>
2
3
Detect all MIPS store instructions in cpu_signal_handler for all available
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.]
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
14
---
3
tcg/tcg-op.c | 47 ++++++++++++++++++++++++-----------------------
15
accel/tcg/user-exec.c | 43 +++++++++++++++++++++++++++++++++++++++----
4
1 file changed, 24 insertions(+), 23 deletions(-)
16
1 file changed, 39 insertions(+), 4 deletions(-)
5
17
6
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
18
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
7
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
8
--- a/tcg/tcg-op.c
20
--- a/accel/tcg/user-exec.c
9
+++ b/tcg/tcg-op.c
21
+++ b/accel/tcg/user-exec.c
10
@@ -XXX,XX +XXX,XX @@ static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
22
@@ -XXX,XX +XXX,XX @@ int cpu_signal_handler(int host_signum, void *pinfo,
11
tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
23
12
tcg_gen_movi_i32(TCGV_LOW(ret), 0);
24
#elif defined(__mips__)
13
}
25
14
- } else {
26
+#if defined(__misp16) || defined(__mips_micromips)
15
- TCGv_i32 t0, t1;
27
+#error "Unsupported encoding"
16
-
28
+#endif
17
- t0 = tcg_temp_new_i32();
29
+
18
- t1 = tcg_temp_new_i32();
30
int cpu_signal_handler(int host_signum, void *pinfo,
19
- if (right) {
31
void *puc)
20
- tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
32
{
21
- if (arith) {
33
siginfo_t *info = pinfo;
22
- tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
34
ucontext_t *uc = puc;
23
- } else {
35
- greg_t pc = uc->uc_mcontext.pc;
24
- tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
36
- int is_write;
25
- }
37
+ uintptr_t pc = uc->uc_mcontext.pc;
26
- tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
38
+ uint32_t insn = *(uint32_t *)pc;
27
- tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
39
+ int is_write = 0;
28
- tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
40
+
29
+ } else if (right) {
41
+ /* Detect all store instructions at program counter. */
30
+ if (TCG_TARGET_HAS_extract2_i32) {
42
+ switch((insn >> 26) & 077) {
31
+ tcg_gen_extract2_i32(TCGV_LOW(ret),
43
+ case 050: /* SB */
32
+ TCGV_LOW(arg1), TCGV_HIGH(arg1), c);
44
+ case 051: /* SH */
33
} else {
45
+ case 052: /* SWL */
34
- tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
46
+ case 053: /* SW */
35
- /* Note: ret can be the same as arg1, so we use t1 */
47
+ case 054: /* SDL */
36
- tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
48
+ case 055: /* SDR */
37
- tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
49
+ case 056: /* SWR */
38
- tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
50
+ case 070: /* SC */
39
- tcg_gen_mov_i32(TCGV_LOW(ret), t1);
51
+ case 071: /* SWC1 */
40
+ tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
52
+ case 074: /* SCD */
41
+ tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(ret),
53
+ case 075: /* SDC1 */
42
+ TCGV_HIGH(arg1), 32 - c, c);
54
+ case 077: /* SD */
43
}
55
+#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
44
- tcg_temp_free_i32(t0);
56
+ case 072: /* SWC2 */
45
- tcg_temp_free_i32(t1);
57
+ case 076: /* SDC2 */
46
+ if (arith) {
58
+#endif
47
+ tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
59
+ is_write = 1;
48
+ } else {
60
+ break;
49
+ tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
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;
50
+ }
69
+ }
51
+ } else {
70
+ break;
52
+ if (TCG_TARGET_HAS_extract2_i32) {
71
+ }
53
+ tcg_gen_extract2_i32(TCGV_HIGH(ret),
72
54
+ TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
73
- /* XXX: compute is_write */
55
+ } else {
74
- is_write = 0;
56
+ TCGv_i32 t0 = tcg_temp_new_i32();
75
return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
57
+ tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
58
+ tcg_gen_deposit_i32(TCGV_HIGH(ret), t0,
59
+ TCGV_HIGH(arg1), c, 32 - c);
60
+ tcg_temp_free_i32(t0);
61
+ }
62
+ tcg_gen_shli_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
63
}
64
}
76
}
65
77
66
--
78
--
67
2.17.1
79
2.25.1
68
80
69
81
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
3
tcg/tcg-op.c | 34 ++++++++++++++++++++++++++++++----
4
1 file changed, 30 insertions(+), 4 deletions(-)
5
1
6
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
7
index XXXXXXX..XXXXXXX 100644
8
--- a/tcg/tcg-op.c
9
+++ b/tcg/tcg-op.c
10
@@ -XXX,XX +XXX,XX @@ void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
11
return;
12
}
13
14
- mask = (1u << len) - 1;
15
t1 = tcg_temp_new_i32();
16
17
+ if (TCG_TARGET_HAS_extract2_i32) {
18
+ if (ofs + len == 32) {
19
+ tcg_gen_shli_i32(t1, arg1, len);
20
+ tcg_gen_extract2_i32(ret, t1, arg2, len);
21
+ goto done;
22
+ }
23
+ if (ofs == 0) {
24
+ tcg_gen_extract2_i32(ret, arg1, arg2, len);
25
+ tcg_gen_rotli_i32(ret, ret, len);
26
+ goto done;
27
+ }
28
+ }
29
+
30
+ mask = (1u << len) - 1;
31
if (ofs + len < 32) {
32
tcg_gen_andi_i32(t1, arg2, mask);
33
tcg_gen_shli_i32(t1, t1, ofs);
34
@@ -XXX,XX +XXX,XX @@ void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
35
}
36
tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
37
tcg_gen_or_i32(ret, ret, t1);
38
-
39
+ done:
40
tcg_temp_free_i32(t1);
41
}
42
43
@@ -XXX,XX +XXX,XX @@ void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
44
}
45
}
46
47
- mask = (1ull << len) - 1;
48
t1 = tcg_temp_new_i64();
49
50
+ if (TCG_TARGET_HAS_extract2_i64) {
51
+ if (ofs + len == 64) {
52
+ tcg_gen_shli_i64(t1, arg1, len);
53
+ tcg_gen_extract2_i64(ret, t1, arg2, len);
54
+ goto done;
55
+ }
56
+ if (ofs == 0) {
57
+ tcg_gen_extract2_i64(ret, arg1, arg2, len);
58
+ tcg_gen_rotli_i64(ret, ret, len);
59
+ goto done;
60
+ }
61
+ }
62
+
63
+ mask = (1ull << len) - 1;
64
if (ofs + len < 64) {
65
tcg_gen_andi_i64(t1, arg2, mask);
66
tcg_gen_shli_i64(t1, t1, ofs);
67
@@ -XXX,XX +XXX,XX @@ void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
68
}
69
tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
70
tcg_gen_or_i64(ret, ret, t1);
71
-
72
+ done:
73
tcg_temp_free_i64(t1);
74
}
75
76
--
77
2.17.1
78
79
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2
---
3
tcg/i386/tcg-target.h | 4 ++--
4
tcg/i386/tcg-target.inc.c | 11 +++++++++++
5
2 files changed, 13 insertions(+), 2 deletions(-)
6
1
7
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
8
index XXXXXXX..XXXXXXX 100644
9
--- a/tcg/i386/tcg-target.h
10
+++ b/tcg/i386/tcg-target.h
11
@@ -XXX,XX +XXX,XX @@ extern bool have_avx2;
12
#define TCG_TARGET_HAS_deposit_i32 1
13
#define TCG_TARGET_HAS_extract_i32 1
14
#define TCG_TARGET_HAS_sextract_i32 1
15
-#define TCG_TARGET_HAS_extract2_i32 0
16
+#define TCG_TARGET_HAS_extract2_i32 1
17
#define TCG_TARGET_HAS_movcond_i32 1
18
#define TCG_TARGET_HAS_add2_i32 1
19
#define TCG_TARGET_HAS_sub2_i32 1
20
@@ -XXX,XX +XXX,XX @@ extern bool have_avx2;
21
#define TCG_TARGET_HAS_deposit_i64 1
22
#define TCG_TARGET_HAS_extract_i64 1
23
#define TCG_TARGET_HAS_sextract_i64 0
24
-#define TCG_TARGET_HAS_extract2_i64 0
25
+#define TCG_TARGET_HAS_extract2_i64 1
26
#define TCG_TARGET_HAS_movcond_i64 1
27
#define TCG_TARGET_HAS_add2_i64 1
28
#define TCG_TARGET_HAS_sub2_i64 1
29
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/tcg/i386/tcg-target.inc.c
32
+++ b/tcg/i386/tcg-target.inc.c
33
@@ -XXX,XX +XXX,XX @@ static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
34
#define OPC_SHUFPS (0xc6 | P_EXT)
35
#define OPC_SHLX (0xf7 | P_EXT38 | P_DATA16)
36
#define OPC_SHRX (0xf7 | P_EXT38 | P_SIMDF2)
37
+#define OPC_SHRD_Ib (0xac | P_EXT)
38
#define OPC_TESTL    (0x85)
39
#define OPC_TZCNT (0xbc | P_EXT | P_SIMDF3)
40
#define OPC_UD2 (0x0b | P_EXT)
41
@@ -XXX,XX +XXX,XX @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
42
}
43
break;
44
45
+ OP_32_64(extract2):
46
+ /* Note that SHRD outputs to the r/m operand. */
47
+ tcg_out_modrm(s, OPC_SHRD_Ib + rexw, a2, a0);
48
+ tcg_out8(s, args[3]);
49
+ break;
50
+
51
case INDEX_op_mb:
52
tcg_out_mb(s, a0);
53
break;
54
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
55
static const TCGTargetOpDef r_0 = { .args_ct_str = { "r", "0" } };
56
static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
57
static const TCGTargetOpDef r_r_re = { .args_ct_str = { "r", "r", "re" } };
58
+ static const TCGTargetOpDef r_0_r = { .args_ct_str = { "r", "0", "r" } };
59
static const TCGTargetOpDef r_0_re = { .args_ct_str = { "r", "0", "re" } };
60
static const TCGTargetOpDef r_0_ci = { .args_ct_str = { "r", "0", "ci" } };
61
static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
62
@@ -XXX,XX +XXX,XX @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
63
case INDEX_op_ctpop_i32:
64
case INDEX_op_ctpop_i64:
65
return &r_r;
66
+ case INDEX_op_extract2_i32:
67
+ case INDEX_op_extract2_i64:
68
+ return &r_0_r;
69
70
case INDEX_op_deposit_i32:
71
case INDEX_op_deposit_i64:
72
--
73
2.17.1
74
75
diff view generated by jsdifflib
Deleted patch
1
There is no point in coding for a 2GB offset when the max TB size
2
is already limited to 64k. If we further restrict to 32k then we
3
can eliminate the extra ADDIS instruction.
4
1
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
tcg/ppc/tcg-target.inc.c | 28 ++++++++++------------------
8
1 file changed, 10 insertions(+), 18 deletions(-)
9
10
diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tcg/ppc/tcg-target.inc.c
13
+++ b/tcg/ppc/tcg-target.inc.c
14
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
15
intptr_t value, intptr_t addend)
16
{
17
tcg_insn_unit *target;
18
- tcg_insn_unit old;
19
20
value += addend;
21
target = (tcg_insn_unit *)value;
22
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
23
case R_PPC_REL24:
24
return reloc_pc24(code_ptr, target);
25
case R_PPC_ADDR16:
26
- /* We are abusing this relocation type. This points to a pair
27
- of insns, addis + load. If the displacement is small, we
28
- can nop out the addis. */
29
- if (value == (int16_t)value) {
30
- code_ptr[0] = NOP;
31
- old = deposit32(code_ptr[1], 0, 16, value);
32
- code_ptr[1] = deposit32(old, 16, 5, TCG_REG_TB);
33
- } else {
34
- int16_t lo = value;
35
- int hi = value - lo;
36
- if (hi + lo != value) {
37
- return false;
38
- }
39
- code_ptr[0] = deposit32(code_ptr[0], 0, 16, hi >> 16);
40
- code_ptr[1] = deposit32(code_ptr[1], 0, 16, lo);
41
+ /*
42
+ * We are (slightly) abusing this relocation type. In particular,
43
+ * assert that the low 2 bits are zero, and do not modify them.
44
+ * That way we can use this with LD et al that have opcode bits
45
+ * in the low 2 bits of the insn.
46
+ */
47
+ if ((value & 3) || value != (int16_t)value) {
48
+ return false;
49
}
50
+ *code_ptr = (*code_ptr & ~0xfffc) | (value & 0xfffc);
51
break;
52
default:
53
g_assert_not_reached();
54
@@ -XXX,XX +XXX,XX @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
55
if (!in_prologue && USE_REG_TB) {
56
new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr,
57
-(intptr_t)s->code_gen_ptr);
58
- tcg_out32(s, ADDIS | TAI(ret, TCG_REG_TB, 0));
59
- tcg_out32(s, LD | TAI(ret, ret, 0));
60
+ tcg_out32(s, LD | TAI(ret, TCG_REG_TB, 0));
61
return;
62
}
63
64
--
65
2.17.1
66
67
diff view generated by jsdifflib