[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 36/48] target-arm: fix neon vqshl/vqshlu instruction
From: |
Riku Voipio |
Subject: |
[Qemu-devel] [PATCH 36/48] target-arm: fix neon vqshl/vqshlu instructions |
Date: |
Fri, 26 Mar 2010 16:06:56 +0000 |
From: Juha Riihimäki <address@hidden>
Signed-Off-By: Riku Voipio <address@hidden>
Signed-off-by: Juha Riihimäki <address@hidden>
---
target-arm/helpers.h | 4 +++
target-arm/neon_helper.c | 58 +++++++++++++++++++++++++++++++++++++++++----
target-arm/translate.c | 28 +++++++++++-----------
3 files changed, 70 insertions(+), 20 deletions(-)
diff --git a/target-arm/helpers.h b/target-arm/helpers.h
index a5fd2e8..e1a8136 100644
--- a/target-arm/helpers.h
+++ b/target-arm/helpers.h
@@ -253,6 +253,10 @@ DEF_HELPER_3(neon_qshl_u32, i32, env, i32, i32)
DEF_HELPER_3(neon_qshl_s32, i32, env, i32, i32)
DEF_HELPER_3(neon_qshl_u64, i64, env, i64, i64)
DEF_HELPER_3(neon_qshl_s64, i64, env, i64, i64)
+DEF_HELPER_3(neon_qshlu_s8, i32, env, i32, i32)
+DEF_HELPER_3(neon_qshlu_s16, i32, env, i32, i32)
+DEF_HELPER_3(neon_qshlu_s32, i32, env, i32, i32)
+DEF_HELPER_3(neon_qshlu_s64, i64, env, i64, i64)
DEF_HELPER_3(neon_qrshl_u8, i32, env, i32, i32)
DEF_HELPER_3(neon_qrshl_s8, i32, env, i32, i32)
DEF_HELPER_3(neon_qrshl_u16, i32, env, i32, i32)
diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index 924bf40..7985293 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -600,8 +600,6 @@ uint64_t HELPER(neon_qshl_u64)(CPUState *env, uint64_t val,
uint64_t shiftop)
if (val) {
val = ~(uint64_t)0;
SET_QC();
- } else {
- val = 0;
}
} else if (shift <= -64) {
val = 0;
@@ -622,9 +620,10 @@ uint64_t HELPER(neon_qshl_u64)(CPUState *env, uint64_t
val, uint64_t shiftop)
int8_t tmp; \
tmp = (int8_t)src2; \
if (tmp >= (ssize_t)sizeof(src1) * 8) { \
- if (src1) \
+ if (src1) { \
SET_QC(); \
- dest = src1 >> 31; \
+ } \
+ dest = src1 ? ((uint32_t)(1 << (sizeof(src1) * 8 - 1)) - (src1 > 0 ? 1
: 0)) : 0; \
} else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
dest = src1 >> 31; \
} else if (tmp < 0) { \
@@ -633,7 +632,7 @@ uint64_t HELPER(neon_qshl_u64)(CPUState *env, uint64_t val,
uint64_t shiftop)
dest = src1 << tmp; \
if ((dest >> tmp) != src1) { \
SET_QC(); \
- dest = src2 >> 31; \
+ dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)) - (src1 > 0 ? 1 :
0); \
} \
}} while (0)
NEON_VOP_ENV(qshl_s8, neon_s8, 4)
@@ -650,7 +649,7 @@ uint64_t HELPER(neon_qshl_s64)(CPUState *env, uint64_t
valop, uint64_t shiftop)
SET_QC();
val = (val >> 63) & ~SIGNBIT64;
}
- } else if (shift <= 64) {
+ } else if (shift <= -64) {
val >>= 63;
} else if (shift < 0) {
val >>= -shift;
@@ -665,6 +664,53 @@ uint64_t HELPER(neon_qshl_s64)(CPUState *env, uint64_t
valop, uint64_t shiftop)
return val;
}
+#define NEON_FN(dest, src1, src2) do { \
+ if (src1 & (1 << (sizeof(src1) * 8 - 1))) { \
+ SET_QC(); \
+ dest = 0; \
+ } else { \
+ int8_t tmp; \
+ tmp = (int8_t)src2; \
+ if (tmp >= (ssize_t)sizeof(src1) * 8) { \
+ if (src1) { \
+ SET_QC(); \
+ dest = ~0; \
+ } else { \
+ dest = 0; \
+ } \
+ } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
+ dest = 0; \
+ } else if (tmp < 0) { \
+ dest = src1 >> -tmp; \
+ } else { \
+ dest = src1 << tmp; \
+ if ((dest >> tmp) != src1) { \
+ SET_QC(); \
+ dest = ~0; \
+ } \
+ } \
+ }} while (0)
+NEON_VOP_ENV(qshlu_s8, neon_u8, 4)
+NEON_VOP_ENV(qshlu_s16, neon_u16, 2)
+#undef NEON_FN
+
+uint32_t HELPER(neon_qshlu_s32)(CPUState *env, uint32_t valop, uint32_t
shiftop)
+{
+ if ((int32_t)valop < 0) {
+ SET_QC();
+ return 0;
+ }
+ return helper_neon_qshl_u32(env, valop, shiftop);
+}
+
+uint64_t HELPER(neon_qshlu_s64)(CPUState *env, uint64_t valop, uint64_t
shiftop)
+{
+ if ((int64_t)valop < 0) {
+ SET_QC();
+ return 0;
+ }
+ return helper_neon_qshl_u64(env, valop, shiftop);
+}
/* FIXME: This is wrong. */
#define NEON_FN(dest, src1, src2) do { \
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 26e6bf4..97fac4d 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4139,9 +4139,9 @@ static int disas_neon_data_insn(CPUState * env,
DisasContext *s, uint32_t insn)
case 9: /* VQSHL */
if (u) {
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
- cpu_V0, cpu_V0);
+ cpu_V1, cpu_V0);
} else {
- gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
+ gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
cpu_V1, cpu_V0);
}
break;
@@ -4612,10 +4612,10 @@ static int disas_neon_data_insn(CPUState * env,
DisasContext *s, uint32_t insn)
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
break;
case 6: /* VQSHLU */
- gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0,
- cpu_V1);
+ gen_helper_neon_qshlu_s64(cpu_V0, cpu_env, cpu_V0,
+ cpu_V1);
break;
- case 7: /* VQSHL/VQSHLU */
+ case 7: /* VQSHL */
if (u) {
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
cpu_V0, cpu_V1);
@@ -4673,26 +4673,26 @@ static int disas_neon_data_insn(CPUState * env,
DisasContext *s, uint32_t insn)
}
break;
case 6: /* VQSHLU */
- GEN_NEON_INTEGER_OP_ENV(qshl);
- break;
- case 7: /* VQSHLU */
switch (size) {
case 0:
- gen_helper_neon_qshl_u8(tmp, cpu_env, tmp,
- tmp2);
+ gen_helper_neon_qshlu_s8(tmp, cpu_env, tmp,
+ tmp2);
break;
case 1:
- gen_helper_neon_qshl_u16(tmp, cpu_env, tmp,
- tmp2);
+ gen_helper_neon_qshlu_s16(tmp, cpu_env, tmp,
+ tmp2);
break;
case 2:
- gen_helper_neon_qshl_u32(tmp, cpu_env, tmp,
- tmp2);
+ gen_helper_neon_qshlu_s32(tmp, cpu_env, tmp,
+ tmp2);
break;
default:
abort(); /* size == 3 is handled earlier */
}
break;
+ case 7: /* VQSHL */
+ GEN_NEON_INTEGER_OP_ENV(qshl);
+ break;
}
tcg_temp_free_i32(tmp2);
--
1.6.5
- [Qemu-devel] [PATCH 04/48] audio: fix integer overflow expression, (continued)
- [Qemu-devel] [PATCH 04/48] audio: fix integer overflow expression, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 33/48] Add OpenGL ES accelerator support, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 34/48] target-arm: add support for smc, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 30/48] savevm and reset support for soc_dma, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 29/48] Add triton2 (twl4030) driver, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 20/48] add reset support for musb, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 19/48] usb-ohci: add omap init support, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 37/48] target-arm: fix neon vqrshl instruction, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 27/48] tsc2005 overhaul, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 10/48] Lots of ARM TCG changes, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 36/48] target-arm: fix neon vqshl/vqshlu instructions,
Riku Voipio <=
- [Qemu-devel] [PATCH 24/48] onenand overhaul, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 26/48] SD overhaul, Riku Voipio, 2010/03/26
- [Qemu-devel] [PATCH 05/48] audio: fix coreaudio compilation, Riku Voipio, 2010/03/26
- Re: [Qemu-devel] [PATCH 00/48] RFC: omap3 patch collection, Paul Brook, 2010/03/26