Patchwork tci: Support deposit operations

login
register
mail settings
Submitter Stefan Weil
Date Sept. 8, 2012, 2:12 p.m.
Message ID <1347113540-32047-1-git-send-email-sw@weilnetz.de>
Download mbox | patch
Permalink /patch/182580/
State Superseded
Headers show

Comments

Stefan Weil - Sept. 8, 2012, 2:12 p.m.
The operations for INDEX_op_deposit_i32 and INDEX_op_deposit_i64
are now supported and enabled by default.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
---
 tcg/tci/tcg-target.c |   24 ++++++++++++++++++++++++
 tcg/tci/tcg-target.h |    4 ++--
 tci.c                |   22 ++++++++++++++++++++++
 3 files changed, 48 insertions(+), 2 deletions(-)
Richard Henderson - Sept. 10, 2012, 2:08 p.m.
On Sat, 2012-09-08 at 16:12 +0200, Stefan Weil wrote:
> +            tmp16 = *tb_ptr++;
> +            tmp8 = *tb_ptr++;
> +            tmp32 = (((1 << tmp8) - 1) << tmp16);
> +            tci_write_reg32(t0, (t1 & ~tmp32) | ((t2 << tmp16) &
> tmp32));

Use the deposit* functions from bitops.h?


r~
Stefan Weil - Sept. 14, 2012, 7:12 p.m.
Am 10.09.2012 16:08, schrieb Richard Henderson:
> On Sat, 2012-09-08 at 16:12 +0200, Stefan Weil wrote:
>> +            tmp16 = *tb_ptr++;
>> +            tmp8 = *tb_ptr++;
>> +            tmp32 = (((1<<  tmp8) - 1)<<  tmp16);
>> +            tci_write_reg32(t0, (t1&  ~tmp32) | ((t2<<  tmp16)&
>> tmp32));
>
> Use the deposit* functions from bitops.h?
>
>
> r~


Well, that would justify their existence in bitops.h, wouldn't it?

When I wrote deposit for TCI (November 2011), there still
was no bitops.h, and I was just too lazy to modify and test the
code again.

Now I tested code with both my version (with a small correction for
the 64 bit variant) and with the deposit* functions.

Both variants give identical results. The deposit* variant
creates larger (and I expect also less efficient) code.
I doubt that the effect will be measurable in a system emulation.

Results with 64 bit Debian Linux:

my variant
    6909       0     128    7037    1b7d 
bin/ndebug/x86-tci/i386-linux-user/tci.o
    6975       0     128    7103    1bbf 
bin/ndebug/x86-tci/i386-softmmu/tci.o
    6917       0     128    7045    1b85 
bin/ndebug/x86-tci/x86_64-linux-user/tci.o
    6972       0     128    7100    1bbc 
bin/ndebug/x86-tci/x86_64-softmmu/tci.o

deposit*
    6935       0     128    7063    1b97 
bin/ndebug/x86-tci/i386-linux-user/tci.o
    7000       0     128    7128    1bd8 
bin/ndebug/x86-tci/i386-softmmu/tci.o
    6963       0     128    7091    1bb3 
bin/ndebug/x86-tci/x86_64-linux-user/tci.o
    6997       0     128    7125    1bd5 
bin/ndebug/x86-tci/x86_64-softmmu/tci.o

Other emulation targets show similar differences.

On a Windows host, the difference was smaller, but still in favour of my 
code.

Regards,
Stefan

Patch

diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
index ef8580f..7124b15 100644
--- a/tcg/tci/tcg-target.c
+++ b/tcg/tci/tcg-target.c
@@ -123,6 +123,9 @@  static const TCGTargetOpDef tcg_target_op_defs[] = {
     { INDEX_op_rotl_i32, { R, RI, RI } },
     { INDEX_op_rotr_i32, { R, RI, RI } },
 #endif
+#if TCG_TARGET_HAS_deposit_i32
+    { INDEX_op_deposit_i32, { R, "0", R } },
+#endif
 
     { INDEX_op_brcond_i32, { R, RI } },
 
@@ -201,6 +204,9 @@  static const TCGTargetOpDef tcg_target_op_defs[] = {
     { INDEX_op_rotl_i64, { R, RI, RI } },
     { INDEX_op_rotr_i64, { R, RI, RI } },
 #endif
+#if TCG_TARGET_HAS_deposit_i64
+    { INDEX_op_deposit_i64, { R, "0", R } },
+#endif
     { INDEX_op_brcond_i64, { R, RI } },
 
 #if TCG_TARGET_HAS_ext8s_i64
@@ -655,6 +661,15 @@  static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out_ri32(s, const_args[1], args[1]);
         tcg_out_ri32(s, const_args[2], args[2]);
         break;
+    case INDEX_op_deposit_i32:  /* Optional (TCG_TARGET_HAS_deposit_i32). */
+        tcg_out_r(s, args[0]);
+        tcg_out_r(s, args[1]);
+        tcg_out_r(s, args[2]);
+        assert(args[3] <= UINT8_MAX);
+        tcg_out8(s, args[3]);
+        assert(args[4] <= UINT8_MAX);
+        tcg_out8(s, args[4]);
+        break;
 
 #if TCG_TARGET_REG_BITS == 64
     case INDEX_op_mov_i64:
@@ -682,6 +697,15 @@  static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out_ri64(s, const_args[1], args[1]);
         tcg_out_ri64(s, const_args[2], args[2]);
         break;
+    case INDEX_op_deposit_i64:  /* Optional (TCG_TARGET_HAS_deposit_i64). */
+        tcg_out_r(s, args[0]);
+        tcg_out_r(s, args[1]);
+        tcg_out_r(s, args[2]);
+        assert(args[3] <= UINT8_MAX);
+        tcg_out8(s, args[3]);
+        assert(args[4] <= UINT8_MAX);
+        tcg_out8(s, args[4]);
+        break;
     case INDEX_op_div_i64:      /* Optional (TCG_TARGET_HAS_div_i64). */
     case INDEX_op_divu_i64:     /* Optional (TCG_TARGET_HAS_div_i64). */
     case INDEX_op_rem_i64:      /* Optional (TCG_TARGET_HAS_div_i64). */
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 30a0f21..f7ca8be 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -67,7 +67,7 @@ 
 #define TCG_TARGET_HAS_ext8u_i32        1
 #define TCG_TARGET_HAS_ext16u_i32       1
 #define TCG_TARGET_HAS_andc_i32         0
-#define TCG_TARGET_HAS_deposit_i32      0
+#define TCG_TARGET_HAS_deposit_i32      1
 #define TCG_TARGET_HAS_eqv_i32          0
 #define TCG_TARGET_HAS_nand_i32         0
 #define TCG_TARGET_HAS_nor_i32          0
@@ -80,7 +80,7 @@ 
 #define TCG_TARGET_HAS_bswap16_i64      1
 #define TCG_TARGET_HAS_bswap32_i64      1
 #define TCG_TARGET_HAS_bswap64_i64      1
-#define TCG_TARGET_HAS_deposit_i64      0
+#define TCG_TARGET_HAS_deposit_i64      1
 /* Not more than one of the next two defines must be 1. */
 #define TCG_TARGET_HAS_div_i64          0
 #define TCG_TARGET_HAS_div2_i64         0
diff --git a/tci.c b/tci.c
index c79350d..01d365a 100644
--- a/tci.c
+++ b/tci.c
@@ -697,6 +697,17 @@  tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             tci_write_reg32(t0, (t1 >> t2) | (t1 << (32 - t2)));
             break;
 #endif
+#if TCG_TARGET_HAS_deposit_i32
+        case INDEX_op_deposit_i32:
+            t0 = *tb_ptr++;
+            t1 = tci_read_r32(&tb_ptr);
+            t2 = tci_read_r32(&tb_ptr);
+            tmp16 = *tb_ptr++;
+            tmp8 = *tb_ptr++;
+            tmp32 = (((1 << tmp8) - 1) << tmp16);
+            tci_write_reg32(t0, (t1 & ~tmp32) | ((t2 << tmp16) & tmp32));
+            break;
+#endif
         case INDEX_op_brcond_i32:
             t0 = tci_read_r32(&tb_ptr);
             t1 = tci_read_ri32(&tb_ptr);
@@ -944,6 +955,17 @@  tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             TODO();
             break;
 #endif
+#if TCG_TARGET_HAS_deposit_i64
+        case INDEX_op_deposit_i64:
+            t0 = *tb_ptr++;
+            t1 = tci_read_r64(&tb_ptr);
+            t2 = tci_read_r64(&tb_ptr);
+            tmp16 = *tb_ptr++;
+            tmp8 = *tb_ptr++;
+            tmp64 = (((1ULL << tmp8) - 1) << tmp16);
+            tci_write_reg32(t0, (t1 & ~tmp64) | ((t2 << tmp16) & tmp64));
+            break;
+#endif
         case INDEX_op_brcond_i64:
             t0 = tci_read_r64(&tb_ptr);
             t1 = tci_read_ri64(&tb_ptr);