Code » test-msb » commit 7a38a37
First commit
author | Olivier Brunel
<jjk@jjacky.com> 2023-01-19 08:41:32 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-01-19 21:32:23 UTC |
parent | 291bf2ce89c864b728719722f26552d440744f45 |
.gitignore | +35 | -0 |
meta/AUTHORS | +9 | -0 |
meta/COPYING | +12 | -336 |
meta/LICENSE | +1 | -14 |
meta/code | +1 | -1 |
meta/deps-bin | +33 | -0 |
meta/desc | +4 | -0 |
meta/doc | +0 | -1 |
meta/git | +1 | -1 |
meta/site | +0 | -1 |
project.mk | +17 | -4 |
scripts/check | +10 | -0 |
scripts/test | +27 | -0 |
src/check.c | +34 | -0 |
src/m0.c | +13 | -0 |
src/m1.c | +18 | -0 |
src/m10.c | +9 | -0 |
src/m2.c | +31 | -0 |
src/m3.c | +23 | -0 |
src/m4.c | +34 | -0 |
src/m5.c | +118 | -0 |
src/m6.c | +35 | -0 |
src/m7.c | +38 | -0 |
src/m8.c | +38 | -0 |
src/m9.c | +13 | -0 |
src/test-alt.c | +35 | -0 |
src/test.c | +19 | -0 |
diff --git a/.gitignore b/.gitignore index 7ccd516..24b4937 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,38 @@ *.o *.lo *.d +check +check0 +check1 +check2 +check3 +check4 +check5 +check6 +check7 +check8 +check9 +check10 +test +test0 +test1 +test2 +test3 +test4 +test5 +test6 +test7 +test8 +test9 +test10 +test-alt0 +test-alt1 +test-alt2 +test-alt3 +test-alt4 +test-alt5 +test-alt6 +test-alt7 +test-alt8 +test-alt9 +test-alt10 diff --git a/meta/AUTHORS b/meta/AUTHORS index 6aef6f1..b32c3a5 100644 --- a/meta/AUTHORS +++ b/meta/AUTHORS @@ -1,2 +1,11 @@ Main author: * Olivier Brunel <jjk@jjacky.com> + +Contributors: +* VoidStar [method 2] +* Kaz Kylheku [method 4, method 5] +* Kim Walisch [method 6] +* Mark Dickinson [method 6] +* Niklas B. [method 7] +* Jim Mischel [method 8] +* David Howells <dhowells@redhat.com> [method 9, test-alt] diff --git a/meta/COPYING b/meta/COPYING index a43ea21..3ef26ce 100644 --- a/meta/COPYING +++ b/meta/COPYING @@ -1,339 +1,15 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 +# ISC License - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +Copyright (C) 2023 Olivier Brunel - Preamble +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/meta/LICENSE b/meta/LICENSE index f867b90..272cd42 100644 --- a/meta/LICENSE +++ b/meta/LICENSE @@ -1,15 +1,2 @@ -Released under GPL-2.0, see COPYING for more. +Released under ISC, see COPYING for more. Copyright (C) 2023 Olivier Brunel - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -version 2, as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/meta/code b/meta/code index b2c0c07..9b9b216 100644 --- a/meta/code +++ b/meta/code @@ -1 +1 @@ -https://lila.oss/code/test +https://lila.oss/code/test-msb diff --git a/meta/deps-bin b/meta/deps-bin new file mode 100644 index 0000000..63eaea8 --- /dev/null +++ b/meta/deps-bin @@ -0,0 +1,33 @@ +test0: src/test.o src/m0.o +test1: src/test.o src/m1.o +test2: src/test.o src/m2.o +test3: src/test.o src/m3.o +test4: src/test.o src/m4.o +test5: src/test.o src/m5.o +test6: src/test.o src/m6.o +test7: src/test.o src/m7.o +test8: src/test.o src/m8.o +test9: src/test.o src/m9.o +test10: src/test.o src/m10.o +test-alt0: src/test-alt.o src/m0.o +test-alt1: src/test-alt.o src/m1.o +test-alt2: src/test-alt.o src/m2.o +test-alt3: src/test-alt.o src/m3.o +test-alt4: src/test-alt.o src/m4.o +test-alt5: src/test-alt.o src/m5.o +test-alt6: src/test-alt.o src/m6.o +test-alt7: src/test-alt.o src/m7.o +test-alt8: src/test-alt.o src/m8.o +test-alt9: src/test-alt.o src/m9.o +test-alt10: src/test-alt.o src/m10.o +check0: src/check.o src/m0.o +check1: src/check.o src/m1.o +check2: src/check.o src/m2.o +check3: src/check.o src/m3.o +check4: src/check.o src/m4.o +check5: src/check.o src/m5.o +check6: src/check.o src/m6.o +check7: src/check.o src/m7.o +check8: src/check.o src/m8.o +check9: src/check.o src/m9.o +check10: src/check.o src/m10.o diff --git a/meta/desc b/meta/desc new file mode 100644 index 0000000..42f29ec --- /dev/null +++ b/meta/desc @@ -0,0 +1,4 @@ +Tests of different methods to find the first bit set (MSB) + +Testing of different methods to find the first bit set - or most significant bit +- to see which is fastest. diff --git a/meta/doc b/meta/doc deleted file mode 100644 index d6b75cd..0000000 --- a/meta/doc +++ /dev/null @@ -1 +0,0 @@ -https://lila.oss/doc/test diff --git a/meta/git b/meta/git index 4bbf44f..7dbc6f1 100644 --- a/meta/git +++ b/meta/git @@ -1 +1 @@ -git://lila.oss/test.git +git://lila.oss/test-msb.git diff --git a/meta/site b/meta/site deleted file mode 100644 index 68a3318..0000000 --- a/meta/site +++ /dev/null @@ -1 +0,0 @@ -https://lila.oss/test diff --git a/project.mk b/project.mk index 0892fd9..b080fe4 100644 --- a/project.mk +++ b/project.mk @@ -1,7 +1,20 @@ -$(error You need to edit project.mk) # binaries: -- don't forget to set meta/deps-bin with all deps & .o files -BINS = +BINS = test0 test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 +BINS += test-alt0 test-alt1 test-alt2 test-alt3 test-alt4 test-alt5 \ + test-alt6 test-alt7 test-alt8 test-alt9 test-alt10 +BINS += check0 check1 check2 check3 check4 check5 check6 check7 check8 \ + check9 check10 -# librairies -- don't forget to set meta/deps-lib with all deps & .o files -LIBS = +SCRIPTS = check test + +check: scripts/check + +test: scripts/test + +CLEAN += $(SCRIPTS) + +all: $(SCRIPTS) + +$(SCRIPTS): + $(_CP) cp scripts/$@ $@ diff --git a/scripts/check b/scripts/check new file mode 100755 index 0000000..91cdf67 --- /dev/null +++ b/scripts/check @@ -0,0 +1,10 @@ +#!/bin/sh + +i=0 +while test $i -lt 11; do + ./check$i + e=$? + if test $e -ne 0; then echo "method $i: $e errors found"; fi + i=$(($i+1)) +done +echo "done." diff --git a/scripts/test b/scripts/test new file mode 100755 index 0000000..b44203d --- /dev/null +++ b/scripts/test @@ -0,0 +1,27 @@ +#!/bin/sh + +if test $# -ne 1 || test $1 == "tst"; then + echo "## Tests" + echo + i=0 + while test $i -lt 11; do + printf '``` method-'$i + time ./test$i + echo '```' + echo + i=$(($i+1)) + done +fi + +if test $# -ne 1 || test $1 == "alt"; then + echo "## Alternative Tests" + echo + i=0 + while test $i -lt 11; do + printf '``` method-'$i + time ./test-alt$i + echo '```' + echo + i=$(($i+1)) + done +fi diff --git a/src/check.c b/src/check.c new file mode 100644 index 0000000..5ae1443 --- /dev/null +++ b/src/check.c @@ -0,0 +1,34 @@ +#include <stdint.h> +#include <stdio.h> + +typedef uint64_t u64; + +extern int msb(u64 v); + +int main(void) +{ + int rc = 0; + + for(int n = 0; n < 64; ++n) { + u64 v = 1ULL << n; + int r = msb(v - 1); + if (r != n) { + ++rc; + printf("ERROR: msb(%zu)=%d [expected:%d]\n", v - 1, r, n); + } + r = msb(v); + if (r != n + 1) { + ++rc; + printf("ERROR: msb(%zu)=%d [expected:%d]\n", v, r, n + 1); + } + if (v + 1 != 2) { + r = msb(v + 1); + if (r != n + 1) { + ++rc; + printf("ERROR: msb(%zu)=%d [expected:%d]\n", v + 1, r, n + 1); + } + } + } + + return rc; +} diff --git a/src/m0.c b/src/m0.c new file mode 100644 index 0000000..e0bd2e8 --- /dev/null +++ b/src/m0.c @@ -0,0 +1,13 @@ +#include <stdint.h> + +typedef uint64_t u64; + +int msb(u64 v) +{ + if (!v) return 0; + + int n; + for(n = 0; v >>= 1; ++n) + ; + return n + 1; +} diff --git a/src/m1.c b/src/m1.c new file mode 100644 index 0000000..6d49569 --- /dev/null +++ b/src/m1.c @@ -0,0 +1,18 @@ +#include <stdint.h> + +typedef uint64_t u64; + +int msb(u64 v) +{ + if (!v) return 0; + + int k = 0; + if (v > 0xFFFFFFFFUL) { v >>= 32; k = 32; } + if (v > 0x0000FFFFUL) { v >>= 16; k |= 16; } + if (v > 0x000000FFUL) { v >>= 8; k |= 8; } + if (v > 0x0000000FUL) { v >>= 4; k |= 4; } + if (v > 0x00000003UL) { v >>= 2; k |= 2; } + if (v > 0x00000001UL) { k |= 1; } + + return k + 1; +} diff --git a/src/m10.c b/src/m10.c new file mode 100644 index 0000000..48cb729 --- /dev/null +++ b/src/m10.c @@ -0,0 +1,9 @@ +#include <stdint.h> + +typedef uint64_t u64; + +int msb(u64 v) +{ + if (!v) return 0; + return 64 - __builtin_clzll(v); +} diff --git a/src/m2.c b/src/m2.c new file mode 100644 index 0000000..85433ba --- /dev/null +++ b/src/m2.c @@ -0,0 +1,31 @@ +#include <stdint.h> + +typedef uint8_t u8; +typedef uint64_t u64; + +/* VoidStar */ + +const u8 kTableLog2[256] = { +0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, +5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, +6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, +6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, +7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +int msb(u64 v) +{ + if (!v) return 0; + + int k = 0; + if (v > 0xFFFFFFFFUL) { v >>= 32; k = 32; } + if (v > 0x00FFFFFFUL) { v >>= 24; k |= 24; } + if (v > 0x0000FFFFUL) { v >>= 16; k |= 16; } + if (v > 0x000000FFUL) { v >>= 8; k |= 8; } + k |= kTableLog2[v]; /* precompute the Log2 of the low byte */ + + return k + 1; +} diff --git a/src/m3.c b/src/m3.c new file mode 100644 index 0000000..53efbc7 --- /dev/null +++ b/src/m3.c @@ -0,0 +1,23 @@ +#include <stdint.h> + +typedef uint64_t u64; + +int msb(u64 v) +{ + if (!v) return 0; + + u64 msb = 32; + u64 step = msb; + while (step > 1) + { + step /= 2; + if (v >> msb) + msb += step; + else + msb -= step; + } + if (v >> msb) + ++msb; + + return msb; +} diff --git a/src/m4.c b/src/m4.c new file mode 100644 index 0000000..cabd6b4 --- /dev/null +++ b/src/m4.c @@ -0,0 +1,34 @@ +#include <stdint.h> + +typedef uint64_t u64; + +/* Kaz Kylheku */ + +int msb(u64 v) +{ + const long long mask[] = { + 0x00000000FFFFFFFF, + 0x000000000000FFFF, + 0x00000000000000FF, + 0x000000000000000F, + 0x0000000000000003, + 0x0000000000000001 + }; + int hi = 64; + int lo = 0; + int i = 0; + + if (v == 0) + return 0; + + for (i = 0; i < sizeof mask / sizeof mask[0]; i++) { + int mi = lo + (hi - lo) / 2; + + if ((v >> mi) != 0) + lo = mi; + else if ((v & (mask[i] << lo)) != 0) + hi = mi; + } + + return lo + 1; +} diff --git a/src/m5.c b/src/m5.c new file mode 100644 index 0000000..c969a95 --- /dev/null +++ b/src/m5.c @@ -0,0 +1,118 @@ +#include <stdint.h> + +typedef uint64_t u64; + +/* Kaz Kylheku */ + +int msb(u64 n) +{ + if (n & 0xFFFFFFFF00000000) { + if (n & 0xFFFF000000000000) { + if (n & 0xFF00000000000000) { + if (n & 0xF000000000000000) { + if (n & 0xC000000000000000) + return (n & 0x8000000000000000) ? 64 : 63; + else + return (n & 0x2000000000000000) ? 62 : 61; + } else { + if (n & 0x0C00000000000000) + return (n & 0x0800000000000000) ? 60 : 59; + else + return (n & 0x0200000000000000) ? 58 : 57; + } + } else { + if (n & 0x00F0000000000000) { + if (n & 0x00C0000000000000) + return (n & 0x0080000000000000) ? 56 : 55; + else + return (n & 0x0020000000000000) ? 54 : 53; + } else { + if (n & 0x000C000000000000) + return (n & 0x0008000000000000) ? 52 : 51; + else + return (n & 0x0002000000000000) ? 50 : 49; + } + } + } else { + if (n & 0x0000FF0000000000) { + if (n & 0x0000F00000000000) { + if (n & 0x0000C00000000000) + return (n & 0x0000800000000000) ? 48 : 47; + else + return (n & 0x0000200000000000) ? 46 : 45; + } else { + if (n & 0x00000C0000000000) + return (n & 0x0000080000000000) ? 44 : 43; + else + return (n & 0x0000020000000000) ? 42 : 41; + } + } else { + if (n & 0x000000F000000000) { + if (n & 0x000000C000000000) + return (n & 0x0000008000000000) ? 40 : 39; + else + return (n & 0x0000002000000000) ? 38 : 37; + } else { + if (n & 0x0000000C00000000) + return (n & 0x0000000800000000) ? 36 : 35; + else + return (n & 0x0000000200000000) ? 34 : 33; + } + } + } + } else { + if (n & 0x00000000FFFF0000) { + if (n & 0x00000000FF000000) { + if (n & 0x00000000F0000000) { + if (n & 0x00000000C0000000) + return (n & 0x0000000080000000) ? 32 : 31; + else + return (n & 0x0000000020000000) ? 30 : 29; + } else { + if (n & 0x000000000C000000) + return (n & 0x0000000008000000) ? 28 : 27; + else + return (n & 0x0000000002000000) ? 26 : 25; + } + } else { + if (n & 0x0000000000F00000) { + if (n & 0x0000000000C00000) + return (n & 0x0000000000800000) ? 24 : 23; + else + return (n & 0x0000000000200000) ? 22 : 21; + } else { + if (n & 0x00000000000C0000) + return (n & 0x0000000000080000) ? 20 : 19; + else + return (n & 0x0000000000020000) ? 18 : 17; + } + } + } else { + if (n & 0x000000000000FF00) { + if (n & 0x000000000000F000) { + if (n & 0x000000000000C000) + return (n & 0x0000000000008000) ? 16 : 15; + else + return (n & 0x0000000000002000) ? 14 : 13; + } else { + if (n & 0x0000000000000C00) + return (n & 0x0000000000000800) ? 12 : 11; + else + return (n & 0x0000000000000200) ? 10 : 9; + } + } else { + if (n & 0x00000000000000F0) { + if (n & 0x00000000000000C0) + return (n & 0x0000000000000080) ? 8 : 7; + else + return (n & 0x0000000000000020) ? 6 : 5; + } else { + if (n & 0x000000000000000C) + return (n & 0x0000000000000008) ? 4 : 3; + else + return (n & 0x0000000000000002) ? 2 : (n ? 1 : 0); + } + } + } + } +} diff --git a/src/m6.c b/src/m6.c new file mode 100644 index 0000000..2ade11e --- /dev/null +++ b/src/m6.c @@ -0,0 +1,35 @@ +#include <stdint.h> + +typedef uint8_t u8; +typedef uint64_t u64; + +/* Kim Walisch, Mark Dickinson + * https://www.chessprogramming.org/BitScan#De_Bruijn_Multiplication_2 + */ + +const u8 index64[64] = { + 0, 47, 1, 56, 48, 27, 2, 60, + 57, 49, 41, 37, 28, 16, 3, 61, + 54, 58, 35, 52, 50, 42, 21, 44, + 38, 32, 29, 23, 17, 11, 4, 62, + 46, 55, 26, 59, 40, 36, 15, 53, + 34, 51, 20, 43, 31, 22, 10, 45, + 25, 39, 14, 33, 19, 30, 9, 24, + 13, 18, 8, 12, 7, 6, 5, 63 +}; + +int msb(u64 v) +{ + if (!v) return 0; + + const u64 debruijn64 = 0x03F79D71B4CB0A89UL; + + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + + return index64[(v * debruijn64) >> 58] + 1; +} diff --git a/src/m7.c b/src/m7.c new file mode 100644 index 0000000..d289a6c --- /dev/null +++ b/src/m7.c @@ -0,0 +1,38 @@ +#include <stdint.h> + +typedef uint8_t u8; +typedef uint64_t u64; + +/* Niklas B. + * https://stackoverflow.com/questions/21888140/de-bruijn-algorithm-binary-digit-count-64bits-c-sharp/21888542#21888542 + */ + +const u8 bitPatternToLog2[128] = { + 0, 48, -1, -1, 31, -1, 15, 51, + -1, 63, 5, -1, -1, -1, 19, -1, + 23, 28, -1, -1, -1, 40, 36, 46, + -1, 13, -1, -1, -1, 34, -1, 58, + -1, 60, 2, 43, 55, -1, -1, -1, + 50, 62, 4, -1, 18, 27, -1, 39, + 45, -1, -1, 33, 57, -1, 1, 54, + -1, 49, -1, 17, -1, -1, 32, -1, + 53, -1, 16, -1, -1, 52, -1, -1, + -1, 64, 6, 7, 8, -1, 9, -1, + -1, -1, 20, 10, -1, -1, 24, -1, + 29, -1, -1, 21, -1, 11, -1, -1, + 41, -1, 25, 37, -1, 47, -1, 30, + 14, -1, -1, -1, -1, 22, -1, -1, + 35, 12, -1, -1, -1, 59, 42, -1, + -1, 61, 3, 26, 38, 44, -1, 56 +}; + +int msb(u64 v) +{ + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; + return bitPatternToLog2[(u64)(v * 0x6C04F118E9966F6BUL) >> 57]; +} diff --git a/src/m8.c b/src/m8.c new file mode 100644 index 0000000..b75e08c --- /dev/null +++ b/src/m8.c @@ -0,0 +1,38 @@ +#include <stdint.h> + +typedef uint8_t u8; +typedef uint32_t u32; +typedef uint64_t u64; + +/* de Bruijn magic & table from Jim Mischel */ + +const u8 table[32] = +{ + 0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31 +}; + +int msb(u64 v) +{ + if (!v) return 0; + + u32 v32; + u8 n; + if (v > 0xFFFFFFFF) { + v32 = v >> 32; + n = 33; + } else { + v32 = v; + n = 1; + } + + v32 |= v32 >> 1; + v32 |= v32 >> 2; + v32 |= v32 >> 4; + v32 |= v32 >> 8; + v32 |= v32 >> 16; + + return n + table[(v32 * 0x07C4ACDDU) >> 27]; +} diff --git a/src/m9.c b/src/m9.c new file mode 100644 index 0000000..5cf3824 --- /dev/null +++ b/src/m9.c @@ -0,0 +1,13 @@ +#include <stdint.h> + +typedef uint64_t u64; + +int msb(u64 v) +{ + long n = -1; + + __asm__("bsrq %1,%0" + : "+r" (n) + : "rm" (v)); + return n + 1; +} diff --git a/src/test-alt.c b/src/test-alt.c new file mode 100644 index 0000000..ca0ccb4 --- /dev/null +++ b/src/test-alt.c @@ -0,0 +1,35 @@ +#include <stdint.h> + +typedef uint64_t u64; + +extern int msb(u64 v); + +int total = 0; + +/* By David Howells */ + +#define PAGE_SHIFT 12 +static int +get_msb(u64 v) +{ + int r; + --v; + v >>= PAGE_SHIFT; + r = msb(v); + return r; +} + +int main(void) +{ + long rep, loop; + u64 v; + + for (rep = 1000000; rep > 0; --rep) { + for (loop = 0; loop <= 16384; loop += 4) { + v = 1UL << loop; + total += get_msb(v); + } + } + + return 0; +} diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..aa13dec --- /dev/null +++ b/src/test.c @@ -0,0 +1,19 @@ +#include <stdint.h> + +typedef uint64_t u64; + +extern int msb(u64 v); + +int total = 0; + +int main(void) +{ + for(int i = 4200000; i > 0; --i) { + for(int l = 0; l < 64; ++l) { + u64 n = 1ULL << l; + total += msb(n - 1) + msb(n) + msb(n + 1); + } + } + + return 0; +}