diff mbox series

[04/67] target/arm: Convert CRC32, CRC32C to decodetree

Message ID 20241201150607.12812-5-richard.henderson@linaro.org (mailing list archive)
State New
Headers show
Series target/arm: AArch64 decodetree conversion, final part | expand

Commit Message

Richard Henderson Dec. 1, 2024, 3:05 p.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/tcg/translate-a64.c | 101 +++++++++++++--------------------
 target/arm/tcg/a64.decode      |  12 ++++
 2 files changed, 53 insertions(+), 60 deletions(-)

Comments

Philippe Mathieu-Daudé Dec. 2, 2024, 2:01 p.m. UTC | #1
Hi Richard,

On 1/12/24 16:05, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/arm/tcg/translate-a64.c | 101 +++++++++++++--------------------
>   target/arm/tcg/a64.decode      |  12 ++++
>   2 files changed, 53 insertions(+), 60 deletions(-)
> 
> diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
> index 8b7ca2c68a..22594a1149 100644
> --- a/target/arm/tcg/translate-a64.c
> +++ b/target/arm/tcg/translate-a64.c
> @@ -7592,6 +7592,39 @@ TRANS(LSRV, do_shift_reg, a, A64_SHIFT_TYPE_LSR)
>   TRANS(ASRV, do_shift_reg, a, A64_SHIFT_TYPE_ASR)
>   TRANS(RORV, do_shift_reg, a, A64_SHIFT_TYPE_ROR)
>   
> +static bool do_crc32(DisasContext *s, arg_rrr_e *a, bool crc32c)
> +{
> +    TCGv_i64 tcg_acc, tcg_val, tcg_rd;
> +    TCGv_i32 tcg_bytes;
> +
> +    switch (a->esz) {
> +    case MO_8:
> +    case MO_16:
> +    case MO_32:
> +        tcg_val = tcg_temp_new_i64();
> +        tcg_gen_extract_i64(tcg_val, cpu_reg(s, a->rm), 0, 8 << a->esz);
> +        break;
> +    case MO_64:
> +        tcg_val = cpu_reg(s, a->rm);
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +    tcg_acc = cpu_reg(s, a->rn);
> +    tcg_bytes = tcg_constant_i32(1 << a->esz);
> +    tcg_rd = cpu_reg(s, a->rd);
> +
> +    if (crc32c) {
> +        gen_helper_crc32c_64(tcg_rd, tcg_acc, tcg_val, tcg_bytes);
> +    } else {
> +        gen_helper_crc32_64(tcg_rd, tcg_acc, tcg_val, tcg_bytes);
> +    }
> +    return true;
> +}
> +
> +TRANS_FEAT(CRC32, aa64_crc32, do_crc32, a, false)
> +TRANS_FEAT(CRC32C, aa64_crc32, do_crc32, a, true)
> +
>   /* Logical (shifted register)
>    *   31  30 29 28       24 23   22 21  20  16 15    10 9    5 4    0
>    * +----+-----+-----------+-------+---+------+--------+------+------+
> @@ -8473,52 +8506,6 @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
>   }
>   
>   
> -/* CRC32[BHWX], CRC32C[BHWX] */
> -static void handle_crc32(DisasContext *s,
> -                         unsigned int sf, unsigned int sz, bool crc32c,
> -                         unsigned int rm, unsigned int rn, unsigned int rd)
> -{
> -    TCGv_i64 tcg_acc, tcg_val;
> -    TCGv_i32 tcg_bytes;
> -
> -    if (!dc_isar_feature(aa64_crc32, s)
> -        || (sf == 1 && sz != 3)
> -        || (sf == 0 && sz == 3)) {

We are not checking the sf bit anymore, is that intended?

Should we add the 'rrr_sf_[bhsd]' format?

> -        unallocated_encoding(s);
> -        return;
> -    }
> -
> -    if (sz == 3) {
> -        tcg_val = cpu_reg(s, rm);
> -    } else {
> -        uint64_t mask;
> -        switch (sz) {
> -        case 0:
> -            mask = 0xFF;
> -            break;
> -        case 1:
> -            mask = 0xFFFF;
> -            break;
> -        case 2:
> -            mask = 0xFFFFFFFF;
> -            break;
> -        default:
> -            g_assert_not_reached();
> -        }
> -        tcg_val = tcg_temp_new_i64();
> -        tcg_gen_andi_i64(tcg_val, cpu_reg(s, rm), mask);
> -    }
> -
> -    tcg_acc = cpu_reg(s, rn);
> -    tcg_bytes = tcg_constant_i32(1 << sz);
> -
> -    if (crc32c) {
> -        gen_helper_crc32c_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes);
> -    } else {
> -        gen_helper_crc32_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes);
> -    }
> -}
> -
>   /* Data-processing (2 source)
>    *   31   30  29 28             21 20  16 15    10 9    5 4    0
>    * +----+---+---+-----------------+------+--------+------+------+
> @@ -8590,20 +8577,6 @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
>           gen_helper_pacga(cpu_reg(s, rd), tcg_env,
>                            cpu_reg(s, rn), cpu_reg_sp(s, rm));
>           break;
> -    case 16:
> -    case 17:
> -    case 18:
> -    case 19:
> -    case 20:
> -    case 21:
> -    case 22:
> -    case 23: /* CRC32 */
> -    {
> -        int sz = extract32(opcode, 0, 2);
> -        bool crc32c = extract32(opcode, 2, 1);
> -        handle_crc32(s, sf, sz, crc32c, rm, rn, rd);
> -        break;
> -    }
>       default:
>       do_unallocated:
>       case 2: /* UDIV */
> @@ -8612,6 +8585,14 @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
>       case 9: /* LSRV */
>       case 10: /* ASRV */
>       case 11: /* RORV */
> +    case 16:
> +    case 17:
> +    case 18:
> +    case 19:
> +    case 20:
> +    case 21:
> +    case 22:
> +    case 23: /* CRC32 */
>           unallocated_encoding(s);
>           break;
>       }
> diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
> index 3db55b78a6..1664f4793c 100644
> --- a/target/arm/tcg/a64.decode
> +++ b/target/arm/tcg/a64.decode
> @@ -45,7 +45,9 @@
>   @rr_d           ........ ... ..... ...... rn:5 rd:5     &rr_e esz=3
>   @rr_sd          ........ ... ..... ...... rn:5 rd:5     &rr_e esz=%esz_sd
>   
> +@rrr_b          ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=0
>   @rrr_h          ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=1
> +@rrr_s          ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=2
>   @rrr_d          ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=3
>   @rrr_sd         ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=%esz_sd
>   @rrr_hsd        ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=%esz_hsd
> @@ -663,6 +665,16 @@ LSRV            . 00 11010110 ..... 00100 1 ..... ..... @rrr_sf
>   ASRV            . 00 11010110 ..... 00101 0 ..... ..... @rrr_sf
>   RORV            . 00 11010110 ..... 00101 1 ..... ..... @rrr_sf
>   
> +CRC32           0 00 11010110 ..... 0100 00 ..... ..... @rrr_b
> +CRC32           0 00 11010110 ..... 0100 01 ..... ..... @rrr_h
> +CRC32           0 00 11010110 ..... 0100 10 ..... ..... @rrr_s
> +CRC32           1 00 11010110 ..... 0100 11 ..... ..... @rrr_d
> +
> +CRC32C          0 00 11010110 ..... 0101 00 ..... ..... @rrr_b
> +CRC32C          0 00 11010110 ..... 0101 01 ..... ..... @rrr_h
> +CRC32C          0 00 11010110 ..... 0101 10 ..... ..... @rrr_s
> +CRC32C          1 00 11010110 ..... 0101 11 ..... ..... @rrr_d
> +
>   # Data Processing (1-source)
>   # Logical (shifted reg)
>   # Add/subtract (shifted reg)
Richard Henderson Dec. 2, 2024, 5:49 p.m. UTC | #2
On 12/2/24 08:01, Philippe Mathieu-Daudé wrote:
>> -    if (!dc_isar_feature(aa64_crc32, s)
>> -        || (sf == 1 && sz != 3)
>> -        || (sf == 0 && sz == 3)) {
> 
> We are not checking the sf bit anymore, is that intended?

Yes.

>> +CRC32           0 00 11010110 ..... 0100 00 ..... ..... @rrr_b
>> +CRC32           0 00 11010110 ..... 0100 01 ..... ..... @rrr_h
>> +CRC32           0 00 11010110 ..... 0100 10 ..... ..... @rrr_s
>> +CRC32           1 00 11010110 ..... 0100 11 ..... ..... @rrr_d
>> +
>> +CRC32C          0 00 11010110 ..... 0101 00 ..... ..... @rrr_b
>> +CRC32C          0 00 11010110 ..... 0101 01 ..... ..... @rrr_h
>> +CRC32C          0 00 11010110 ..... 0101 10 ..... ..... @rrr_s
>> +CRC32C          1 00 11010110 ..... 0101 11 ..... ..... @rrr_d

We are forcing sf (bit 31) to match sz (bits 10:11) in decode.


r~
Philippe Mathieu-Daudé Dec. 2, 2024, 9:04 p.m. UTC | #3
On 2/12/24 18:49, Richard Henderson wrote:
> On 12/2/24 08:01, Philippe Mathieu-Daudé wrote:
>>> -    if (!dc_isar_feature(aa64_crc32, s)
>>> -        || (sf == 1 && sz != 3)
>>> -        || (sf == 0 && sz == 3)) {
>>
>> We are not checking the sf bit anymore, is that intended?
> 
> Yes.
> 
>>> +CRC32           0 00 11010110 ..... 0100 00 ..... ..... @rrr_b
>>> +CRC32           0 00 11010110 ..... 0100 01 ..... ..... @rrr_h
>>> +CRC32           0 00 11010110 ..... 0100 10 ..... ..... @rrr_s
>>> +CRC32           1 00 11010110 ..... 0100 11 ..... ..... @rrr_d
>>> +
>>> +CRC32C          0 00 11010110 ..... 0101 00 ..... ..... @rrr_b
>>> +CRC32C          0 00 11010110 ..... 0101 01 ..... ..... @rrr_h
>>> +CRC32C          0 00 11010110 ..... 0101 10 ..... ..... @rrr_s
>>> +CRC32C          1 00 11010110 ..... 0101 11 ..... ..... @rrr_d
> 
> We are forcing sf (bit 31) to match sz (bits 10:11) in decode.

Oh, indeed :)

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

Patch

diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 8b7ca2c68a..22594a1149 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -7592,6 +7592,39 @@  TRANS(LSRV, do_shift_reg, a, A64_SHIFT_TYPE_LSR)
 TRANS(ASRV, do_shift_reg, a, A64_SHIFT_TYPE_ASR)
 TRANS(RORV, do_shift_reg, a, A64_SHIFT_TYPE_ROR)
 
+static bool do_crc32(DisasContext *s, arg_rrr_e *a, bool crc32c)
+{
+    TCGv_i64 tcg_acc, tcg_val, tcg_rd;
+    TCGv_i32 tcg_bytes;
+
+    switch (a->esz) {
+    case MO_8:
+    case MO_16:
+    case MO_32:
+        tcg_val = tcg_temp_new_i64();
+        tcg_gen_extract_i64(tcg_val, cpu_reg(s, a->rm), 0, 8 << a->esz);
+        break;
+    case MO_64:
+        tcg_val = cpu_reg(s, a->rm);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    tcg_acc = cpu_reg(s, a->rn);
+    tcg_bytes = tcg_constant_i32(1 << a->esz);
+    tcg_rd = cpu_reg(s, a->rd);
+
+    if (crc32c) {
+        gen_helper_crc32c_64(tcg_rd, tcg_acc, tcg_val, tcg_bytes);
+    } else {
+        gen_helper_crc32_64(tcg_rd, tcg_acc, tcg_val, tcg_bytes);
+    }
+    return true;
+}
+
+TRANS_FEAT(CRC32, aa64_crc32, do_crc32, a, false)
+TRANS_FEAT(CRC32C, aa64_crc32, do_crc32, a, true)
+
 /* Logical (shifted register)
  *   31  30 29 28       24 23   22 21  20  16 15    10 9    5 4    0
  * +----+-----+-----------+-------+---+------+--------+------+------+
@@ -8473,52 +8506,6 @@  static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
 }
 
 
-/* CRC32[BHWX], CRC32C[BHWX] */
-static void handle_crc32(DisasContext *s,
-                         unsigned int sf, unsigned int sz, bool crc32c,
-                         unsigned int rm, unsigned int rn, unsigned int rd)
-{
-    TCGv_i64 tcg_acc, tcg_val;
-    TCGv_i32 tcg_bytes;
-
-    if (!dc_isar_feature(aa64_crc32, s)
-        || (sf == 1 && sz != 3)
-        || (sf == 0 && sz == 3)) {
-        unallocated_encoding(s);
-        return;
-    }
-
-    if (sz == 3) {
-        tcg_val = cpu_reg(s, rm);
-    } else {
-        uint64_t mask;
-        switch (sz) {
-        case 0:
-            mask = 0xFF;
-            break;
-        case 1:
-            mask = 0xFFFF;
-            break;
-        case 2:
-            mask = 0xFFFFFFFF;
-            break;
-        default:
-            g_assert_not_reached();
-        }
-        tcg_val = tcg_temp_new_i64();
-        tcg_gen_andi_i64(tcg_val, cpu_reg(s, rm), mask);
-    }
-
-    tcg_acc = cpu_reg(s, rn);
-    tcg_bytes = tcg_constant_i32(1 << sz);
-
-    if (crc32c) {
-        gen_helper_crc32c_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes);
-    } else {
-        gen_helper_crc32_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes);
-    }
-}
-
 /* Data-processing (2 source)
  *   31   30  29 28             21 20  16 15    10 9    5 4    0
  * +----+---+---+-----------------+------+--------+------+------+
@@ -8590,20 +8577,6 @@  static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
         gen_helper_pacga(cpu_reg(s, rd), tcg_env,
                          cpu_reg(s, rn), cpu_reg_sp(s, rm));
         break;
-    case 16:
-    case 17:
-    case 18:
-    case 19:
-    case 20:
-    case 21:
-    case 22:
-    case 23: /* CRC32 */
-    {
-        int sz = extract32(opcode, 0, 2);
-        bool crc32c = extract32(opcode, 2, 1);
-        handle_crc32(s, sf, sz, crc32c, rm, rn, rd);
-        break;
-    }
     default:
     do_unallocated:
     case 2: /* UDIV */
