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] tcg-i386: Introduce specific deposit helpers
Date: Wed, 28 Sep 2011 14:28:07 +0200 [thread overview]
Message-ID: <4E8312D7.4080403@siemens.com> (raw)
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, a version using only a single instruction is feasible.
Introducing such helpers 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>
---
tcg/i386/tcg-target.c | 25 +++++++++++++++++++++++++
tcg/i386/tcg-target.h | 6 ++++++
tcg/tcg-op.h | 12 ++++++++++++
tcg/tcg-opc.h | 6 ++++++
tcg/tcg.h | 3 +++
5 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 281f87d..3f9d0ad 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1747,6 +1747,19 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
#endif
+ OP_32_64(deposit8l):
+ tcg_out_modrm(s, OPC_MOVB_EvGv | P_REXB_R | P_REXB_RM,
+ args[2], args[0]);
+ break;
+
+ OP_32_64(deposit8h):
+ tcg_out_modrm(s, OPC_MOVB_EvGv, args[2], args[0] + 4);
+ break;
+
+ OP_32_64(deposit16l):
+ tcg_out_modrm(s, OPC_MOVL_EvGv | P_DATA16, args[2], args[0]);
+ break;
+
default:
tcg_abort();
}
@@ -1802,6 +1815,14 @@ static const TCGTargetOpDef x86_op_defs[] = {
{ INDEX_op_setcond_i32, { "q", "r", "ri" } },
+#if TCG_TARGET_REG_BITS == 64
+ { INDEX_op_deposit8l_i32, { "r", "0", "r" } },
+#else
+ { INDEX_op_deposit8l_i32, { "abcd", "0", "abcd" } },
+#endif
+ { INDEX_op_deposit8h_i32, { "abcd", "0", "abcd" } },
+ { INDEX_op_deposit16l_i32, { "r", "0", "r" } },
+
#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 +1874,10 @@ 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_deposit8l_i64, { "r", "0", "r" } },
+ { INDEX_op_deposit8h_i64, { "abcd", "0", "abcd" } },
+ { INDEX_op_deposit16l_i64, { "r", "0", "r" } },
#endif
#if TCG_TARGET_REG_BITS == 64
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 5088e47..54b2f60 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -91,6 +91,9 @@ enum {
#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_deposit8l_i32 1
+#define TCG_TARGET_HAS_deposit8h_i32 1
+#define TCG_TARGET_HAS_deposit16l_i32 1
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_div2_i64 1
@@ -112,6 +115,9 @@ enum {
#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_deposit8l_i64 1
+#define TCG_TARGET_HAS_deposit8h_i64 1
+#define TCG_TARGET_HAS_deposit16l_i64 1
#endif
#define TCG_TARGET_HAS_GUEST_BASE
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 404b637..80ffccb 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2047,6 +2047,12 @@ static inline void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1,
{
if (TCG_TARGET_HAS_deposit_i32) {
tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
+ } else if (ofs == 0 && len == 8 && TCG_TARGET_HAS_deposit8l_i32) {
+ tcg_gen_op3_i32(INDEX_op_deposit8l_i32, ret, arg1, arg2);
+ } else if (ofs == 8 && len == 8 && TCG_TARGET_HAS_deposit8h_i32) {
+ tcg_gen_op3_i32(INDEX_op_deposit8h_i32, ret, arg1, arg2);
+ } else if (ofs == 0 && len == 16 && TCG_TARGET_HAS_deposit16l_i32) {
+ tcg_gen_op3_i32(INDEX_op_deposit16l_i32, ret, arg1, arg2);
} else {
uint32_t mask = (1u << len) - 1;
TCGv_i32 t1 = tcg_temp_new_i32 ();
@@ -2066,6 +2072,12 @@ static inline void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1,
{
if (TCG_TARGET_HAS_deposit_i64) {
tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
+ } else if (ofs == 0 && len == 8 && TCG_TARGET_HAS_deposit8l_i64) {
+ tcg_gen_op3_i32(INDEX_op_deposit8l_i64, ret, arg1, arg2);
+ } else if (ofs == 8 && len == 8 && TCG_TARGET_HAS_deposit8h_i64) {
+ tcg_gen_op3_i32(INDEX_op_deposit8h_i64, ret, arg1, arg2);
+ } else if (ofs == 0 && len == 16 && TCG_TARGET_HAS_deposit16l_i64) {
+ tcg_gen_op3_i32(INDEX_op_deposit16l_i64, ret, arg1, arg2);
} else {
uint64_t mask = (1ull << len) - 1;
TCGv_i64 t1 = tcg_temp_new_i64 ();
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index 8e06d03..0871d15 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -80,6 +80,9 @@ DEF(sar_i32, 1, 2, 0, 0)
DEF(rotl_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32))
DEF(rotr_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32))
DEF(deposit_i32, 1, 2, 2, IMPL(TCG_TARGET_HAS_deposit_i32))
+DEF(deposit8l_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_deposit8l_i32))
+DEF(deposit8h_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_deposit8h_i32))
+DEF(deposit16l_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_deposit16l_i32))
DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
@@ -139,6 +142,9 @@ DEF(sar_i64, 1, 2, 0, IMPL64)
DEF(rotl_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
DEF(rotr_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
DEF(deposit_i64, 1, 2, 2, IMPL64 | IMPL(TCG_TARGET_HAS_deposit_i64))
+DEF(deposit8l_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_deposit8l_i64))
+DEF(deposit8h_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_deposit8h_i64))
+DEF(deposit16l_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_deposit16l_i64))
DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS | IMPL64)
DEF(ext8s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8s_i64))
diff --git a/tcg/tcg.h b/tcg/tcg.h
index dc5e9c9..9a95d2b 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -69,6 +69,9 @@ typedef uint64_t TCGRegSet;
#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_deposit8l_i64 0
+#define TCG_TARGET_HAS_deposit8h_i64 0
+#define TCG_TARGET_HAS_deposit16l_i64 0
#endif
/* Only one of DIV or DIV2 should be defined. */
--
1.7.3.4
next reply other threads:[~2011-09-28 12:28 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-28 12:28 Jan Kiszka [this message]
2011-09-28 14:26 ` [Qemu-devel] [PATCH] tcg-i386: Introduce specific deposit helpers 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 ` [Qemu-devel] [PATCH v4] " Jan Kiszka
2011-09-29 19:50 ` 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=4E8312D7.4080403@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.