qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
To: qemu-devel@nongnu.org
Cc: arikalo@wavecomp.com, Yongbok Kim <yongbok.kim@mips.com>,
	philmd@redhat.com, amarkovic@wavecomp.com
Subject: [Qemu-devel] [PATCH for 4.2 v7 05/26] target/mips: Add support for emulation of CRC32 group of instructions
Date: Fri,  9 Aug 2019 14:46:38 +0200	[thread overview]
Message-ID: <1565354819-1495-6-git-send-email-aleksandar.markovic@rt-rk.com> (raw)
In-Reply-To: <1565354819-1495-1-git-send-email-aleksandar.markovic@rt-rk.com>

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of MIPS' CRC32 (Cyclic Redundancy Check) instructions.
Reuse zlib crc32() and Linux crc32c(). Note that, at the time being,
there is no MIPS CPU that supports CRC32 instructions (they are an
optional part of MIPS64/32 R6 anf nanoMIPS ISAs).

Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
---
 disas/mips.c            |  8 ++++++++
 target/mips/helper.h    |  2 ++
 target/mips/op_helper.c | 22 ++++++++++++++++++++++
 target/mips/translate.c | 41 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 73 insertions(+)

diff --git a/disas/mips.c b/disas/mips.c
index c3a3059..b9a5204 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -1411,6 +1411,14 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"evp",        "t",     0x41600004, 0xffe0ffff, TRAP|WR_t,            0, I32R6},
 {"ginvi",      "v",     0x7c00003d, 0xfc1ffcff, TRAP | INSN_TLB,      0, I32R6},
 {"ginvt",      "v",     0x7c0000bd, 0xfc1ffcff, TRAP | INSN_TLB,      0, I32R6},
+{"crc32b",     "t,v,t", 0x7c00000f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, I32R6},
+{"crc32h",     "t,v,t", 0x7c00004f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, I32R6},
+{"crc32w",     "t,v,t", 0x7c00008f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, I32R6},
+{"crc32d",     "t,v,t", 0x7c0000cf, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, I64R6},
+{"crc32cb",    "t,v,t", 0x7c00010f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, I32R6},
+{"crc32ch",    "t,v,t", 0x7c00014f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, I32R6},
+{"crc32cw",    "t,v,t", 0x7c00018f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, I32R6},
+{"crc32cd",    "t,v,t", 0x7c0001cf, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, I64R6},
 
 /* MSA */
 {"sll.b",   "+d,+e,+f", 0x7800000d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
diff --git a/target/mips/helper.h b/target/mips/helper.h
index c7d35bd..0e61043 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -40,6 +40,8 @@ DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl)
 #endif
 
+DEF_HELPER_3(crc32, tl, tl, tl, i32)
+DEF_HELPER_3(crc32c, tl, tl, tl, i32)
 DEF_HELPER_FLAGS_4(rotx, TCG_CALL_NO_RWG_SE, tl, tl, i32, i32, i32)
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 3104904..5874029 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -25,6 +25,8 @@
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "sysemu/kvm.h"
+#include "qemu/crc32c.h"
+#include <zlib.h>
 
 /*****************************************************************************/
 /* Exceptions processing helpers */
@@ -343,6 +345,26 @@ target_ulong helper_rotx(target_ulong rs, uint32_t shift, uint32_t shiftx,
     return (int64_t)(int32_t)(uint32_t)tmp5;
 }
 
