summaryrefslogtreecommitdiff
path: root/target-arm/helper.c
diff options
context:
space:
mode:
authorWill Newton <will.newton@linaro.org>2014-02-26 17:20:07 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-02-26 17:20:07 +0000
commiteb0ecd5ad908b72dfe4fadf84272616b2de101d1 (patch)
treec52a660b3610ad9baa7394aedeba0e8ac47c9f27 /target-arm/helper.c
parent0956ff5a4e1fceb33e098133dd2b083647bb8eaa (diff)
downloadqemu-eb0ecd5ad908b72dfe4fadf84272616b2de101d1.tar.gz
qemu-eb0ecd5ad908b72dfe4fadf84272616b2de101d1.tar.bz2
qemu-eb0ecd5ad908b72dfe4fadf84272616b2de101d1.zip
target-arm: Add support for AArch32 ARMv8 CRC32 instructions
Add support for AArch32 CRC32 and CRC32C instructions added in ARMv8 and add a CPU feature flag to enable these instructions. The CRC32-C implementation used is the built-in qemu implementation and The CRC-32 implementation is from zlib. This requires adding zlib to LIBS to ensure it is linked for the linux-user binary. Signed-off-by: Will Newton <will.newton@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1393411566-24104-3-git-send-email-will.newton@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r--target-arm/helper.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 56219527ca..90f85f1899 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5,6 +5,8 @@
#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
#include "qemu/bitops.h"
+#include "qemu/crc32c.h"
+#include <zlib.h> /* For crc32 */
#ifndef CONFIG_USER_ONLY
static inline int get_phys_addr(CPUARMState *env, uint32_t address,
@@ -4703,3 +4705,40 @@ int arm_rmode_to_sf(int rmode)
}
return rmode;
}
+
+static void crc_init_buffer(uint8_t *buf, uint32_t val, uint32_t bytes)
+{
+ memset(buf, 0, 4);
+
+ if (bytes == 1) {
+ buf[0] = val & 0xff;
+ } else if (bytes == 2) {
+ buf[0] = val & 0xff;
+ buf[1] = (val >> 8) & 0xff;
+ } else {
+ buf[0] = val & 0xff;
+ buf[1] = (val >> 8) & 0xff;
+ buf[2] = (val >> 16) & 0xff;
+ buf[3] = (val >> 24) & 0xff;
+ }
+}
+
+uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
+{
+ uint8_t buf[4];
+
+ crc_init_buffer(buf, val, bytes);
+
+ /* zlib crc32 converts the accumulator and output to one's complement. */
+ return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
+}
+
+uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
+{
+ uint8_t buf[4];
+
+ crc_init_buffer(buf, val, bytes);
+
+ /* Linux crc32c converts the output to one's complement. */
+ return crc32c(acc, buf, bytes) ^ 0xffffffff;
+}