diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2020-11-09 19:08:30 -0800 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-05-16 07:13:51 -0500 |
commit | 463e45dcb4aa1a878b5ae5c6bbaf4ae70e24bf50 (patch) | |
tree | 11b2dfc3e24b7ac6dbc3060443e6f56dbfe9027d /include/fpu | |
parent | 5ffb6bd9c44763a0ee11981c632b9be96ec68d8c (diff) | |
download | qemu-463e45dcb4aa1a878b5ae5c6bbaf4ae70e24bf50.zip qemu-463e45dcb4aa1a878b5ae5c6bbaf4ae70e24bf50.tar.gz qemu-463e45dcb4aa1a878b5ae5c6bbaf4ae70e24bf50.tar.bz2 |
softfloat: Introduce sh[lr]_double primitives
Have x86_64 assembly for them, with a fallback.
This avoids shuffling values through %cl in the x86 case.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'include/fpu')
-rw-r--r-- | include/fpu/softfloat-macros.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index 672c1db..ec4e27a 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -85,6 +85,42 @@ this code that are retained. #include "fpu/softfloat-types.h" #include "qemu/host-utils.h" +/** + * shl_double: double-word merging left shift + * @l: left or most-significant word + * @r: right or least-significant word + * @c: shift count + * + * Shift @l left by @c bits, shifting in bits from @r. + */ +static inline uint64_t shl_double(uint64_t l, uint64_t r, int c) +{ +#if defined(__x86_64__) + asm("shld %b2, %1, %0" : "+r"(l) : "r"(r), "ci"(c)); + return l; +#else + return c ? (l << c) | (r >> (64 - c)) : l; +#endif +} + +/** + * shr_double: double-word merging right shift + * @l: left or most-significant word + * @r: right or least-significant word + * @c: shift count + * + * Shift @r right by @c bits, shifting in bits from @l. + */ +static inline uint64_t shr_double(uint64_t l, uint64_t r, int c) +{ +#if defined(__x86_64__) + asm("shrd %b2, %1, %0" : "+r"(r) : "r"(l), "ci"(c)); + return r; +#else + return c ? (r >> c) | (l << (64 - c)) : r; +#endif +} + /*---------------------------------------------------------------------------- | Shifts `a' right by the number of bits given in `count'. If any nonzero | bits are shifted off, they are ``jammed'' into the least significant bit of |