[PATCH v3 15/38] target/s390x: Improve general case of disas_jcc

Richard Henderson posted 38 patches 8 months, 2 weeks ago
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, Laurent Vivier <laurent@vivier.eu>, David Hildenbrand <david@redhat.com>, Ilya Leoshkevich <iii@linux.ibm.com>, Thomas Huth <thuth@redhat.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Artyom Tarasenko <atar4qemu@gmail.com>, WANG Xuerui <git@xen0n.name>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Aurelien Jarno <aurelien@aurel32.net>, Huacai Chen <chenhuacai@kernel.org>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <Alistair.Francis@wdc.com>, Stefan Weil <sw@weilnetz.de>
[PATCH v3 15/38] target/s390x: Improve general case of disas_jcc
Posted by Richard Henderson 8 months, 2 weeks ago
Avoid code duplication by handling 7 of the 14 cases
by inverting the test for the other 7 cases.

Use TCG_COND_TSTNE for cc in {1,3}.
Use (cc - 1) <= 1 for cc in {1,2}.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/s390x/tcg/translate.c | 82 +++++++++++++-----------------------
 1 file changed, 30 insertions(+), 52 deletions(-)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index ae4e7b27ec..168974f2e6 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -885,67 +885,45 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
     case CC_OP_STATIC:
         c->is_64 = false;
         c->u.s32.a = cc_op;
