summaryrefslogtreecommitdiff
path: root/target-arm/helper-a64.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-06-09 15:43:25 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-06-09 16:06:12 +0100
commit130f2e7dcb4a5f9534fc65200121f06983435a77 (patch)
tree24d33bae4c819916142f6b9ccc21164c64393bcc /target-arm/helper-a64.c
parentda5141fc45937fa358ca4554a335ae6a4c4453ec (diff)
downloadqemu-130f2e7dcb4a5f9534fc65200121f06983435a77.tar.gz
target-arm: A64: Implement CRC instructions
Implement the optional A64 CRC instructions. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1401458125-27977-6-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'target-arm/helper-a64.c')
-rw-r--r--target-arm/helper-a64.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index f0d27229d4..2b4ce6ac60 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -24,6 +24,8 @@
#include "sysemu/sysemu.h"
#include "qemu/bitops.h"
#include "internals.h"
+#include "qemu/crc32c.h"
+#include <zlib.h> /* For crc32 */
/* C2.4.7 Multiply and divide */
/* special cases for 0 and LLONG_MIN are mandated by the standard */
@@ -408,6 +410,34 @@ float32 HELPER(fcvtx_f64_to_f32)(float64 a, CPUARMState *env)
return r;
}
+/* 64-bit versions of the CRC helpers. Note that although the operation
+ * (and the prototypes of crc32c() and crc32() mean that only the bottom
+ * 32 bits of the accumulator and result are used, we pass and return
+ * uint64_t for convenience of the generated code. Unlike the 32-bit
+ * instruction set versions, val may genuinely have 64 bits of data in it.
+ * The upper bytes of val (above the number specified by 'bytes') must have
+ * been zeroed out by the caller.
+ */
+uint64_t HELPER(crc32_64)(uint64_t acc, uint64_t val, uint32_t bytes)
+{
+ uint8_t buf[8];
+
+ stq_le_p(buf, val);
+
+ /* zlib crc32 converts the accumulator and output to one's complement. */
+ return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
+}
+
+uint64_t HELPER(crc32c_64)(uint64_t acc, uint64_t val, uint32_t bytes)
+{
+ uint8_t buf[8];
+
+ stq_le_p(buf, val);
+
+ /* Linux crc32c converts the output to one's complement. */
+ return crc32c(acc, buf, bytes) ^ 0xffffffff;
+}
+
/* Handle a CPU exception. */
void aarch64_cpu_do_interrupt(CPUState *cs)
{