On 20/10/26 16:55, Stian Halseth wrote:
Implement the CRC32C instruction according to OSA
(Oracle SPARC Architecture) 2011 section 7.19.

Using QEMU's crc32c.h and bswap.h.
Gated behind the crypto CPU feature and disabled for sparc32.

Signed-off-by: Stian Halseth <[email protected]>
---
  target/sparc/crypto_helper.c | 20 ++++++++++++++++++++
  target/sparc/helper.h        |  1 +
  target/sparc/insns.decode    |  1 +
  target/sparc/translate.c     |  2 ++
  4 files changed, 24 insertions(+)

Bonus for generic tests in tests/tcg/multiarch/ (can be done later).


diff --git a/target/sparc/crypto_helper.c b/target/sparc/crypto_helper.c
index 5d2940b825..fdae71a06f 100644
--- a/target/sparc/crypto_helper.c
+++ b/target/sparc/crypto_helper.c
@@ -10,6 +10,8 @@
  #include "exec/helper-proto.h"
  #include "crypto/aes-round.h"
  #include "crypto/aes.h"
+#include "qemu/bswap.h"
+#include "qemu/crc32c.h"
/*
   * SPARC four-operand AES round (Section 7.3).
@@ -141,3 +143,21 @@ uint64_t helper_aes_kexpand2(uint64_t rs1, uint64_t rs2)
  {
      return aes_kexpand(rs1, (uint32_t)rs2);
  }
+
+/*
+ * CRC32C Operation 3 operand (Section 7.19)

"3-operand"

+ * Accumulate CRC32C over the eight bytes of rs2, most significant first.
+ */
+uint64_t helper_crc32c(uint64_t rs1, uint64_t rs2)
+{
+    uint8_t buf[8];
+    /* IV and result are byte-swapped in the register. */
+    uint32_t crc = bswap32((uint32_t)rs1);
+
+    stq_be_p(buf, rs2);
+
+    /* Undo crc32c()'s final inversion for the instruction's raw result. */
+    crc = crc32c(crc, buf, sizeof(buf)) ^ UINT32_MAX;
+

Nitpicking again to be slighly more explicit:

       /* Result lives in the low 32 bits; upper half reads as zero. */
       return (uint64_t)bswap32(crc);

+    return bswap32(crc);
+}

Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Tested-by: Philippe Mathieu-Daudé <[email protected]>

Reply via email to