-        switch (mask) {
-        case 0x8 | 0x4 | 0x2: /* cc != 3 */
-            cond = TCG_COND_NE;
+
+        /* Fold half of the cases using bit 3 to invert. */
+        switch (mask & 8 ? mask ^ 0xf : mask) {
+        case 0x1: /* cc == 3 */
+            cond = TCG_COND_EQ;
             c->u.s32.b = tcg_constant_i32(3);
             break;
-        case 0x8 | 0x4 | 0x1: /* cc != 2 */
-            cond = TCG_COND_NE;
-            c->u.s32.b = tcg_constant_i32(2);
-            break;
-        case 0x8 | 0x2 | 0x1: /* cc != 1 */
-            cond = TCG_COND_NE;
-            c->u.s32.b = tcg_constant_i32(1);
-            break;
-        case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */
-            cond = TCG_COND_EQ;
-            c->u.s32.a = tcg_temp_new_i32();
-            c->u.s32.b = tcg_constant_i32(0);
-            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
-            break;
-        case 0x8 | 0x4: /* cc < 2 */
-            cond = TCG_COND_LTU;
-            c->u.s32.b = tcg_constant_i32(2);
-            break;
-        case 0x8: /* cc == 0 */
-            cond = TCG_COND_EQ;
-            c->u.s32.b = tcg_constant_i32(0);
-            break;
-        case 0x4 | 0x2 | 0x1: /* cc != 0 */
-            cond = TCG_COND_NE;
-            c->u.s32.b = tcg_constant_i32(0);
-            break;
-        case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
-            cond = TCG_COND_NE;
-            c->u.s32.a = tcg_temp_new_i32();
-            c->u.s32.b = tcg_constant_i32(0);
-            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
-            break;
-        case 0x4: /* cc == 1 */
-            cond = TCG_COND_EQ;
-            c->u.s32.b = tcg_constant_i32(1);
-            break;
-        case 0x2 | 0x1: /* cc > 1 */
-            cond = TCG_COND_GTU;
-            c->u.s32.b = tcg_constant_i32(1);
-            break;
         case 0x2: /* cc == 2 */
             cond = TCG_COND_EQ;
             c->u.s32.b = tcg_constant_i32(2);
             break;
-        case 0x1: /* cc == 3 */
+        case 0x4: /* cc == 1 */
             cond = TCG_COND_EQ;
-            c->u.s32.b = tcg_constant_i32(3);
+            c->u.s32.b = tcg_constant_i32(1);
+            break;
+        case 0x2 | 0x1: /* cc == 2 || cc == 3 => cc > 1 */
+            cond = TCG_COND_GTU;
+            c->u.s32.b = tcg_constant_i32(1);
+            break;
+        case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
+            cond = TCG_COND_TSTNE;
+            c->u.s32.b = tcg_constant_i32(1);
+            break;
+        case 0x4 | 0x2: /* cc == 1 || cc == 2 => (cc - 1) <= 1 */
+            cond = TCG_COND_LEU;
+            c->u.s32.a = tcg_temp_new_i32();
+            c->u.s32.b = tcg_constant_i32(1);
+            tcg_gen_addi_i32(c->u.s32.a, cc_op, -1);
+            break;
+        case 0x4 | 0x2 | 0x1: /* cc != 0 */
+            cond = TCG_COND_NE;
+            c->u.s32.b = tcg_constant_i32(0);
             break;
         default:
-            /* CC is masked by something else: (8 >> cc) & mask.  */
-            cond = TCG_COND_NE;
-            c->u.s32.a = tcg_temp_new_i32();
-            c->u.s32.b = tcg_constant_i32(0);
-            tcg_gen_shr_i32(c->u.s32.a, tcg_constant_i32(8), cc_op);
-            tcg_gen_andi_i32(c->u.s32.a, c->u.s32.a, mask);
-            break;
+            /* case 0: never, handled above. */
+            g_assert_not_reached();
+        }
+        if (mask & 8) {
+            cond = tcg_invert_cond(cond);
         }
         break;
 
-- 
2.34.1
Re: [PATCH v3 15/38] target/s390x: Improve general case of disas_jcc
Posted by Philippe Mathieu-Daudé 8 months, 1 week ago
Hi Richard,

On 10/1/24 23:43, Richard Henderson wrote:
> Avoid code duplication by handling 7 of the 14 cases
> by inverting the test for the other 7 cases.
> 
> Use TCG_COND_TSTNE for cc in {1,3}.
> Use (cc - 1) <= 1 for cc in {1,2}.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/s390x/tcg/translate.c | 82 +++++++++++++-----------------------
>   1 file changed, 30 insertions(+), 52 deletions(-)
> 
> diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
> index ae4e7b27ec..168974f2e6 100644
> --- a/target/s390x/tcg/translate.c
> +++ b/target/s390x/tcg/translate.c
> @@ -885,67 +885,45 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
>       case CC_OP_STATIC:
>           c->is_64 = false;
>           c->u.s32.a = cc_op;
> -        switch (mask) {
> -        case 0x8 | 0x4 | 0x2: /* cc != 3 */
> -            cond = TCG_COND_NE;
> +
> +        /* Fold half of the cases using bit 3 to invert. */
> +        switch (mask & 8 ? mask ^ 0xf : mask) {
> +        case 0x1: /* cc == 3 */
> +            cond = TCG_COND_EQ;
>               c->u.s32.b = tcg_constant_i32(3);
>               break;
> -        case 0x8 | 0x4 | 0x1: /* cc != 2 */
> -            cond = TCG_COND_NE;
> -            c->u.s32.b = tcg_constant_i32(2);
> -            break;
> -        case 0x8 | 0x2 | 0x1: /* cc != 1 */
> -            cond = TCG_COND_NE;
> -            c->u.s32.b = tcg_constant_i32(1);
> -            break;
> -        case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */
> -            cond = TCG_COND_EQ;
> -            c->u.s32.a = tcg_temp_new_i32();
> -            c->u.s32.b = tcg_constant_i32(0);
> -            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
> -            break;
> -        case 0x8 | 0x4: /* cc < 2 */
> -            cond = TCG_COND_LTU;
> -            c->u.s32.b = tcg_constant_i32(2);
> -            break;
> -        case 0x8: /* cc == 0 */
> -            cond = TCG_COND_EQ;
> -            c->u.s32.b = tcg_constant_i32(0);
> -            break;
> -        case 0x4 | 0x2 | 0x1: /* cc != 0 */
> -            cond = TCG_COND_NE;
> -            c->u.s32.b = tcg_constant_i32(0);
> -            break;
> -        case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
> -            cond = TCG_COND_NE;
> -            c->u.s32.a = tcg_temp_new_i32();
> -            c->u.s32.b = tcg_constant_i32(0);
> -            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
> -            break;
> -        case 0x4: /* cc == 1 */
> -            cond = TCG_COND_EQ;
> -            c->u.s32.b = tcg_constant_i32(1);
> -            break;
> -        case 0x2 | 0x1: /* cc > 1 */
> -            cond = TCG_COND_GTU;
> -            c->u.s32.b = tcg_constant_i32(1);
> -            break;
>           case 0x2: /* cc == 2 */
>               cond = TCG_COND_EQ;
>               c->u.s32.b = tcg_constant_i32(2);
>               break;
> -        case 0x1: /* cc == 3 */
> +        case 0x4: /* cc == 1 */
>               cond = TCG_COND_EQ;
> -            c->u.s32.b = tcg_constant_i32(3);
> +            c->u.s32.b = tcg_constant_i32(1);
> +            break;
> +        case 0x2 | 0x1: /* cc == 2 || cc == 3 => cc > 1 */
> +            cond = TCG_COND_GTU;
> +            c->u.s32.b = tcg_constant_i32(1);
> +            break;
> +        case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
> +            cond = TCG_COND_TSTNE;
> +            c->u.s32.b = tcg_constant_i32(1);

Don't we need to AND?

               c->u.s32.a = tcg_temp_new_i32();
               tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);

> +            break;
> +        case 0x4 | 0x2: /* cc == 1 || cc == 2 => (cc - 1) <= 1 */
> +            cond = TCG_COND_LEU;
> +            c->u.s32.a = tcg_temp_new_i32();
> +            c->u.s32.b = tcg_constant_i32(1);
> +            tcg_gen_addi_i32(c->u.s32.a, cc_op, -1);
> +            break;
> +        case 0x4 | 0x2 | 0x1: /* cc != 0 */
> +            cond = TCG_COND_NE;
> +            c->u.s32.b = tcg_constant_i32(0);
>               break;
>           default:
> -            /* CC is masked by something else: (8 >> cc) & mask.  */
> -            cond = TCG_COND_NE;
> -            c->u.s32.a = tcg_temp_new_i32();
> -            c->u.s32.b = tcg_constant_i32(0);
> -            tcg_gen_shr_i32(c->u.s32.a, tcg_constant_i32(8), cc_op);
> -            tcg_gen_andi_i32(c->u.s32.a, c->u.s32.a, mask);
> -            break;
> +            /* case 0: never, handled above. */
> +            g_assert_not_reached();
> +        }
> +        if (mask & 8) {
> +            cond = tcg_invert_cond(cond);
>           }
>           break;
>
Re: [PATCH v3 15/38] target/s390x: Improve general case of disas_jcc
Posted by Richard Henderson 8 months, 1 week ago
On 1/17/24 09:19, Philippe Mathieu-Daudé wrote:
>> +        case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
>> +            cond = TCG_COND_TSTNE;
>> +            c->u.s32.b = tcg_constant_i32(1);
> 
> Don't we need to AND?
> 
>                c->u.s32.a = tcg_temp_new_i32();
>                tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);

