All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: agraf@suse.de, aurelien@aurel32.net
Subject: [Qemu-devel] [PATCH 5/7] tcg-i386: Implement deposit operation.
Date: Mon, 10 Jan 2011 19:23:46 -0800	[thread overview]
Message-ID: <1294716228-9299-6-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1294716228-9299-1-git-send-email-rth@twiddle.net>

Special case deposits that are implementable with byte and word stores.
Otherwise implement with double-word shift plus rotates.

Expose tcg_scratch_alloc to the backend for allocation of scratch registers.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/i386/tcg-target.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++--
 tcg/i386/tcg-target.h |    2 +
 tcg/tcg.c             |   11 ++++++++
 3 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index bb19a95..ba1c45a 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -258,7 +258,8 @@ static inline int tcg_target_const_match(tcg_target_long val,
 #define OPC_JMP_long	(0xe9)
 #define OPC_JMP_short	(0xeb)
 #define OPC_LEA         (0x8d)
-#define OPC_MOVB_EvGv	(0x88)		/* stores, more or less */
+#define OPC_MOVB_EbGb	(0x88)		/* stores, more or less */
+#define OPC_MOVB_GbEb   (0x8a)		/* loads, more or less */
 #define OPC_MOVL_EvGv	(0x89)		/* stores, more or less */
 #define OPC_MOVL_GvEv	(0x8b)		/* loads, more or less */
 #define OPC_MOVL_EvIz	(0xc7)
@@ -277,6 +278,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
 #define OPC_SHIFT_1	(0xd1)
 #define OPC_SHIFT_Ib	(0xc1)
 #define OPC_SHIFT_cl	(0xd3)
+#define OPC_SHRD_Ib	(0xac | P_EXT)
 #define OPC_TESTL	(0x85)
 #define OPC_XCHG_ax_r32	(0x90)
 
@@ -710,6 +712,59 @@ static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
     }
 }
 
