From: Peter Maydell <peter.maydell@linaro.org>
To: Anthony Liguori <aliguori@amazon.com>
Cc: Blue Swirl <blauwirbel@gmail.com>,
qemu-devel@nongnu.org, Aurelien Jarno <aurelien@aurel32.net>
Subject: [Qemu-devel] [PULL 38/45] target-arm: Add support for AArch32 ARMv8 CRC32 instructions
Date: Wed, 26 Feb 2014 18:02:28 +0000 [thread overview]
Message-ID: <1393437755-23586-39-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1393437755-23586-1-git-send-email-peter.maydell@linaro.org>
From: Will Newton <will.newton@linaro.org>
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>
---
configure | 2 +-
target-arm/cpu.c | 1 +
target-arm/cpu.h | 1 +
target-arm/helper.c | 39 +++++++++++++++++++++++++++++++++++
target-arm/helper.h | 3 +++
target-arm/translate.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 101 insertions(+), 1 deletion(-)
diff --git a/configure b/configure
index 423f435..030da86 100755
--- a/configure
+++ b/configure
@@ -1657,7 +1657,7 @@ EOF
"Make sure to have the zlib libs and headers installed."
fi
fi
-libs_softmmu="$libs_softmmu -lz"
+LIBS="$LIBS -lz"
##########################################
# libseccomp check
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 7384e17..1ce8a9b 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -924,6 +924,7 @@ static void arm_any_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
set_feature(&cpu->env, ARM_FEATURE_V7MP);
+ set_feature(&cpu->env, ARM_FEATURE_CRC);
#ifdef TARGET_AARCH64
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
#endif
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index afc46b2..49fef3f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -626,6 +626,7 @@ enum arm_features {
ARM_FEATURE_AARCH64, /* supports 64 bit mode */
ARM_FEATURE_V8_AES, /* implements AES part of v8 Crypto Extensions */
ARM_FEATURE_CBAR, /* has cp15 CBAR */
+ ARM_FEATURE_CRC, /* ARMv8 CRC instructions */
};
static inline int arm_feature(CPUARMState *env, int feature)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5621952..90f85f1 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;
+}
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 4a063c1..276f3a9 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -499,6 +499,9 @@ DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
DEF_HELPER_4(crypto_aese, void, env, i32, i32, i32)
DEF_HELPER_4(crypto_aesmc, void, env, i32, i32, i32)
+DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
+DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
+
#ifdef TARGET_AARCH64
#include "helper-a64.h"
#endif
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6ccf0ba..253d2a1 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7561,6 +7561,36 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
store_reg(s, 14, tmp2);
gen_bx(s, tmp);
break;
+ case 0x4:
+ {
+ /* crc32/crc32c */
+ uint32_t c = extract32(insn, 8, 4);
+
+ /* Check this CPU supports ARMv8 CRC instructions.
+ * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
+ * Bits 8, 10 and 11 should be zero.
+ */
+ if (!arm_feature(env, ARM_FEATURE_CRC) || op1 == 0x3 ||
+ (c & 0xd) != 0) {
+ goto illegal_op;
+ }
+
+ rn = extract32(insn, 16, 4);
+ rd = extract32(insn, 12, 4);
+
+ tmp = load_reg(s, rn);
+ tmp2 = load_reg(s, rm);
+ tmp3 = tcg_const_i32(1 << op1);
+ if (c & 0x2) {
+ gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
+ } else {
+ gen_helper_crc32(tmp, tmp, tmp2, tmp3);
+ }
+ tcg_temp_free_i32(tmp2);
+ tcg_temp_free_i32(tmp3);
+ store_reg(s, rd, tmp);
+ break;
+ }
case 0x5: /* saturating add/subtract */
ARCH(5TE);
rd = (insn >> 12) & 0xf;
@@ -9145,6 +9175,32 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
case 0x18: /* clz */
gen_helper_clz(tmp, tmp);
break;
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x28:
+ case 0x29:
+ case 0x2a:
+ {
+ /* crc32/crc32c */
+ uint32_t sz = op & 0x3;
+ uint32_t c = op & 0x8;
+
+ if (!arm_feature(env, ARM_FEATURE_CRC)) {
+ goto illegal_op;
+ }
+
+ tmp2 = load_reg(s, rm);
+ tmp3 = tcg_const_i32(1 << sz);
+ if (c) {
+ gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
+ } else {
+ gen_helper_crc32(tmp, tmp, tmp2, tmp3);
+ }
+ tcg_temp_free_i32(tmp2);
+ tcg_temp_free_i32(tmp3);
+ break;
+ }
default:
goto illegal_op;
}
--
1.9.0
next prev parent reply other threads:[~2014-02-26 18:02 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-26 18:01 [Qemu-devel] [PULL 00/45] target-arm queue Peter Maydell
2014-02-26 18:01 ` [Qemu-devel] [PULL 01/45] hw/misc/arm_sysctl: Fix bad boundary check on mb clock accesses Peter Maydell
2014-02-26 18:01 ` [Qemu-devel] [PULL 02/45] hw/net/stellaris_enet: Avoid unintended sign extension Peter Maydell
2014-02-26 18:01 ` [Qemu-devel] [PULL 03/45] hw/timer/arm_timer: Avoid array overrun for bad addresses Peter Maydell
2014-02-26 18:01 ` [Qemu-devel] [PULL 04/45] target-arm: Fix incorrect arithmetic constructing short-form PAR for ATS ops Peter Maydell
2014-02-26 18:01 ` [Qemu-devel] [PULL 05/45] hw/intc/exynos4210_combiner: Don't overrun output_irq array in init Peter Maydell
2014-02-26 18:01 ` [Qemu-devel] [PULL 06/45] hw/arm/musicpal: Remove nonexistent CDTP2, CDTP3 registers Peter Maydell
2014-02-26 18:01 ` [Qemu-devel] [PULL 07/45] target-arm: Load correct access bits from ARMv5 level 2 page table descriptors Peter Maydell
2014-02-26 18:01 ` [Qemu-devel] [PULL 08/45] hw/intc/arm_gic: Fix GIC_SET_LEVEL Peter Maydell
2014-02-26 18:01 ` [Qemu-devel] [PULL 09/45] linux-headers: Update from v3.14-rc3 Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 10/45] kvm: Introduce kvm_arch_irqchip_create Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 11/45] kvm: Common device control API functions Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 12/45] arm: vgic device control api support Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 13/45] hw: arm_gic_kvm: Add KVM VGIC save/restore logic Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 14/45] target-arm: Fix raw read and write functions on AArch64 registers Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 15/45] target-arm: A64: Make cache ID registers visible to AArch64 Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 16/45] target-arm: Implement AArch64 CurrentEL sysreg Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 17/45] target-arm: Implement AArch64 MIDR_EL1 Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 18/45] target-arm: Implement AArch64 cache invalidate/clean ops Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 19/45] target-arm: Implement AArch64 TLB invalidate ops Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 20/45] target-arm: Implement AArch64 dummy MDSCR_EL1 Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 21/45] target-arm: Implement AArch64 memory attribute registers Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 22/45] target-arm: Implement AArch64 SCTLR_EL1 Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 23/45] target-arm: Implement AArch64 TCR_EL1 Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 24/45] target-arm: Implement AArch64 VBAR_EL1 Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 25/45] target-arm: Implement AArch64 TTBR* Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 26/45] target-arm: Implement AArch64 MPIDR Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 27/45] target-arm: Implement AArch64 generic timers Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 28/45] target-arm: Implement AArch64 ID and feature registers Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 29/45] target-arm: Implement AArch64 dummy breakpoint and watchpoint registers Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 30/45] target-arm: Implement AArch64 OSLAR_EL1 sysreg as WI Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 31/45] target-arm: Get MMU index information correct for A64 code Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 32/45] target-arm: A64: Implement WFI Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 33/45] target-arm: Store AIF bits in env->pstate for AArch32 Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 34/45] target-arm: A64: Implement MSR (immediate) instructions Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 35/45] target-arm: Implement AArch64 view of CPACR Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 36/45] target-arm: Add utility function for checking AA32/64 state of an EL Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 37/45] include/qemu/crc32c.h: Rename include guards to match filename Peter Maydell
2014-02-26 18:02 ` Peter Maydell [this message]
2014-02-26 18:02 ` [Qemu-devel] [PULL 39/45] dma/pl330: Delete overly verbose debug printf Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 40/45] dma/pl330: Fix misleading type Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 41/45] dma/pl330: printf format type sweep Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 42/45] dma/pl330: Rename parent_obj Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 43/45] dma/pl330: Add event debugging printfs Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 44/45] dma/pl330: Fix buffer depth Peter Maydell
2014-02-26 18:02 ` [Qemu-devel] [PULL 45/45] dma/pl330: implement dmaadnh instruction Peter Maydell
2014-02-27 11:33 ` [Qemu-devel] [PULL 00/45] target-arm queue Peter Maydell
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=1393437755-23586-39-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=aliguori@amazon.com \
--cc=aurelien@aurel32.net \
--cc=blauwirbel@gmail.com \
--cc=qemu-devel@nongnu.org \
/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).