Patchwork [v2] tci: Support deposit operations

login
register
mail settings
Submitter Stefan Weil
Date Sept. 18, 2012, 8:52 p.m.
Message ID <1348001534-14189-1-git-send-email-sw@weilnetz.de>
Download mbox | patch
Permalink /patch/184851/
State Accepted
Headers show

Comments

Stefan Weil - Sept. 18, 2012, 8:52 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>
---

The interpreter code for INDEX_op_deposit_i64 was buggy in v1 of this patch.

There is also an alternate implementation of the interpreter part which is
based on deposit32, deposit32 from bitops.h.

The implemention below is a little bit more efficient (smaller and faster).

Regards

Stefan Weil


 tcg/tci/tcg-target.c |   24 ++++++++++++++++++++++++
 tcg/tci/tcg-target.h |    4 ++--
 tci.c                |   22 ++++++++++++++++++++++
 3 files changed, 48 insertions(+), 2 deletions(-)
Stefan Weil - Nov. 18, 2012, 7:39 p.m.
Am 18.09.2012 22:52, schrieb Stefan Weil:
> 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>
> ---
>
> The interpreter code for INDEX_op_deposit_i64 was buggy in v1 of this patch.
>
> There is also an alternate implementation of the interpreter part which is
> based on deposit32, deposit32 from bitops.h.
>
> The implemention below is a little bit more efficient (smaller and faster).
>
> Regards
>
> Stefan Weil
>
>
>   tcg/tci/tcg-target.c |   24 ++++++++++++++++++++++++
>   tcg/tci/tcg-target.h |    4 ++--
>   tci.c                |   22 ++++++++++++++++++++++
>   3 files changed, 48 insertions(+), 2 deletions(-)
>
> diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
> index d272a90..5866b6b 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
> @@ -657,6 +663,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:
> @@ -684,6 +699,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 a4f7b78..21535c7 100644
> --- a/tci.c
> +++ b/tci.c
> @@ -690,6 +690,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);
> @@ -937,6 +948,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_reg64(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);

Blue, could you please commit either this patch or
http://patchwork.ozlabs.org/patch/184852/

Thanks,
Stefan
Blue Swirl - Nov. 18, 2012, 9:10 p.m.
Thanks, applied.


On Tue, Sep 18, 2012 at 8:52 PM, Stefan Weil <sw@weilnetz.de> wrote:
> 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>
> ---
>
> The interpreter code for INDEX_op_deposit_i64 was buggy in v1 of this patch.
>
> There is also an alternate implementation of the interpreter part which is
> based on deposit32, deposit32 from bitops.h.
>
> The implemention below is a little bit more efficient (smaller and faster).
>
> Regards
>
> Stefan Weil
>
>
>  tcg/tci/tcg-target.c |   24 ++++++++++++++++++++++++
>  tcg/tci/tcg-target.h |    4 ++--
>  tci.c                |   22 ++++++++++++++++++++++
>  3 files changed, 48 insertions(+), 2 deletions(-)
>
> diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
> index d272a90..5866b6b 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
> @@ -657,6 +663,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:
> @@ -684,6 +699,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 a4f7b78..21535c7 100644
> --- a/tci.c
> +++ b/tci.c
> @@ -690,6 +690,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);
> @@ -937,6 +948,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_reg64(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);
> --
> 1.7.10
>
>

Patch

diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
index d272a90..5866b6b 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
@@ -657,6 +663,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:
@@ -684,6 +699,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 a4f7b78..21535c7 100644
--- a/tci.c
+++ b/tci.c
@@ -690,6 +690,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);
@@ -937,6 +948,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_reg64(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);