summaryrefslogtreecommitdiff
path: root/target-arm
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
commitaa633469ed902a6d96b3d4013ec5ce32597f0626 (patch)
treea6ffde3939a1065b13d8ed6c45fe9c2312ca2eea /target-arm
parent130f2e7dcb4a5f9534fc65200121f06983435a77 (diff)
downloadqemu-aa633469ed902a6d96b3d4013ec5ce32597f0626.tar.gz
target-arm: A32/T32: Mask CRC value in calling code, not helper
Bring the 32-bit CRC helper functions into line with the A64 ones, by masking the high bytes of the value in the calling code rather than the helper. This is more efficient since we can determine the mask at translation time. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1401458125-27977-7-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'target-arm')
-rw-r--r--target-arm/helper.c25
-rw-r--r--target-arm/translate.c10
2 files changed, 16 insertions, 19 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1e50a7840e..177ed076c7 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5559,28 +5559,15 @@ 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;
- }
-}
-
+/* CRC helpers.
+ * The upper bytes of val (above the number specified by 'bytes') must have
+ * been zeroed out by the caller.
+ */
uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
{
uint8_t buf[4];
- crc_init_buffer(buf, val, bytes);
+ stl_le_p(buf, val);
/* zlib crc32 converts the accumulator and output to one's complement. */
return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
@@ -5590,7 +5577,7 @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
{
uint8_t buf[4];
- crc_init_buffer(buf, val, bytes);
+ stl_le_p(buf, val);
/* Linux crc32c converts the output to one's complement. */
return crc32c(acc, buf, bytes) ^ 0xffffffff;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 41c3fc77b0..351943f6f3 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7806,6 +7806,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
tmp = load_reg(s, rn);
tmp2 = load_reg(s, rm);
+ if (op1 == 0) {
+ tcg_gen_andi_i32(tmp2, tmp2, 0xff);
+ } else if (op1 == 1) {
+ tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
+ }
tmp3 = tcg_const_i32(1 << op1);
if (c & 0x2) {
gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
@@ -9438,6 +9443,11 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
}
tmp2 = load_reg(s, rm);
+ if (sz == 0) {
+ tcg_gen_andi_i32(tmp2, tmp2, 0xff);
+ } else if (sz == 1) {
+ tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
+ }
tmp3 = tcg_const_i32(1 << sz);
if (c) {
gen_helper_crc32c(tmp, tmp, tmp2, tmp3);