No, that's the TSTNE cond there.


r~

Re: [PATCH v3 15/38] target/s390x: Improve general case of disas_jcc
Posted by Philippe Mathieu-Daudé 8 months ago
On 17/1/24 04:19, Richard Henderson wrote:
> On 1/17/24 09:19, Philippe Mathieu-Daudé wrote:
>>> +        case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
>>> +            cond = TCG_COND_TSTNE;
>>> +            c->u.s32.b = tcg_constant_i32(1);
>>
>> Don't we need to AND?
>>
>>                c->u.s32.a = tcg_temp_new_i32();
>>                tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
> 
> No, that's the TSTNE cond there.

This patch as is was too complex for me so I split it in very
dumb steps to get a trivial patch:
https://lore.kernel.org/qemu-devel/20240119232302.50393-6-philmd@linaro.org/.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


[PATCH v3 15/38 1/6] target/s390x: Reorder CC_OP_STATIC switch case in disas_jcc (1/5)
Posted by Philippe Mathieu-Daudé 8 months ago
Code movement to ease review, no logical change.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/s390x/tcg/translate.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 2897880d88..e84c6459f0 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -916,6 +916,10 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
             cond = TCG_COND_NE;
             c->u.s32.b = tcg_constant_i32(0);
             break;
+        case 0x2 | 0x1: /* cc > 1 */
+            cond = TCG_COND_GTU;
+            c->u.s32.b = tcg_constant_i32(1);
+            break;
         case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
             cond = TCG_COND_NE;
             c->u.s32.a = tcg_temp_new_i32();
