18038068aSConrad Meyer /*-
28038068aSConrad Meyer * Copyright (c) 2018 Conrad Meyer <cem@freebsd.org>
38038068aSConrad Meyer * All rights reserved.
48038068aSConrad Meyer *
58038068aSConrad Meyer * Redistribution and use in source and binary forms, with or without
68038068aSConrad Meyer * modification, are permitted provided that the following conditions
78038068aSConrad Meyer * are met:
88038068aSConrad Meyer * 1. Redistributions of source code must retain the above copyright
98038068aSConrad Meyer * notice, this list of conditions and the following disclaimer.
108038068aSConrad Meyer * 2. Redistributions in binary form must reproduce the above copyright
118038068aSConrad Meyer * notice, this list of conditions and the following disclaimer in the
128038068aSConrad Meyer * documentation and/or other materials provided with the distribution.
138038068aSConrad Meyer *
148038068aSConrad Meyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
158038068aSConrad Meyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
168038068aSConrad Meyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
178038068aSConrad Meyer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
188038068aSConrad Meyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
198038068aSConrad Meyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
208038068aSConrad Meyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
218038068aSConrad Meyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
228038068aSConrad Meyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
238038068aSConrad Meyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
248038068aSConrad Meyer * SUCH DAMAGE.
258038068aSConrad Meyer *
268038068aSConrad Meyer * $FreeBSD$
278038068aSConrad Meyer */
288038068aSConrad Meyer
298038068aSConrad Meyer #include "zstd_kfreebsd.h"
30*22aec4deSConrad Meyer #include <sys/param.h>
318fb95dc2SConrad Meyer #include <sys/endian.h>
328038068aSConrad Meyer
33*22aec4deSConrad Meyer #ifndef _KERNEL
34*22aec4deSConrad Meyer #include <strings.h>
35*22aec4deSConrad Meyer #endif
36*22aec4deSConrad Meyer
378038068aSConrad Meyer /*
388038068aSConrad Meyer * The kernel as a standalone target does not link against libgcc or
398038068aSConrad Meyer * libcompiler-rt. On platforms (e.g., MIPS and RISCV) that do not have a
408038068aSConrad Meyer * direct assembly implementation of the relevant builtin functions that zstd
418038068aSConrad Meyer * references, the compiler converts them into calls to the runtime library
428038068aSConrad Meyer * intrinsics. Since the kernel does not link against the runtime libraries,
438038068aSConrad Meyer * this results in a failure to link the kernel.
448038068aSConrad Meyer *
458038068aSConrad Meyer * The goal of the following definitions is to use supported kernel constructs
468038068aSConrad Meyer * to implement the same functionality, without adding diff to the Zstd contrib
478038068aSConrad Meyer * code.
488038068aSConrad Meyer *
498038068aSConrad Meyer * A subsequent enhancement might create a mini compiler-rt library for kernel
508038068aSConrad Meyer * use and move these over there instead.
518038068aSConrad Meyer */
528038068aSConrad Meyer
538fb95dc2SConrad Meyer /* Swap endianness */
548fb95dc2SConrad Meyer int
__bswapsi2(int x)558fb95dc2SConrad Meyer __bswapsi2(int x)
568fb95dc2SConrad Meyer {
578fb95dc2SConrad Meyer return (bswap32(x));
588fb95dc2SConrad Meyer }
598fb95dc2SConrad Meyer
608fb95dc2SConrad Meyer long long
__bswapdi2(long long x)618fb95dc2SConrad Meyer __bswapdi2(long long x)
628fb95dc2SConrad Meyer {
638fb95dc2SConrad Meyer return (bswap64(x));
648fb95dc2SConrad Meyer }
658fb95dc2SConrad Meyer
668038068aSConrad Meyer /* Count trailing zeros */
678038068aSConrad Meyer int
__ctzsi2(int x)688038068aSConrad Meyer __ctzsi2(int x)
698038068aSConrad Meyer {
708038068aSConrad Meyer if (x == 0)
718038068aSConrad Meyer return (sizeof(x) * NBBY);
728038068aSConrad Meyer return (ffs(x) - 1);
738038068aSConrad Meyer }
748038068aSConrad Meyer
758038068aSConrad Meyer long long
__ctzdi2(long long x)768038068aSConrad Meyer __ctzdi2(long long x)
778038068aSConrad Meyer {
788038068aSConrad Meyer if (x == 0)
798038068aSConrad Meyer return (sizeof(x) * NBBY);
808038068aSConrad Meyer return (ffsll(x) - 1);
818038068aSConrad Meyer }
828038068aSConrad Meyer
838038068aSConrad Meyer /* Count leading zeros */
848038068aSConrad Meyer int
__clzsi2(int x)858038068aSConrad Meyer __clzsi2(int x)
868038068aSConrad Meyer {
878038068aSConrad Meyer return (sizeof(x) * NBBY - fls(x));
888038068aSConrad Meyer }
898038068aSConrad Meyer
908038068aSConrad Meyer long long
__clzdi2(long long x)918038068aSConrad Meyer __clzdi2(long long x)
928038068aSConrad Meyer {
938038068aSConrad Meyer return (sizeof(x) * NBBY - flsll(x));
948038068aSConrad Meyer }
95