On Mon, Jan 03, 2011 at 04:20:47PM +0000, Peter Maydell wrote: > Add neon helper functions to implement VQSHLU, which is a > signed-to-unsigned version of VQSHL available only as an > immediate form. > > Signed-off-by: Juha Riihimäki <juha.riihim...@nokia.com> > Reviewed-by: Peter Maydell <peter.mayd...@linaro.org> > --- > target-arm/helpers.h | 4 +++ > target-arm/neon_helper.c | 47 > ++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 51 insertions(+), 0 deletions(-) > > diff --git a/target-arm/helpers.h b/target-arm/helpers.h > index 0d1bc47..b88ebae 100644 > --- a/target-arm/helpers.h > +++ b/target-arm/helpers.h > @@ -249,6 +249,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 dae063e..20f3c16 100644 > --- a/target-arm/neon_helper.c > +++ b/target-arm/neon_helper.c > @@ -632,6 +632,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); > +}
I guess defining this function using helper_neon_qshl_u32() instead of using NEON_VOP_ENV(qshlu_s32, neon_u32, 1) is to optimize the generated code. Note that it only make 48 bytes difference, with one jump. > +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 { \ Reviewed-by: Aurelien Jarno <aurel...@aurel32.net> -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net