diff mbox series

[v4,072/163] tcg/loongarch64: Support negsetcond

Message ID 20250415192515.232910-73-richard.henderson@linaro.org
State New
Headers show
Series tcg: Convert to TCGOutOp structures | expand

Commit Message

Richard Henderson April 15, 2025, 7:23 p.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/loongarch64/tcg-target-con-set.h |  2 --
 tcg/loongarch64/tcg-target-has.h     |  4 ++--
 tcg/loongarch64/tcg-target.c.inc     | 34 ++++++++++++++++++++++------
 3 files changed, 29 insertions(+), 11 deletions(-)

Comments

Pierrick Bouvier April 15, 2025, 9:19 p.m. UTC | #1
On 4/15/25 12:23, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/loongarch64/tcg-target-con-set.h |  2 --
>   tcg/loongarch64/tcg-target-has.h     |  4 ++--
>   tcg/loongarch64/tcg-target.c.inc     | 34 ++++++++++++++++++++++------
>   3 files changed, 29 insertions(+), 11 deletions(-)
> 
> diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h
> index da84e4d49c..c145d4ab66 100644
> --- a/tcg/loongarch64/tcg-target-con-set.h
> +++ b/tcg/loongarch64/tcg-target-con-set.h
> @@ -29,8 +29,6 @@ C_O1_I2(r, r, rJ)
>   C_O1_I2(r, r, rU)
>   C_O1_I2(r, r, rW)
>   C_O1_I2(r, 0, rz)
> -C_O1_I2(r, rz, ri)
> -C_O1_I2(r, rz, rJ)
>   C_O1_I2(w, w, w)
>   C_O1_I2(w, w, wM)
>   C_O1_I2(w, w, wA)
> diff --git a/tcg/loongarch64/tcg-target-has.h b/tcg/loongarch64/tcg-target-has.h
> index 12a721b4da..e9bb913961 100644
> --- a/tcg/loongarch64/tcg-target-has.h
> +++ b/tcg/loongarch64/tcg-target-has.h
> @@ -10,7 +10,7 @@
>   #include "host/cpuinfo.h"
>   
>   /* optional instructions */
> -#define TCG_TARGET_HAS_negsetcond_i32   0
> +#define TCG_TARGET_HAS_negsetcond_i32   1
>   #define TCG_TARGET_HAS_extract2_i32     0
>   #define TCG_TARGET_HAS_add2_i32         0
>   #define TCG_TARGET_HAS_sub2_i32         0
> @@ -19,7 +19,7 @@
>   #define TCG_TARGET_HAS_qemu_st8_i32     0
>   
>   /* 64-bit operations */
> -#define TCG_TARGET_HAS_negsetcond_i64   0
> +#define TCG_TARGET_HAS_negsetcond_i64   1
>   #define TCG_TARGET_HAS_extract2_i64     0
>   #define TCG_TARGET_HAS_extr_i64_i32     1
>   #define TCG_TARGET_HAS_bswap16_i64      1
> diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
> index aed1d9712d..c4f908f3ae 100644
> --- a/tcg/loongarch64/tcg-target.c.inc
> +++ b/tcg/loongarch64/tcg-target.c.inc
> @@ -634,14 +634,29 @@ static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
>   }
>   
>   static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
> -                            TCGReg arg1, tcg_target_long arg2, bool c2)
> +                            TCGReg arg1, tcg_target_long arg2,
> +                            bool c2, bool neg)
>   {
>       int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2, c2);
> +    TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
>   
> -    if (tmpflags != ret) {
> -        TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
> -
> +    if (neg) {
> +        /* If intermediate result is zero/non-zero: test != 0. */
> +        if (tmpflags & SETCOND_NEZ) {
> +            tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp);
> +            tmp = ret;
> +        }
> +        /* Produce the 0/-1 result. */
> +        if (tmpflags & SETCOND_INV) {
> +            tcg_out_opc_addi_d(s, ret, tmp, -1);
> +        } else {
> +            tcg_out_opc_sub_d(s, ret, TCG_REG_ZERO, tmp);
> +        }
> +    } else {
>           switch (tmpflags & SETCOND_FLAGS) {
> +        case 0:
> +            tcg_debug_assert(tmp == ret);
> +            break;
>           case SETCOND_INV:
>               /* Intermediate result is boolean: simply invert. */
>               tcg_out_opc_xori(s, ret, tmp, 1);
> @@ -1788,7 +1803,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
>   
>       case INDEX_op_setcond_i32:
>       case INDEX_op_setcond_i64:
> -        tcg_out_setcond(s, args[3], a0, a1, a2, c2);
> +        tcg_out_setcond(s, args[3], a0, a1, a2, c2, false);
> +        break;
> +    case INDEX_op_negsetcond_i32:
> +    case INDEX_op_negsetcond_i64:
> +        tcg_out_setcond(s, args[3], a0, a1, a2, c2, true);
>           break;
>   
>       case INDEX_op_movcond_i32:
> @@ -2428,9 +2447,10 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
>           return C_O1_I2(r, 0, rz);
>   
>       case INDEX_op_setcond_i32:
> -        return C_O1_I2(r, rz, ri);
>       case INDEX_op_setcond_i64:
> -        return C_O1_I2(r, rz, rJ);
> +    case INDEX_op_negsetcond_i32:
> +    case INDEX_op_negsetcond_i64:
> +        return C_O1_I2(r, r, rJ);
>   
>       case INDEX_op_movcond_i32:
>       case INDEX_op_movcond_i64:

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
diff mbox series

Patch

diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h
index da84e4d49c..c145d4ab66 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -29,8 +29,6 @@  C_O1_I2(r, r, rJ)
 C_O1_I2(r, r, rU)
 C_O1_I2(r, r, rW)
 C_O1_I2(r, 0, rz)
-C_O1_I2(r, rz, ri)
-C_O1_I2(r, rz, rJ)
 C_O1_I2(w, w, w)
 C_O1_I2(w, w, wM)
 C_O1_I2(w, w, wA)
diff --git a/tcg/loongarch64/tcg-target-has.h b/tcg/loongarch64/tcg-target-has.h
index 12a721b4da..e9bb913961 100644
--- a/tcg/loongarch64/tcg-target-has.h
+++ b/tcg/loongarch64/tcg-target-has.h
@@ -10,7 +10,7 @@ 
 #include "host/cpuinfo.h"
 
 /* optional instructions */
-#define TCG_TARGET_HAS_negsetcond_i32   0
+#define TCG_TARGET_HAS_negsetcond_i32   1
 #define TCG_TARGET_HAS_extract2_i32     0
 #define TCG_TARGET_HAS_add2_i32         0
 #define TCG_TARGET_HAS_sub2_i32         0
@@ -19,7 +19,7 @@ 
 #define TCG_TARGET_HAS_qemu_st8_i32     0
 
 /* 64-bit operations */
-#define TCG_TARGET_HAS_negsetcond_i64   0
+#define TCG_TARGET_HAS_negsetcond_i64   1
 #define TCG_TARGET_HAS_extract2_i64     0
 #define TCG_TARGET_HAS_extr_i64_i32     1
 #define TCG_TARGET_HAS_bswap16_i64      1
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index aed1d9712d..c4f908f3ae 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -634,14 +634,29 @@  static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
 }
 
 static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
-                            TCGReg arg1, tcg_target_long arg2, bool c2)
+                            TCGReg arg1, tcg_target_long arg2,
+                            bool c2, bool neg)
 {
     int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2, c2);