+static void tcg_out_deposit(TCGContext *s, int inout, int val,
+                            unsigned ofs, unsigned len, int rexw)
+{
+    /* Look for MOVW special case.  */
+    if (ofs == 0 && len == 16) {
+        tcg_out_modrm(s, OPC_MOVL_GvEv + P_DATA16, inout, val);
+        return;
+    }
+
+    /* Look for MOVB w/ %reg_l special case.  */
+    if (ofs == 0 && len == 8
+        && (TCG_TARGET_REG_BITS == 64 || (inout < 4 && val < 4))) {
+        tcg_out_modrm(s, OPC_MOVB_GbEb + P_REXB_R + P_REXB_RM, inout, val);
+        return;
+    }
+
+    /* Look for MOVB w/ %reg_h special case.  */
+    if (ofs == 8 && len == 8 && inout < 4 && val < 4) {
+        tcg_out_modrm(s, OPC_MOVB_GbEb, inout + 4, val);
+        return;
+    }
+
+    /* If we have a real deposit from self, we need a temporary.  */
+    if (inout == val) {
+        TCGType type = rexw ? TCG_TYPE_I64 : TCG_TYPE_I32;
+        TCGRegSet live;
+
+        tcg_regset_clear(live);
+        tcg_regset_set_reg(live, inout);
+        val = tcg_scratch_alloc(s, type, live);
+
+        tcg_out_mov(s, type, val, inout);
+    }
+
+    /* Arrange for the field to be at offset 0.  */
+    if (ofs != 0) {
+        tcg_out_shifti(s, SHIFT_ROR + rexw, inout, ofs);
+    }
+
+    /* Shift the value into the top of the word.  This shifts the old
+       field out of the bottom of the word and leaves us with the whole
+       word rotated right by the size of the field.  */
+    tcg_out_modrm(s, OPC_SHRD_Ib + rexw, val, inout);
+    tcg_out8(s, len);
+
+    /* Restore the field to its proper location.  */
+    ofs = (len + ofs) & (rexw ? 63 : 31);
+    if (ofs != 0) {
+        tcg_out_shifti(s, SHIFT_ROL + rexw, inout, ofs);
+    }
+}
+
+
 /* Use SMALL != 0 to force a short forward branch.  */
 static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
 {
@@ -1266,7 +1321,7 @@ static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
 
     switch (sizeop) {
     case 0:
-        tcg_out_modrm_offset(s, OPC_MOVB_EvGv + P_REXB_R, datalo, base, ofs);
+        tcg_out_modrm_offset(s, OPC_MOVB_EbGb + P_REXB_R, datalo, base, ofs);
         break;
     case 1:
         if (bswap) {
@@ -1504,7 +1559,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         break;
 
     OP_32_64(st8):
-        tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
+        tcg_out_modrm_offset(s, OPC_MOVB_EbGb | P_REXB_R,
                              args[0], args[1], args[2]);
         break;
     OP_32_64(st16):
@@ -1603,6 +1658,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         }
         break;
 
+    OP_32_64(deposit):
+        tcg_out_deposit(s, args[0], args[2], args[3], args[4], rexw);
+        break;
+
     case INDEX_op_brcond_i32:
         tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
                          args[3], 0);
@@ -1783,6 +1842,7 @@ static const TCGTargetOpDef x86_op_defs[] = {
     { INDEX_op_sar_i32, { "r", "0", "ci" } },
     { INDEX_op_rotl_i32, { "r", "0", "ci" } },
     { INDEX_op_rotr_i32, { "r", "0", "ci" } },
+    { INDEX_op_deposit_i32, { "r", "0", "r" } },
 
     { INDEX_op_brcond_i32, { "r", "ri" } },
 
@@ -1835,6 +1895,7 @@ static const TCGTargetOpDef x86_op_defs[] = {
     { INDEX_op_sar_i64, { "r", "0", "ci" } },
     { INDEX_op_rotl_i64, { "r", "0", "ci" } },
     { INDEX_op_rotr_i64, { "r", "0", "ci" } },
+    { INDEX_op_deposit_i64, { "r", "0", "r" } },
 
     { INDEX_op_brcond_i64, { "r", "re" } },
     { INDEX_op_setcond_i64, { "r", "r", "re" } },
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index bfafbfc..9f90d17 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -77,6 +77,7 @@ enum {
 /* optional instructions */
 #define TCG_TARGET_HAS_div2_i32
 #define TCG_TARGET_HAS_rot_i32
+#define TCG_TARGET_HAS_deposit_i32
 #define TCG_TARGET_HAS_ext8s_i32
 #define TCG_TARGET_HAS_ext16s_i32
 #define TCG_TARGET_HAS_ext8u_i32
@@ -94,6 +95,7 @@ enum {
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_div2_i64
 #define TCG_TARGET_HAS_rot_i64
+#define TCG_TARGET_HAS_deposit_i64
 #define TCG_TARGET_HAS_ext8s_i64
 #define TCG_TARGET_HAS_ext16s_i64
 #define TCG_TARGET_HAS_ext32s_i64
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 5dd6a2c..d190a20 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -156,6 +156,17 @@ int gen_new_label(void)
     return idx;
 }
 
+static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2);
+
+/* For use by backends, allocate a scratch register of TYPE, avoiding
+   any that are present in live.  */
+
+static inline int tcg_scratch_alloc(TCGContext *s, TCGType type, TCGRegSet live)
+{
+    tcg_regset_or (live, s->reserved_regs, live);
+    return tcg_reg_alloc(s, tcg_target_available_regs[type], live);
+}
+
 #include "tcg-target.c"
 
 /* pool based memory allocation */
-- 
1.7.2.3

  parent reply	other threads:[~2011-01-11  3:24 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-11  3:23 [Qemu-devel] [PATCH 0/7] Define "deposit" tcg operation, v2 Richard Henderson
2011-01-11  3:23 ` [Qemu-devel] [PATCH 1/7] tcg: Define "deposit" as an optional operation Richard Henderson
2011-01-11 23:45   ` Aurelien Jarno
2011-01-12 11:00   ` Edgar E. Iglesias
2011-01-11  3:23 ` [Qemu-devel] [PATCH 2/7] tcg-ppc: Implement deposit operation Richard Henderson
2011-01-11 12:40   ` [Qemu-devel] " malc
2011-01-11 16:32     ` Richard Henderson
2011-01-11 19:11       ` malc
2011-01-11  3:23 ` [Qemu-devel] [PATCH 3/7] tcg-hppa: " Richard Henderson
2011-01-11  3:23 ` [Qemu-devel] [PATCH 4/7] tcg-ia64: " Richard Henderson
2011-01-11  3:23 ` Richard Henderson [this message]
2011-01-25 12:27   ` [Qemu-devel] [PATCH 5/7] tcg-i386: " Edgar E. Iglesias
2011-01-25 16:13     ` Richard Henderson
2011-01-25 16:48       ` Edgar E. Iglesias
2011-01-25 22:07         ` Richard Henderson
2011-01-26  8:53           ` Edgar E. Iglesias
2011-01-26  9:23             ` Alexander Graf
2011-01-26 15:50               ` Richard Henderson
2011-01-26 16:00                 ` Alexander Graf
2011-01-26 16:34                   ` Avi Kivity
2011-01-26 16:40                   ` Richard Henderson
2011-01-26 16:50                     ` Alexander Graf
2011-01-26 18:21                       ` Richard Henderson
2011-01-26 18:27                         ` Alexander Graf
2011-01-26 18:55                           ` Richard Henderson
2011-01-26 19:01                             ` Alexander Graf
2011-01-26 19:05                               ` Richard Henderson
2011-01-26 19:09                                 ` Alexander Graf
2011-01-26 19:19                                   ` Richard Henderson
2011-01-26 19:27                                     ` Alexander Graf
2011-01-31  8:33     ` Aurelien Jarno
2011-02-08 18:05       ` Richard Henderson
2011-02-09  7:41         ` [Qemu-devel] " Paolo Bonzini
2011-02-09 17:24           ` Blue Swirl
2011-01-11  3:23 ` [Qemu-devel] [PATCH 6/7] target-i386: Use " Richard Henderson
2011-01-12 11:01   ` Edgar E. Iglesias
2011-01-20 11:06   ` Aurelien Jarno
2011-01-11  3:23 ` [Qemu-devel] [PATCH 7/7] target-ppc: " Richard Henderson
2011-01-11 23:45 ` [Qemu-devel] [PATCH 0/7] Define "deposit" tcg operation, v2 Aurelien Jarno
2011-01-20 11:31 ` Edgar E. Iglesias
  -- strict thread matches above, loose matches on Subject: below --
2011-01-07 22:42 [Qemu-devel] [PATCH 0/7] Define "deposit" tcg operation Richard Henderson
2011-01-07 22:43 ` [Qemu-devel] [PATCH 5/7] tcg-i386: Implement deposit operation Richard Henderson

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=1294716228-9299-6-git-send-email-rth@twiddle.net \
    --to=rth@twiddle.net \
    --cc=agraf@suse.de \
    --cc=aurelien@aurel32.net \
    --cc=qemu-devel@nongnu.org \
    /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.