@@ -8612,6 +8585,14 @@  static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
     case 9: /* LSRV */
     case 10: /* ASRV */
     case 11: /* RORV */
+    case 16:
+    case 17:
+    case 18:
+    case 19:
+    case 20:
+    case 21:
+    case 22:
+    case 23: /* CRC32 */
         unallocated_encoding(s);
         break;
     }
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 3db55b78a6..1664f4793c 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -45,7 +45,9 @@ 
 @rr_d           ........ ... ..... ...... rn:5 rd:5     &rr_e esz=3
 @rr_sd          ........ ... ..... ...... rn:5 rd:5     &rr_e esz=%esz_sd
 
+@rrr_b          ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=0
 @rrr_h          ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=1
+@rrr_s          ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=2
 @rrr_d          ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=3
 @rrr_sd         ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=%esz_sd
 @rrr_hsd        ........ ... rm:5 ...... rn:5 rd:5      &rrr_e esz=%esz_hsd
@@ -663,6 +665,16 @@  LSRV            . 00 11010110 ..... 00100 1 ..... ..... @rrr_sf
 ASRV            . 00 11010110 ..... 00101 0 ..... ..... @rrr_sf
 RORV            . 00 11010110 ..... 00101 1 ..... ..... @rrr_sf
 
+CRC32           0 00 11010110 ..... 0100 00 ..... ..... @rrr_b
+CRC32           0 00 11010110 ..... 0100 01 ..... ..... @rrr_h
+CRC32           0 00 11010110 ..... 0100 10 ..... ..... @rrr_s
+CRC32           1 00 11010110 ..... 0100 11 ..... ..... @rrr_d
+
+CRC32C          0 00 11010110 ..... 0101 00 ..... ..... @rrr_b
+CRC32C          0 00 11010110 ..... 0101 01 ..... ..... @rrr_h
+CRC32C          0 00 11010110 ..... 0101 10 ..... ..... @rrr_s
+CRC32C          1 00 11010110 ..... 0101 11 ..... ..... @rrr_d
+
 # Data Processing (1-source)
 # Logical (shifted reg)
 # Add/subtract (shifted reg)