+    TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
 
-    if (tmpflags != ret) {
-        TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
-
+    if (neg) {
+        /* If intermediate result is zero/non-zero: test != 0. */
+        if (tmpflags & SETCOND_NEZ) {
+            tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp);
+            tmp = ret;
+        }
+        /* Produce the 0/-1 result. */
+        if (tmpflags & SETCOND_INV) {
+            tcg_out_opc_addi_d(s, ret, tmp, -1);
+        } else {
+            tcg_out_opc_sub_d(s, ret, TCG_REG_ZERO, tmp);
+        }
+    } else {
         switch (tmpflags & SETCOND_FLAGS) {
+        case 0:
+            tcg_debug_assert(tmp == ret);
+            break;
         case SETCOND_INV:
             /* Intermediate result is boolean: simply invert. */
             tcg_out_opc_xori(s, ret, tmp, 1);
@@ -1788,7 +1803,11 @@  static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
 
     case INDEX_op_setcond_i32:
     case INDEX_op_setcond_i64:
-        tcg_out_setcond(s, args[3], a0, a1, a2, c2);
+        tcg_out_setcond(s, args[3], a0, a1, a2, c2, false);
+        break;
+    case INDEX_op_negsetcond_i32:
+    case INDEX_op_negsetcond_i64:
+        tcg_out_setcond(s, args[3], a0, a1, a2, c2, true);
         break;
 
     case INDEX_op_movcond_i32:
@@ -2428,9 +2447,10 @@  tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
         return C_O1_I2(r, 0, rz);
 
     case INDEX_op_setcond_i32:
-        return C_O1_I2(r, rz, ri);
     case INDEX_op_setcond_i64:
-        return C_O1_I2(r, rz, rJ);
+    case INDEX_op_negsetcond_i32:
+    case INDEX_op_negsetcond_i64:
+        return C_O1_I2(r, r, rJ);
 
     case INDEX_op_movcond_i32:
     case INDEX_op_movcond_i64: