[PATCH 2/2] tcg: possibly convert deposit_z to shl+shr

Paolo Bonzini posted 2 patches 3 weeks, 4 days ago
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>
[PATCH 2/2] tcg: possibly convert deposit_z to shl+shr
Posted by Paolo Bonzini 3 weeks, 4 days ago
extract and deposit_z are similar operations, only differing in
that extract shifts the operand right and deposit_z shifts it left.
Like extract, it is possible to implement deposit_z as either AND+SHL or
SHL+SHR.  Use tcg_op_imm_match to check whether the processor supports the
immediate that is needed for the mask, and if not fall back to two shifts.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tcg/tcg-op.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index ccf66382623..e7d6702f9c4 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -960,8 +960,18 @@ void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
             tcg_gen_extract_i32(ret, ret, 0, ofs + len);
             return;
         }
-        tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
-        tcg_gen_shli_i32(ret, ret, ofs);
+        /*
+         * Use TCG_TARGET_extract_valid to check for 8- and 16-bit extension
+         * opcodes, which tcg_gen_andi_i32 can produce.
+         */
+        if (TCG_TARGET_extract_valid(TCG_TYPE_I32, 0, len) ||
+            tcg_op_imm_match(INDEX_op_and, TCG_TYPE_I32, (1u << len) - 1)) {
+            tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
+            tcg_gen_shli_i32(ret, ret, ofs);
+        } else {
+            tcg_gen_shli_i32(ret, arg, 32 - len);
+            tcg_gen_shri_i32(ret, ret, 32 - len - ofs);
+        }
     }
 }
 
@@ -2628,8 +2638,18 @@ void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
             tcg_gen_extract_i64(ret, ret, 0, ofs + len);
             return;
         }
-        tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
-        tcg_gen_shli_i64(ret, ret, ofs);
+        /*
+         * Use TCG_TARGET_extract_valid to check for 8-, 16- and 32-bit extension
+         * opcodes, which tcg_gen_andi_i64 can produce.
+         */
+        if (TCG_TARGET_extract_valid(TCG_TYPE_I64, 0, len) ||
+	    tcg_op_imm_match(INDEX_op_and, TCG_TYPE_I64, (1ull << len) - 1)) {
+            tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
+            tcg_gen_shli_i64(ret, ret, ofs);
+        } else {
+            tcg_gen_shli_i64(ret, arg, 64 - len);
+            tcg_gen_shri_i64(ret, ret, 64 - len - ofs);
+        }
     }
 }
 
-- 
2.52.0
Re: [PATCH 2/2] tcg: possibly convert deposit_z to shl+shr
Posted by Jim MacArthur 3 weeks, 3 days ago
On 1/15/26 13:54, Paolo Bonzini wrote:
>   
> @@ -2628,8 +2638,18 @@ void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
>               tcg_gen_extract_i64(ret, ret, 0, ofs + len);
>               return;
>           }
> -        tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
> -        tcg_gen_shli_i64(ret, ret, ofs);
> +        /*
> +         * Use TCG_TARGET_extract_valid to check for 8-, 16- and 32-bit extension
> +         * opcodes, which tcg_gen_andi_i64 can produce.
> +         */
> +        if (TCG_TARGET_extract_valid(TCG_TYPE_I64, 0, len) ||
> +	    tcg_op_imm_match(INDEX_op_and, TCG_TYPE_I64, (1ull << len) - 1)) {
> +            tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
> +            tcg_gen_shli_i64(ret, ret, ofs);
> +        } else {
> +            tcg_gen_shli_i64(ret, arg, 64 - len);
> +            tcg_gen_shri_i64(ret, ret, 64 - len - ofs);
> +        }
>       }
>   }
>   

Also just a couple of coding standards issues - "Use 
TCG_TARGET_extract_valid" comment is over 80 characters and you have a 
tab at the start of the call to tcp_op_imm_match. Otherwise, looks good.

Jim