@@ -926,10 +930,6 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
             cond = TCG_COND_EQ;
             c->u.s32.b = tcg_constant_i32(1);
             break;
-        case 0x2 | 0x1: /* cc > 1 */
-            cond = TCG_COND_GTU;
-            c->u.s32.b = tcg_constant_i32(1);
-            break;
         case 0x2: /* cc == 2 */
             cond = TCG_COND_EQ;
             c->u.s32.b = tcg_constant_i32(2);
-- 
2.41.0


[PATCH v3 15/38 4/6] target/s390x: Reorder CC_OP_STATIC switch case in disas_jcc (4/5)
Posted by Philippe Mathieu-Daudé 8 months ago
Code movement to ease review, no logical change.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/s390x/tcg/translate.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index fd1138c684..9224df867b 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -914,10 +914,6 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
             cond = TCG_COND_LTU;
             c->u.s32.b = tcg_constant_i32(2);
             break;
-        case 0x8: /* cc == 0 */
-            cond = TCG_COND_EQ;
-            c->u.s32.b = tcg_constant_i32(0);
-            break;
         case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
             cond = TCG_COND_NE;
             c->u.s32.a = tcg_temp_new_i32();
@@ -938,6 +934,10 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
             cond = TCG_COND_GTU;
             c->u.s32.b = tcg_constant_i32(1);
             break;
+        case 0x8: /* cc == 0 */
+            cond = TCG_COND_EQ;
+            c->u.s32.b = tcg_constant_i32(0);
+            break;
         default:
             /* CC is masked by something else: (8 >> cc) & mask.  */
             cond = TCG_COND_NE;
-- 
2.41.0


[PATCH v3 15/38 6/6] target/s390x: Improve general case of disas_jcc
Posted by Philippe Mathieu-Daudé 8 months ago
From: Richard Henderson <richard.henderson@linaro.org>

Avoid code duplication by handling 7 of the 14 cases
by inverting the test for the other 7 cases.

Use TCG_COND_TSTNE for cc in {1,3}.
Use (cc - 1) <= 1 for cc in {1,2}.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/s390x/tcg/translate.c | 52 +++++++++++-------------------------
 1 file changed, 15 insertions(+), 37 deletions(-)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 93c64db33e..030c026699 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -885,67 +885,45 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
     case CC_OP_STATIC:
         c->is_64 = false;
         c->u.s32.a = cc_op;
