149390697SRobert Clausecker /*-
249390697SRobert Clausecker * Copyright (c) 2023 The FreeBSD Foundation
349390697SRobert Clausecker *
449390697SRobert Clausecker * This software was developed by Robert Clausecker <fuz@FreeBSD.org>
549390697SRobert Clausecker * under sponsorship from the FreeBSD Foundation.
649390697SRobert Clausecker *
749390697SRobert Clausecker * Redistribution and use in source and binary forms, with or without
849390697SRobert Clausecker * modification, are permitted provided that the following conditions
949390697SRobert Clausecker * are met:
1049390697SRobert Clausecker * 1. Redistributions of source code must retain the above copyright
1149390697SRobert Clausecker * notice, this list of conditions and the following disclaimer.
1249390697SRobert Clausecker * 2. Redistributions in binary form must reproduce the above copyright
1349390697SRobert Clausecker * notice, this list of conditions and the following disclaimer in the
1449390697SRobert Clausecker * documentation and/or other materials provided with the distribution.
1549390697SRobert Clausecker *
1649390697SRobert Clausecker * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ''AS IS'' AND
1749390697SRobert Clausecker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1849390697SRobert Clausecker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1949390697SRobert Clausecker * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2049390697SRobert Clausecker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2149390697SRobert Clausecker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2249390697SRobert Clausecker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2349390697SRobert Clausecker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2449390697SRobert Clausecker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2549390697SRobert Clausecker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2649390697SRobert Clausecker * SUCH DAMAGE
2749390697SRobert Clausecker */
2849390697SRobert Clausecker
2949390697SRobert Clausecker #include <atf-c.h>
3049390697SRobert Clausecker #include <limits.h>
3149390697SRobert Clausecker #include <stdint.h>
3249390697SRobert Clausecker #include <strings.h>
3349390697SRobert Clausecker
3449390697SRobert Clausecker #ifndef FFS
3549390697SRobert Clausecker # define FFS ffs
3649390697SRobert Clausecker # define TYPE int
3749390697SRobert Clausecker # define TYPE_MIN INT_MIN
3849390697SRobert Clausecker #endif
3949390697SRobert Clausecker
4049390697SRobert Clausecker ATF_TC_WITHOUT_HEAD(zero);
ATF_TC_BODY(zero,tc)4149390697SRobert Clausecker ATF_TC_BODY(zero, tc)
4249390697SRobert Clausecker {
4349390697SRobert Clausecker ATF_CHECK_EQ((TYPE)0, FFS(0));
4449390697SRobert Clausecker }
4549390697SRobert Clausecker
4649390697SRobert Clausecker ATF_TC_WITHOUT_HEAD(twobit);
ATF_TC_BODY(twobit,tc)4749390697SRobert Clausecker ATF_TC_BODY(twobit, tc)
4849390697SRobert Clausecker {
4949390697SRobert Clausecker const TYPE one = 1;
5049390697SRobert Clausecker TYPE x;
5149390697SRobert Clausecker const int n = sizeof(TYPE) * CHAR_BIT;
5249390697SRobert Clausecker int i, j;
5349390697SRobert Clausecker
5449390697SRobert Clausecker for (i = 0; i < n - 1; i++)
5549390697SRobert Clausecker for (j = 0; j <= i; j++) {
5649390697SRobert Clausecker x = one << i | one << j;
5749390697SRobert Clausecker ATF_CHECK_EQ_MSG(j + 1, FFS(x),
5849390697SRobert Clausecker "%s(%#jx) == %d != %d", __STRING(FFS), (intmax_t)x, FFS(x), j + 1);
5949390697SRobert Clausecker }
6049390697SRobert Clausecker }
6149390697SRobert Clausecker
6249390697SRobert Clausecker ATF_TC_WITHOUT_HEAD(twobitneg);
ATF_TC_BODY(twobitneg,tc)6349390697SRobert Clausecker ATF_TC_BODY(twobitneg, tc)
6449390697SRobert Clausecker {
6549390697SRobert Clausecker const TYPE one = 1;
6649390697SRobert Clausecker TYPE x;
6749390697SRobert Clausecker const int n = sizeof(TYPE) * CHAR_BIT;
6849390697SRobert Clausecker int i, j;
6949390697SRobert Clausecker
7049390697SRobert Clausecker for (i = 0; i < n - 1; i++)
7149390697SRobert Clausecker for (j = 0; j <= i; j++) {
7249390697SRobert Clausecker x = one << i | one << j | TYPE_MIN;
7349390697SRobert Clausecker ATF_CHECK_EQ_MSG(j + 1, FFS(x),
7449390697SRobert Clausecker "%s(%#jx) == %d != %d", __STRING(FFS), (intmax_t)x, FFS(x), j + 1);
7549390697SRobert Clausecker }
7649390697SRobert Clausecker }
7749390697SRobert Clausecker
7849390697SRobert Clausecker
ATF_TP_ADD_TCS(tp)7949390697SRobert Clausecker ATF_TP_ADD_TCS(tp)
8049390697SRobert Clausecker {
8149390697SRobert Clausecker
8249390697SRobert Clausecker ATF_TP_ADD_TC(tp, zero);
8349390697SRobert Clausecker ATF_TP_ADD_TC(tp, twobit);
8449390697SRobert Clausecker ATF_TP_ADD_TC(tp, twobitneg);
8549390697SRobert Clausecker
8649390697SRobert Clausecker return (atf_no_error());
8749390697SRobert Clausecker }
88