diff options
Diffstat (limited to 'target-i386/ops_sse.h')
-rw-r--r-- | target-i386/ops_sse.h | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h index 709732a4a7..3232abd965 100644 --- a/target-i386/ops_sse.h +++ b/target-i386/ops_sse.h @@ -802,6 +802,50 @@ void helper_rcpss(XMMReg *d, XMMReg *s) d->XMM_S(0) = approx_rcp(s->XMM_S(0)); } +static inline uint64_t helper_extrq(uint64_t src, int shift, int len) +{ + uint64_t mask; + + if (len == 0) { + mask = ~0LL; + } else { + mask = (1ULL << len) - 1; + } + return (src >> shift) & mask; +} + +void helper_extrq_r(XMMReg *d, XMMReg *s) +{ + d->XMM_Q(0) = helper_extrq(d->XMM_Q(0), s->XMM_B(1), s->XMM_B(0)); +} + +void helper_extrq_i(XMMReg *d, int index, int length) +{ + d->XMM_Q(0) = helper_extrq(d->XMM_Q(0), index, length); +} + +static inline uint64_t helper_insertq(uint64_t src, int shift, int len) +{ + uint64_t mask; + + if (len == 0) { + mask = ~0ULL; + } else { + mask = (1ULL << len) - 1; + } + return (src & ~(mask << shift)) | ((src & mask) << shift); +} + +void helper_insertq_r(XMMReg *d, XMMReg *s) +{ + d->XMM_Q(0) = helper_insertq(s->XMM_Q(0), s->XMM_B(9), s->XMM_B(8)); +} + +void helper_insertq_i(XMMReg *d, int index, int length) +{ + d->XMM_Q(0) = helper_insertq(d->XMM_Q(0), index, length); +} + void helper_haddps(XMMReg *d, XMMReg *s) { XMMReg r; |