[PATCH v2 20/30] tcg/loongarch64: Implement setcond ops

WANG Xuerui posted 30 patches 4 years, 2 months ago
Maintainers: WANG Xuerui <git@xen0n.name>, Riku Voipio <riku.voipio@iki.fi>, Laurent Vivier <laurent@vivier.eu>, Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <richard.henderson@linaro.org>
There is a newer version of this series
[PATCH v2 20/30] tcg/loongarch64: Implement setcond ops
Posted by WANG Xuerui 4 years, 2 months ago
Signed-off-by: WANG Xuerui <git@xen0n.name>
---
 tcg/loongarch64/tcg-target.c.inc | 74 ++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index b0600a3dbd..08e6541dcf 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -386,6 +386,73 @@ static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc,
     tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
 }
 
+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
+                            TCGReg arg1, TCGReg arg2, bool c1, bool c2)
+{
+    TCGReg tmp;
+
+    if (c1) {
+        tcg_debug_assert(arg1 == 0);
+    }
+    if (c2) {
+        tcg_debug_assert(arg2 == 0);
+    }
+
+    switch (cond) {
+    case TCG_COND_EQ:
+        if (c1) {
+            tmp = arg2;
+        } else if (c2) {
+            tmp = arg1;
+        } else {
+            tcg_out_opc_sub_d(s, ret, arg1, arg2);
+            tmp = ret;
+        }
+        tcg_out_opc_sltui(s, ret, tmp, 1);
+        break;
+    case TCG_COND_NE:
+        if (c1) {
+            tmp = arg2;
+        } else if (c2) {
+            tmp = arg1;
+        } else {
+            tcg_out_opc_sub_d(s, ret, arg1, arg2);
+            tmp = ret;
+        }
+        tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp);
+        break;
+    case TCG_COND_LT:
+        tcg_out_opc_slt(s, ret, arg1, arg2);
+        break;
+    case TCG_COND_GE:
+        tcg_out_opc_slt(s, ret, arg1, arg2);
+        tcg_out_opc_xori(s, ret, ret, 1);
+        break;
+    case TCG_COND_LE:
+        tcg_out_setcond(s, TCG_COND_GE, ret, arg2, arg1, c2, c1);
+        break;
+    case TCG_COND_GT:
+        tcg_out_setcond(s, TCG_COND_LT, ret, arg2, arg1, c2, c1);
+        break;
+    case TCG_COND_LTU:
+        tcg_out_opc_sltu(s, ret, arg1, arg2);
+        break;
+    case TCG_COND_GEU:
+        tcg_out_opc_sltu(s, ret, arg1, arg2);
+        tcg_out_opc_xori(s, ret, ret, 1);
+        break;
+    case TCG_COND_LEU:
+        tcg_out_setcond(s, TCG_COND_GEU, ret, arg2, arg1, c2, c1);
+        break;
+    case TCG_COND_GTU:
+        tcg_out_setcond(s, TCG_COND_LTU, ret, arg2, arg1, c2, c1);
+        break;
+    default:
+        g_assert_not_reached();
+        break;
+    }
+}
+
 /*
  * Branch helpers
  */
@@ -768,6 +835,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_opc_mod_du(s, a0, a1, a2);
         break;
 
+    case INDEX_op_setcond_i32:
+    case INDEX_op_setcond_i64:
+        tcg_out_setcond(s, args[3], a0, a1, a2, const_args[1], c2);
+        break;
+
     case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
     case INDEX_op_mov_i64:
     default:
@@ -877,6 +949,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_rem_i64:
     case INDEX_op_remu_i32:
     case INDEX_op_remu_i64:
+    case INDEX_op_setcond_i32:
+    case INDEX_op_setcond_i64:
         return C_O1_I2(r, rZ, rZ);
 
     default:
-- 
2.33.0


Re: [PATCH v2 20/30] tcg/loongarch64: Implement setcond ops
Posted by Richard Henderson 4 years, 2 months ago
On 9/21/21 1:19 PM, WANG Xuerui wrote:
> +static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
> +                            TCGReg arg1, TCGReg arg2, bool c1, bool c2)
> +{
> +    TCGReg tmp;
> +
> +    if (c1) {
> +        tcg_debug_assert(arg1 == 0);
> +    }
> +    if (c2) {
> +        tcg_debug_assert(arg2 == 0);
> +    }

You don't need to work quite this hard.  Only the second argument will be constant.  If 
both are constant, we will have folded the operation away.  If the first argument was 
constant, we will swap the condition.

> +    switch (cond) {
> +    case TCG_COND_EQ:
> +        if (c1) {
> +            tmp = arg2;
> +        } else if (c2) {
> +            tmp = arg1;
> +        } else {
> +            tcg_out_opc_sub_d(s, ret, arg1, arg2);

     if (!c2) {
         ...
     }

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

Re: [PATCH v2 20/30] tcg/loongarch64: Implement setcond ops
Posted by WANG Xuerui 4 years, 2 months ago
Hi Richard,

On 9/22/21 23:13, Richard Henderson wrote:
> On 9/21/21 1:19 PM, WANG Xuerui wrote:
>> +static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
>> +                            TCGReg arg1, TCGReg arg2, bool c1, bool c2)
>> +{
>> +    TCGReg tmp;
>> +
>> +    if (c1) {
>> +        tcg_debug_assert(arg1 == 0);
>> +    }
>> +    if (c2) {
>> +        tcg_debug_assert(arg2 == 0);
>> +    }
>
> You don't need to work quite this hard.  Only the second argument will 
> be constant.  If both are constant, we will have folded the operation 
> away.  If the first argument was constant, we will swap the condition.
Thanks for the clarification; again something I didn't discover during 
my (often cursory) read of tcg middle-end code. I'll drop all the c1 
thing in v3.