// SPDX-License-Identifier: GPL-2.0 /* * 128-bit shift helpers. * * gcc open-codes a variable 128-bit shift when optimizing for speed, but * calls these libgcc routines when optimizing for size. */ #include #include #include union ti { __int128_t val; struct { u64 low; u64 high; }; }; noinstr __int128_t __ashlti3(__int128_t a, int shift) { union ti ti = { .val = a }; if (!shift) return ti.val; if (shift < 64) { ti.high = (ti.high << shift) | (ti.low >> (64 - shift)); ti.low <<= shift; } else { ti.high = ti.low << (shift - 64); ti.low = 0; } return ti.val; } EXPORT_SYMBOL(__ashlti3); noinstr __int128_t __ashrti3(__int128_t a, int shift) { union ti ti = { .val = a }; if (!shift) return ti.val; if (shift < 64) { ti.low = (ti.low >> shift) | (ti.high << (64 - shift)); ti.high = (s64)ti.high >> shift; } else { ti.low = (s64)ti.high >> (shift - 64); ti.high = (s64)ti.high >> 63; } return ti.val; } EXPORT_SYMBOL(__ashrti3); noinstr __int128_t __lshrti3(__int128_t a, int shift) { union ti ti = { .val = a }; if (!shift) return ti.val; if (shift < 64) { ti.low = (ti.low >> shift) | (ti.high << (64 - shift)); ti.high >>= shift; } else { ti.low = ti.high >> (shift - 64); ti.high = 0; } return ti.val; } EXPORT_SYMBOL(__lshrti3);