-        switch (mask) {
+
+        /* Fold half of the cases using bit 3 to invert. */
+        switch (mask & 8 ? mask ^ 0xf : mask) {
         case 0x1: /* cc == 3 */
             cond = TCG_COND_EQ;
             c->u.s32.b = tcg_constant_i32(3);
             break;
-        case 0x8 | 0x4 | 0x2: /* cc != 3 */
-            cond = TCG_COND_NE;
-            c->u.s32.b = tcg_constant_i32(3);
-            break;
         case 0x2: /* cc == 2 */
             cond = TCG_COND_EQ;
             c->u.s32.b = tcg_constant_i32(2);
             break;
-        case 0x8 | 0x4 | 0x1: /* cc != 2 */
-            cond = TCG_COND_NE;
-            c->u.s32.b = tcg_constant_i32(2);
-            break;
         case 0x4: /* cc == 1 */
             cond = TCG_COND_EQ;
             c->u.s32.b = tcg_constant_i32(1);
             break;
-        case 0x8 | 0x2 | 0x1: /* cc != 1 */
-            cond = TCG_COND_NE;
-            c->u.s32.b = tcg_constant_i32(1);
-            break;
-        case 0x8 | 0x4: /* cc < 2 */
-            cond = TCG_COND_LTU;
-            c->u.s32.b = tcg_constant_i32(2);
-            break;
-        case 0x2 | 0x1: /* cc > 1 */
+        case 0x2 | 0x1: /* cc == 2 || cc == 3 => cc > 1 */
             cond = TCG_COND_GTU;
             c->u.s32.b = tcg_constant_i32(1);
             break;
         case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
-            cond = TCG_COND_NE;
-            c->u.s32.a = tcg_temp_new_i32();
-            c->u.s32.b = tcg_constant_i32(0);
-            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
+            cond = TCG_COND_TSTNE;
+            c->u.s32.b = tcg_constant_i32(1);
             break;
-        case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */
-            cond = TCG_COND_EQ;
+        case 0x4 | 0x2: /* cc == 1 || cc == 2 => (cc - 1) <= 1 */
+            cond = TCG_COND_LEU;
             c->u.s32.a = tcg_temp_new_i32();
-            c->u.s32.b = tcg_constant_i32(0);
-            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
+            c->u.s32.b = tcg_constant_i32(1);
+            tcg_gen_addi_i32(c->u.s32.a, cc_op, -1);
             break;
         case 0x4 | 0x2 | 0x1: /* cc != 0 */
             cond = TCG_COND_NE;
             c->u.s32.b = tcg_constant_i32(0);
             break;
-        case 0x8: /* cc == 0 */
-            cond = TCG_COND_EQ;
-            c->u.s32.b = tcg_constant_i32(0);
-            break;
         default:
-            /* CC is masked by something else: (8 >> cc) & mask.  */
-            cond = TCG_COND_NE;
-            c->u.s32.a = tcg_temp_new_i32();
-            c->u.s32.b = tcg_constant_i32(0);
-            tcg_gen_shr_i32(c->u.s32.a, tcg_constant_i32(8), cc_op);
-            tcg_gen_andi_i32(c->u.s32.a, c->u.s32.a, mask);
-            break;
+            /* case 0: never, handled above. */
+            g_assert_not_reached();
+        }
+        if (mask & 8) {
+            cond = tcg_invert_cond(cond);
         }
         break;
 
-- 
2.41.0


Re: [PATCH v3 15/38 6/6] target/s390x: Improve general case of disas_jcc
Posted by Ilya Leoshkevich 8 months ago
On Sat, Jan 20, 2024 at 12:23:02AM +0100, Philippe Mathieu-Daudé wrote:
> From: Richard Henderson <richard.henderson@linaro.org>
> 
> Avoid code duplication by handling 7 of the 14 cases
> by inverting the test for the other 7 cases.
> 
> Use TCG_COND_TSTNE for cc in {1,3}.
> Use (cc - 1) <= 1 for cc in {1,2}.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>  target/s390x/tcg/translate.c | 52 +++++++++++-------------------------
>  1 file changed, 15 insertions(+), 37 deletions(-)

Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
Re: [PATCH v3 15/38 6/6] target/s390x: Improve general case of disas_jcc
Posted by Philippe Mathieu-Daudé 8 months ago
On 20/1/24 00:23, Philippe Mathieu-Daudé wrote:
> From: Richard Henderson <richard.henderson@linaro.org>
> 
> Avoid code duplication by handling 7 of the 14 cases
> by inverting the test for the other 7 cases.
> 
> Use TCG_COND_TSTNE for cc in {1,3}.
> Use (cc - 1) <= 1 for cc in {1,2}.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>   target/s390x/tcg/translate.c | 52 +++++++++++-------------------------
>   1 file changed, 15 insertions(+), 37 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


[PATCH v3 15/38 5/6] target/s390x: Reorder CC_OP_STATIC switch case in disas_jcc (5/5)
Posted by Philippe Mathieu-Daudé 8 months ago
Code movement to ease review, no logical change.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/s390x/tcg/translate.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 9224df867b..93c64db33e 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -914,6 +914,10 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
             cond = TCG_COND_LTU;
             c->u.s32.b = tcg_constant_i32(2);
             break;
+        case 0x2 | 0x1: /* cc > 1 */
+            cond = TCG_COND_GTU;
+            c->u.s32.b = tcg_constant_i32(1);
+            break;
         case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
             cond = TCG_COND_NE;
             c->u.s32.a = tcg_temp_new_i32();
@@ -930,10 +934,6 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
             cond = TCG_COND_NE;
             c->u.s32.b = tcg_constant_i32(0);
             break;
-        case 0x2 | 0x1: /* cc > 1 */
-            cond = TCG_COND_GTU;
-            c->u.s32.b = tcg_constant_i32(1);
-            break;
         case 0x8: /* cc == 0 */
             cond = TCG_COND_EQ;
             c->u.s32.b = tcg_constant_i32(0);
-- 
2.41.0


[PATCH v3 15/38 3/6] target/s390x: Reorder CC_OP_STATIC switch case in disas_jcc (3/5)
Posted by Philippe Mathieu-Daudé 8 months ago
Code movement to ease review, no logical change.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/s390x/tcg/translate.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index aedce85029..fd1138c684 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -910,12 +910,6 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
             cond = TCG_COND_NE;
             c->u.s32.b = tcg_constant_i32(1);
             break;
-        case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */
-            cond = TCG_COND_EQ;
-            c->u.s32.a = tcg_temp_new_i32();
-            c->u.s32.b = tcg_constant_i32(0);
-            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
-            break;
         case 0x8 | 0x4: /* cc < 2 */
             cond = TCG_COND_LTU;
             c->u.s32.b = tcg_constant_i32(2);
@@ -924,6 +918,18 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
             cond = TCG_COND_EQ;
             c->u.s32.b = tcg_constant_i32(0);
             break;
+        case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
+            cond = TCG_COND_NE;
+            c->u.s32.a = tcg_temp_new_i32();
+            c->u.s32.b = tcg_constant_i32(0);
+            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
+            break;
+        case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */
+            cond = TCG_COND_EQ;
+            c->u.s32.a = tcg_temp_new_i32();
+            c->u.s32.b = tcg_constant_i32(0);
+            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
+            break;
         case 0x4 | 0x2 | 0x1: /* cc != 0 */
             cond = TCG_COND_NE;
             c->u.s32.b = tcg_constant_i32(0);
@@ -932,12 +938,6 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
             cond = TCG_COND_GTU;
             c->u.s32.b = tcg_constant_i32(1);
             break;
-        case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
-            cond = TCG_COND_NE;
-            c->u.s32.a = tcg_temp_new_i32();
-            c->u.s32.b = tcg_constant_i32(0);
-            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
-            break;
         default:
             /* CC is masked by something else: (8 >> cc) & mask.  */
             cond = TCG_COND_NE;
-- 
2.41.0


[PATCH v3 15/38 2/6] target/s390x: Reorder CC_OP_STATIC switch case in disas_jcc (2/5)
Posted by Philippe Mathieu-Daudé 8 months ago
Code movement to ease review, no logical change.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/s390x/tcg/translate.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index e84c6459f0..aedce85029 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -886,14 +886,26 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
         c->is_64 = false;
         c->u.s32.a = cc_op;
         switch (mask) {
+        case 0x1: /* cc == 3 */
+            cond = TCG_COND_EQ;
+            c->u.s32.b = tcg_constant_i32(3);
+            break;
         case 0x8 | 0x4 | 0x2: /* cc != 3 */
             cond = TCG_COND_NE;
             c->u.s32.b = tcg_constant_i32(3);
             break;
+        case 0x2: /* cc == 2 */
+            cond = TCG_COND_EQ;
+            c->u.s32.b = tcg_constant_i32(2);
+            break;
         case 0x8 | 0x4 | 0x1: /* cc != 2 */
             cond = TCG_COND_NE;
             c->u.s32.b = tcg_constant_i32(2);
             break;
+        case 0x4: /* cc == 1 */
+            cond = TCG_COND_EQ;
+            c->u.s32.b = tcg_constant_i32(1);
+            break;
         case 0x8 | 0x2 | 0x1: /* cc != 1 */
             cond = TCG_COND_NE;
             c->u.s32.b = tcg_constant_i32(1);
@@ -926,18 +938,6 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
             c->u.s32.b = tcg_constant_i32(0);
             tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
             break;
-        case 0x4: /* cc == 1 */
-            cond = TCG_COND_EQ;
-            c->u.s32.b = tcg_constant_i32(1);
-            break;
-        case 0x2: /* cc == 2 */
-            cond = TCG_COND_EQ;
-            c->u.s32.b = tcg_constant_i32(2);
-            break;
-        case 0x1: /* cc == 3 */
-            cond = TCG_COND_EQ;
-            c->u.s32.b = tcg_constant_i32(3);
-            break;
         default:
             /* CC is masked by something else: (8 >> cc) & mask.  */
             cond = TCG_COND_NE;
-- 
2.41.0