[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3] tcg-i386: Introduce limited deposit support
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH v3] tcg-i386: Introduce limited deposit support |
Date: |
Thu, 29 Sep 2011 17:23:43 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 |
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 <address@hidden>
---
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..520255a 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) 0
+#endif
+#ifndef TCG_TARGET_deposit_i64_valid
+#define TCG_TARGET_deposit_i64_valid(ofs, len) 0
+#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
- [Qemu-devel] [PATCH] tcg-i386: Introduce specific deposit helpers, Jan Kiszka, 2011/09/28
- Re: [Qemu-devel] [PATCH] tcg-i386: Introduce specific deposit helpers, Richard Henderson, 2011/09/28
- Re: [Qemu-devel] [PATCH] tcg-i386: Introduce specific deposit helpers, Jan Kiszka, 2011/09/28
- Re: [Qemu-devel] [PATCH] tcg-i386: Introduce specific deposit helpers, Richard Henderson, 2011/09/28
- Re: [Qemu-devel] [PATCH] tcg-i386: Introduce specific deposit helpers, Jan Kiszka, 2011/09/28
- Re: [Qemu-devel] [PATCH] tcg-i386: Introduce specific deposit helpers, Richard Henderson, 2011/09/28
- [Qemu-devel] [PATCH v2] tcg-i386: Introduce limited deposit support, Jan Kiszka, 2011/09/29
- Re: [Qemu-devel] [PATCH v2] tcg-i386: Introduce limited deposit support, Richard Henderson, 2011/09/29
- Re: [Qemu-devel] [PATCH v2] tcg-i386: Introduce limited deposit support, Jan Kiszka, 2011/09/29
- [Qemu-devel] [PATCH v3] tcg-i386: Introduce limited deposit support,
Jan Kiszka <=
- Re: [Qemu-devel] [PATCH v3] tcg-i386: Introduce limited deposit support, Richard Henderson, 2011/09/29
- [Qemu-devel] [PATCH v4] tcg-i386: Introduce limited deposit support, Jan Kiszka, 2011/09/29
- Re: [Qemu-devel] [PATCH v4] tcg-i386: Introduce limited deposit support, Richard Henderson, 2011/09/29