+/* these crc32 functions are based on target/arm/helper-a64.c */
+target_ulong helper_crc32(target_ulong val, target_ulong m, uint32_t sz)
+{
+    uint8_t buf[8];
+    target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1);
+
+    m &= mask;
+    stq_le_p(buf, m);
+    return (int32_t) (crc32(val ^ 0xffffffff, buf, sz) ^ 0xffffffff);
+}
+
+target_ulong helper_crc32c(target_ulong val, target_ulong m, uint32_t sz)
+{
+    uint8_t buf[8];
+    target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1);
+    m &= mask;
+    stq_le_p(buf, m);
+    return (int32_t) (crc32c(val, buf, sz) ^ 0xffffffff);
+}
+
 #ifndef CONFIG_USER_ONLY
 
 static inline hwaddr do_translate_address(CPUMIPSState *env,
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 3f73be0..3f9f113 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -452,6 +452,7 @@ enum {
     OPC_LWE            = 0x2F | OPC_SPECIAL3,
 
     /* R6 */
+    OPC_CRC32          = 0x0F | OPC_SPECIAL3,
     R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
     R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
     R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
@@ -2550,6 +2551,7 @@ typedef struct DisasContext {
     bool saar;
     bool mi;
     int gi;
+    bool crcp;
 } DisasContext;
 
 #define DISAS_STOP       DISAS_TARGET_0
@@ -27041,6 +27043,33 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
+static void gen_crc32(DisasContext *ctx, int rd, int rs, int rt, int sz,
+                      int crc32c)
+{
+    TCGv t0;
+    TCGv t1;
+    TCGv_i32 tsz = tcg_const_i32(1 << sz);
+    if (rd == 0) {
+        /* Treat as NOP. */
+        return;
+    }
+    t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
+
+    gen_load_gpr(t0, rt);
+    gen_load_gpr(t1, rs);
+
+    if (crc32c) {
+        gen_helper_crc32c(cpu_gpr[rd], t0, t1, tsz);
+    } else {
+        gen_helper_crc32(cpu_gpr[rd], t0, t1, tsz);
+    }
+
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+    tcg_temp_free_i32(tsz);
+}
+
 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
 {
     int rs, rt, rd, sa;
@@ -27055,6 +27084,17 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
 
     op1 = MASK_SPECIAL3(ctx->opcode);
     switch (op1) {
+    case OPC_CRC32:
+        if (unlikely(!ctx->crcp) ||
+            unlikely((extract32(ctx->opcode, 6, 2) == 3) &&
+                     (!(ctx->hflags & MIPS_HFLAG_64))) ||
+            unlikely((extract32(ctx->opcode, 8, 3) >= 2))) {
+            generate_exception_end(ctx, EXCP_RI);
+        }
+        gen_crc32(ctx, rt, rs, rt,
+                  extract32(ctx->opcode, 6, 2),
+                  extract32(ctx->opcode, 8, 3));
+        break;
     case R6_OPC_PREF:
         if (rt >= 24) {
             /* hint codes 24-31 are reserved and signal RI */
@@ -30049,6 +30089,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
     ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
     ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
+    ctx->crcp = (env->CP0_Config5 >> CP0C5_CRCP) & 1;
     restore_cpu_state(env, ctx);
 #ifdef CONFIG_USER_ONLY
         ctx->mem_idx = MIPS_HFLAG_UM;
-- 
2.7.4



  parent reply	other threads:[~2019-08-09 12:51 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-09 12:46 [Qemu-devel] [PATCH for 4.2 v7 00/26] target/mips: Misc patches for 4.2 Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 01/26] target/mips: Add support for DSPRAM Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 02/26] target/mips: Amend CP0 WatchHi register implementation Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 03/26] target/mips: Amend CP0 MemoryMapID " Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 04/26] target/mips: Add support for emulation of GINVT instruction Aleksandar Markovic
2019-08-09 12:46 ` Aleksandar Markovic [this message]
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 06/26] target/mips: Style improvements in cp0_timer.c Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 07/26] target/mips: Style improvements in cpu.c Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 08/26] target/mips: Style improvements in helper.c Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 09/26] target/mips: Style improvements in internal.h Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 10/26] target/mips: Style improvements in machine.c Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 11/26] target/mips: Style improvements in cps.c Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 12/26] target/mips: Style improvements in mips_fulong2e.c Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 13/26] target/mips: Style improvements in mips_int.c Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 14/26] target/mips: Style improvements in mips_malta.c Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 15/26] target/mips: Style improvements in mips_mipssim.c Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 16/26] target/mips: Clean up handling of CP0 register 0 Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 17/26] target/mips: Clean up handling of CP0 register 1 Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 18/26] target/mips: Clean up handling of CP0 register 2 Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 19/26] target/mips: Clean up handling of CP0 register 5 Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 20/26] target/mips: Clean up handling of CP0 register 20 Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 21/26] target/mips: Clean up handling of CP0 register 24 Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 22/26] target/mips: Clean up handling of CP0 register 26 Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 23/26] target/mips: Clean up handling of CP0 register 30 Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 24/26] target/mips: Clean up handling of CP0 register 31 Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 25/26] target/mips: tests/tcg: Add optional printing of more detailed failure info Aleksandar Markovic
2019-08-09 12:46 ` [Qemu-devel] [PATCH for 4.2 v7 26/26] target/mips: tests/tcg: Fix target configurations for MSA tests Aleksandar Markovic

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1565354819-1495-6-git-send-email-aleksandar.markovic@rt-rk.com \
    --to=aleksandar.markovic@rt-rk.com \
    --cc=amarkovic@wavecomp.com \
    --cc=arikalo@wavecomp.com \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=yongbok.kim@mips.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).