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)