From: Jan Kiszka <jan.kiszka@siemens.com>
To: qemu-devel <qemu-devel@nongnu.org>
Cc: Blue Swirl <blauwirbel@gmail.com>,
Aurelien Jarno <aurelien@aurel32.net>,
Richard Henderson <rth@twiddle.net>
Subject: [Qemu-devel] [PATCH v4] tcg-i386: Introduce limited deposit support
Date: Thu, 29 Sep 2011 18:52:11 +0200 [thread overview]
Message-ID: <4E84A23B.2030405@siemens.com> (raw)
In-Reply-To: <4E8498BD.10800@twiddle.net>
On 2011-09-29 18:11, Richard Henderson wrote:
> On 09/29/2011 08:23 AM, Jan Kiszka wrote:
>> +#ifndef TCG_TARGET_deposit_i32_valid
>> +#define TCG_TARGET_deposit_i32_valid(ofs, len) 0
>> +#endif
>> +#ifndef TCG_TARGET_deposit_i64_valid
>> +#define TCG_TARGET_deposit_i64_valid(ofs, len) 0
>> +#endif
>
> Err, no. The default is true. The targets that currently
> implement deposit at present can handle arbitrary inputs.
Grr, of course.
---
x86 cannot provide an optimized generic deposit implementation. But at
least for a few special cases, namely for writing bits 0..7, 8..15, and
0..15, versions using only a single instruction are feasible.
Introducing such limited support improves emulating 16-bit x86 code on
x86, but also rarer cases where 32-bit or 64-bit code accesses bytes or
words.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
Changes in v4:
- provide correct default TCG_TARGET_deposit_i32_valid
Changes in v3:
- provide default TCG_TARGET_deposit_i32_valid - just in case
Changes in v2:
- introduce restricting predicates TCG_TARGET_deposit_i32/64_valid
to decide if deposit support can be used
- express register constraints via new 'Q' symbol
tcg/i386/tcg-target.c | 24 ++++++++++++++++++++++++
tcg/i386/tcg-target.h | 9 +++++++--
tcg/tcg-op.h | 4 ++--
tcg/tcg.h | 7 +++++++
4 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 281f87d..3069e53 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -168,6 +168,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
tcg_regset_set32(ct->u.regs, 0, 0xf);
}
break;
+ case 'Q':
+ ct->ct |= TCG_CT_REG;
+ tcg_regset_set32(ct->u.regs, 0, 0xf);
+ break;
case 'r':
ct->ct |= TCG_CT_REG;
if (TCG_TARGET_REG_BITS == 64) {
@@ -1747,6 +1751,22 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
#endif
+ OP_32_64(deposit):
+ if (args[3] == 0 && args[4] == 8) {
+ /* load bits 0..7 */
+ tcg_out_modrm(s, OPC_MOVB_EvGv | P_REXB_R | P_REXB_RM,
+ args[2], args[0]);
+ } else if (args[3] == 8 && args[4] == 8) {
+ /* load bits 8..15 */
+ tcg_out_modrm(s, OPC_MOVB_EvGv, args[2], args[0] + 4);
+ } else if (args[3] == 0 && args[4] == 16) {
+ /* load bits 0..15 */
+ tcg_out_modrm(s, OPC_MOVL_EvGv | P_DATA16, args[2], args[0]);
+ } else {
+ tcg_abort();
+ }
+ break;
+
default:
tcg_abort();
}
@@ -1802,6 +1822,8 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_setcond_i32, { "q", "r", "ri" } },
+ { INDEX_op_deposit_i32, { "Q", "0", "Q" } },
+
#if TCG_TARGET_REG_BITS == 32
{ INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
{ INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
@@ -1853,6 +1875,8 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_ext8u_i64, { "r", "r" } },
{ INDEX_op_ext16u_i64, { "r", "r" } },
{ INDEX_op_ext32u_i64, { "r", "r" } },
+
+ { INDEX_op_deposit_i64, { "Q", "0", "Q" } },
#endif
#if TCG_TARGET_REG_BITS == 64
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 5088e47..b9c9d4e 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -90,7 +90,7 @@ enum {
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
-#define TCG_TARGET_HAS_deposit_i32 0
+#define TCG_TARGET_HAS_deposit_i32 1
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_div2_i64 1
@@ -111,9 +111,14 @@ enum {
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
-#define TCG_TARGET_HAS_deposit_i64 0
+#define TCG_TARGET_HAS_deposit_i64 1
#endif
+#define TCG_TARGET_deposit_i32_valid(ofs, len) \
+ (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \
+ ((ofs) == 0 && (len) == 16))
+#define TCG_TARGET_deposit_i64_valid TCG_TARGET_deposit_i32_valid
+
#define TCG_TARGET_HAS_GUEST_BASE
/* Note: must be synced with dyngen-exec.h */
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 404b637..fea5983 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2045,7 +2045,7 @@ static inline void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1,
TCGv_i32 arg2, unsigned int ofs,
unsigned int len)
{
- if (TCG_TARGET_HAS_deposit_i32) {
+ if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
} else {
uint32_t mask = (1u << len) - 1;
@@ -2064,7 +2064,7 @@ static inline void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1,
TCGv_i64 arg2, unsigned int ofs,
unsigned int len)
{
- if (TCG_TARGET_HAS_deposit_i64) {
+ if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
} else {
uint64_t mask = (1ull << len) - 1;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index dc5e9c9..c7197f5 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -71,6 +71,13 @@ typedef uint64_t TCGRegSet;
#define TCG_TARGET_HAS_deposit_i64 0
#endif
+#ifndef TCG_TARGET_deposit_i32_valid
+#define TCG_TARGET_deposit_i32_valid(ofs, len) 1
+#endif
+#ifndef TCG_TARGET_deposit_i64_valid
+#define TCG_TARGET_deposit_i64_valid(ofs, len) 1
+#endif
+
/* Only one of DIV or DIV2 should be defined. */
#if defined(TCG_TARGET_HAS_div_i32)
#define TCG_TARGET_HAS_div2_i32 0
--
1.7.3.4
next prev parent reply other threads:[~2011-09-29 16:52 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-28 12:28 [Qemu-devel] [PATCH] tcg-i386: Introduce specific deposit helpers Jan Kiszka
2011-09-28 14:26 ` Richard Henderson
2011-09-28 14:33 ` Jan Kiszka
2011-09-28 15:19 ` Richard Henderson
2011-09-28 22:07 ` Jan Kiszka
2011-09-28 22:47 ` Richard Henderson
2011-09-29 11:31 ` [Qemu-devel] [PATCH v2] tcg-i386: Introduce limited deposit support Jan Kiszka
2011-09-29 14:58 ` Richard Henderson
2011-09-29 15:19 ` Jan Kiszka
2011-09-29 15:23 ` [Qemu-devel] [PATCH v3] " Jan Kiszka
2011-09-29 16:11 ` Richard Henderson
2011-09-29 16:52 ` Jan Kiszka [this message]
2011-09-29 19:50 ` [Qemu-devel] [PATCH v4] " Richard Henderson
2011-10-01 12:06 ` Blue Swirl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4E84A23B.2030405@siemens.com \
--to=jan.kiszka@siemens.com \
--cc=aurelien@aurel32.net \
--cc=blauwirbel@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.