diff options
| author | Ron Yorston <rmy@pobox.com> | 2024-06-23 09:35:35 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2024-06-23 09:44:03 +0100 |
| commit | b07c177b446498ccd739b367f9e80337c3dfa55a (patch) | |
| tree | 8230bce5f937e46ae1a6f18677904d2eccc4ae9e /libbb | |
| parent | 1b094d366f808a2ebc4824004f0d6f75f13c09cb (diff) | |
| parent | a6ce017a8a2db09c6f23aa6abf7ce21fd00c2fdf (diff) | |
| download | busybox-w32-b07c177b446498ccd739b367f9e80337c3dfa55a.tar.gz busybox-w32-b07c177b446498ccd739b367f9e80337c3dfa55a.tar.bz2 busybox-w32-b07c177b446498ccd739b367f9e80337c3dfa55a.zip | |
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/Kbuild.src | 2 | ||||
| -rw-r--r-- | libbb/alloc_affinity.c | 29 | ||||
| -rw-r--r-- | libbb/lineedit.c | 62 | ||||
| -rw-r--r-- | libbb/popcnt.c | 46 |
4 files changed, 111 insertions, 28 deletions
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 7785ef152..32fde90e6 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src | |||
| @@ -58,6 +58,7 @@ lib-y += parse_mode.o | |||
| 58 | lib-y += perror_msg.o | 58 | lib-y += perror_msg.o |
| 59 | lib-y += perror_nomsg_and_die.o | 59 | lib-y += perror_nomsg_and_die.o |
| 60 | lib-y += platform.o | 60 | lib-y += platform.o |
| 61 | lib-y += popcnt.o | ||
| 61 | lib-y += printable.o | 62 | lib-y += printable.o |
| 62 | lib-y += printable_string.o | 63 | lib-y += printable_string.o |
| 63 | lib-y += process_escape_sequence.o | 64 | lib-y += process_escape_sequence.o |
| @@ -99,6 +100,7 @@ lib-y += xgetcwd.o | |||
| 99 | lib-y += xreadlink.o | 100 | lib-y += xreadlink.o |
| 100 | lib-y += xrealloc_vector.o | 101 | lib-y += xrealloc_vector.o |
| 101 | 102 | ||
| 103 | lib-$(CONFIG_PLATFORM_POSIX) += alloc_affinity.o | ||
| 102 | lib-$(CONFIG_PLATFORM_POSIX) += bb_askpass.o | 104 | lib-$(CONFIG_PLATFORM_POSIX) += bb_askpass.o |
| 103 | lib-$(CONFIG_PLATFORM_POSIX) += change_identity.o | 105 | lib-$(CONFIG_PLATFORM_POSIX) += change_identity.o |
| 104 | lib-$(CONFIG_PLATFORM_POSIX) += device_open.o | 106 | lib-$(CONFIG_PLATFORM_POSIX) += device_open.o |
diff --git a/libbb/alloc_affinity.c b/libbb/alloc_affinity.c new file mode 100644 index 000000000..b6d9f649a --- /dev/null +++ b/libbb/alloc_affinity.c | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * Utility routines. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2024 Denys Vlasenko | ||
| 6 | * | ||
| 7 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
| 8 | */ | ||
| 9 | #include <sched.h> | ||
| 10 | #include "libbb.h" | ||
| 11 | |||
| 12 | unsigned long* FAST_FUNC get_malloc_cpu_affinity(int pid, unsigned *sz) | ||
| 13 | { | ||
| 14 | unsigned long *mask = NULL; | ||
| 15 | unsigned sz_in_bytes = *sz; | ||
| 16 | |||
| 17 | for (;;) { | ||
| 18 | mask = xrealloc(mask, sz_in_bytes); | ||
| 19 | if (sched_getaffinity(pid, sz_in_bytes, (void*)mask) == 0) | ||
| 20 | break; /* got it */ | ||
| 21 | sz_in_bytes *= 2; | ||
| 22 | if (errno == EINVAL && (int)sz_in_bytes > 0) | ||
| 23 | continue; | ||
| 24 | bb_perror_msg_and_die("can't %cet pid %d's affinity", 'g', pid); | ||
| 25 | } | ||
| 26 | //bb_error_msg("get mask[0]:%lx sz_in_bytes:%d", mask[0], sz_in_bytes); | ||
| 27 | *sz = sz_in_bytes; | ||
| 28 | return mask; | ||
| 29 | } | ||
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 811e3e475..bd4a17348 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
| @@ -351,7 +351,7 @@ static unsigned save_string(char *dst, unsigned maxsize) | |||
| 351 | return i; | 351 | return i; |
| 352 | } | 352 | } |
| 353 | } | 353 | } |
| 354 | /* I thought just fputwc(c, stdout) would work. But no... */ | 354 | /* I thought just fputwc(c, stderr) would work. But no... */ |
| 355 | static void BB_PUTCHAR(wchar_t c) | 355 | static void BB_PUTCHAR(wchar_t c) |
| 356 | { | 356 | { |
| 357 | if (unicode_status == UNICODE_ON) { | 357 | if (unicode_status == UNICODE_ON) { |
| @@ -360,11 +360,11 @@ static void BB_PUTCHAR(wchar_t c) | |||
| 360 | ssize_t len = wcrtomb(buf, c, &mbst); | 360 | ssize_t len = wcrtomb(buf, c, &mbst); |
| 361 | if (len > 0) { | 361 | if (len > 0) { |
| 362 | buf[len] = '\0'; | 362 | buf[len] = '\0'; |
| 363 | fputs_stdout(buf); | 363 | fputs(buf, stderr); |
| 364 | } | 364 | } |
| 365 | } else { | 365 | } else { |
| 366 | /* In this case, c is always one byte */ | 366 | /* In this case, c is always one byte */ |
| 367 | putchar(c); | 367 | bb_putchar_stderr(c); |
| 368 | } | 368 | } |
| 369 | } | 369 | } |
| 370 | # if ENABLE_UNICODE_COMBINING_WCHARS || ENABLE_UNICODE_WIDE_WCHARS | 370 | # if ENABLE_UNICODE_COMBINING_WCHARS || ENABLE_UNICODE_WIDE_WCHARS |
| @@ -410,7 +410,7 @@ static void save_string(char *dst, unsigned maxsize) | |||
| 410 | safe_strncpy(dst, command_ps, maxsize); | 410 | safe_strncpy(dst, command_ps, maxsize); |
| 411 | } | 411 | } |
| 412 | # endif | 412 | # endif |
| 413 | # define BB_PUTCHAR(c) bb_putchar(c) | 413 | # define BB_PUTCHAR(c) bb_putchar_stderr(c) |
| 414 | /* Should never be called: */ | 414 | /* Should never be called: */ |
| 415 | int adjust_width_and_validate_wc(unsigned *width_adj, int wc); | 415 | int adjust_width_and_validate_wc(unsigned *width_adj, int wc); |
| 416 | #endif | 416 | #endif |
| @@ -469,7 +469,7 @@ static void put_cur_glyph_and_inc_cursor(void) | |||
| 469 | if (c == BB_NUL) | 469 | if (c == BB_NUL) |
| 470 | c = ' '; | 470 | c = ' '; |
| 471 | BB_PUTCHAR(c); | 471 | BB_PUTCHAR(c); |
| 472 | bb_putchar('\b'); | 472 | bb_putchar_stderr('\b'); |
| 473 | #endif | 473 | #endif |
| 474 | cmdedit_y++; | 474 | cmdedit_y++; |
| 475 | if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right == 0) { | 475 | if (!ENABLE_UNICODE_WIDE_WCHARS || ofs_to_right == 0) { |
| @@ -531,12 +531,12 @@ static void goto_new_line(void) | |||
| 531 | put_till_end_and_adv_cursor(); | 531 | put_till_end_and_adv_cursor(); |
| 532 | /* "cursor == 0" is only if prompt is "" and user input is empty */ | 532 | /* "cursor == 0" is only if prompt is "" and user input is empty */ |
| 533 | if (cursor == 0 || cmdedit_x != 0) | 533 | if (cursor == 0 || cmdedit_x != 0) |
| 534 | bb_putchar('\n'); | 534 | bb_putchar_stderr('\n'); |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | static void beep(void) | 537 | static void beep(void) |
| 538 | { | 538 | { |
| 539 | bb_putchar('\007'); | 539 | bb_putchar_stderr('\007'); |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | /* Full or last/sole prompt line, reset edit cursor, calculate terminal cursor. | 542 | /* Full or last/sole prompt line, reset edit cursor, calculate terminal cursor. |
| @@ -544,7 +544,10 @@ static void beep(void) | |||
| 544 | */ | 544 | */ |
| 545 | static void put_prompt_custom(bool is_full) | 545 | static void put_prompt_custom(bool is_full) |
| 546 | { | 546 | { |
| 547 | fputs_stdout((is_full ? cmdedit_prompt : prompt_last_line)); | 547 | /* https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html |
| 548 | * says that shells must write $PSn to stderr, not stdout. | ||
| 549 | */ | ||
| 550 | fputs((is_full ? cmdedit_prompt : prompt_last_line), stderr); | ||
| 548 | cursor = 0; | 551 | cursor = 0; |
| 549 | cmdedit_y = cmdedit_prmt_len / cmdedit_termw; /* new quasireal y */ | 552 | cmdedit_y = cmdedit_prmt_len / cmdedit_termw; /* new quasireal y */ |
| 550 | cmdedit_x = cmdedit_prmt_len % cmdedit_termw; | 553 | cmdedit_x = cmdedit_prmt_len % cmdedit_termw; |
| @@ -582,16 +585,16 @@ static void input_backward(unsigned num) | |||
| 582 | /* This is longer by 5 bytes on x86. | 585 | /* This is longer by 5 bytes on x86. |
| 583 | * Also gets miscompiled for ARM users | 586 | * Also gets miscompiled for ARM users |
| 584 | * (busybox.net/bugs/view.php?id=2274). | 587 | * (busybox.net/bugs/view.php?id=2274). |
| 585 | * printf(("\b\b\b\b" + 4) - num); | 588 | * fprintf(("\b\b\b\b" + 4) - num, stderr); |
| 586 | * return; | 589 | * return; |
| 587 | */ | 590 | */ |
| 588 | do { | 591 | do { |
| 589 | bb_putchar('\b'); | 592 | bb_putchar_stderr('\b'); |
| 590 | } while (--num); | 593 | } while (--num); |
| 591 | return; | 594 | return; |
| 592 | } | 595 | } |
| 593 | #endif | 596 | #endif |
| 594 | printf(ESC"[%uD", num); | 597 | fprintf(stderr, ESC"[%uD", num); |
| 595 | return; | 598 | return; |
| 596 | } | 599 | } |
| 597 | 600 | ||
| @@ -616,7 +619,7 @@ static void input_backward(unsigned num) | |||
| 616 | */ | 619 | */ |
| 617 | unsigned sv_cursor; | 620 | unsigned sv_cursor; |
| 618 | /* go to 1st column; go up to first line */ | 621 | /* go to 1st column; go up to first line */ |
| 619 | printf("\r" ESC"[%uA", cmdedit_y); | 622 | fprintf(stderr, "\r" ESC"[%uA", cmdedit_y); |
| 620 | cmdedit_y = 0; | 623 | cmdedit_y = 0; |
| 621 | sv_cursor = cursor; | 624 | sv_cursor = cursor; |
| 622 | put_prompt_last_line(); /* sets cursor to 0 */ | 625 | put_prompt_last_line(); /* sets cursor to 0 */ |
| @@ -631,12 +634,12 @@ static void input_backward(unsigned num) | |||
| 631 | cmdedit_x = (cmdedit_termw * cmdedit_y - num) % cmdedit_termw; | 634 | cmdedit_x = (cmdedit_termw * cmdedit_y - num) % cmdedit_termw; |
| 632 | cmdedit_y -= lines_up; | 635 | cmdedit_y -= lines_up; |
| 633 | /* go to 1st column; go up */ | 636 | /* go to 1st column; go up */ |
| 634 | printf("\r" ESC"[%uA", lines_up); | 637 | fprintf(stderr, "\r" ESC"[%uA", lines_up); |
| 635 | /* go to correct column. | 638 | /* go to correct column. |
| 636 | * xterm, konsole, Linux VT interpret 0 as 1 below! wow. | 639 | * xterm, konsole, Linux VT interpret 0 as 1 below! wow. |
| 637 | * need to *make sure* we skip it if cmdedit_x == 0 */ | 640 | * need to *make sure* we skip it if cmdedit_x == 0 */ |
| 638 | if (cmdedit_x) | 641 | if (cmdedit_x) |
| 639 | printf(ESC"[%uC", cmdedit_x); | 642 | fprintf(stderr, ESC"[%uC", cmdedit_x); |
| 640 | } | 643 | } |
| 641 | } | 644 | } |
| 642 | 645 | ||
| @@ -644,11 +647,11 @@ static void input_backward(unsigned num) | |||
| 644 | static void draw_custom(int y, int back_cursor, bool is_full) | 647 | static void draw_custom(int y, int back_cursor, bool is_full) |
| 645 | { | 648 | { |
| 646 | if (y > 0) /* up y lines */ | 649 | if (y > 0) /* up y lines */ |
| 647 | printf(ESC"[%uA", y); | 650 | fprintf(stderr, ESC"[%uA", y); |
| 648 | bb_putchar('\r'); | 651 | bb_putchar_stderr('\r'); |
| 649 | put_prompt_custom(is_full); | 652 | put_prompt_custom(is_full); |
| 650 | put_till_end_and_adv_cursor(); | 653 | put_till_end_and_adv_cursor(); |
| 651 | printf(SEQ_CLEAR_TILL_END_OF_SCREEN); | 654 | fputs(SEQ_CLEAR_TILL_END_OF_SCREEN, stderr); |
| 652 | input_backward(back_cursor); | 655 | input_backward(back_cursor); |
| 653 | } | 656 | } |
| 654 | 657 | ||
| @@ -693,7 +696,7 @@ static void input_delete(int save) | |||
| 693 | command_len--; | 696 | command_len--; |
| 694 | put_till_end_and_adv_cursor(); | 697 | put_till_end_and_adv_cursor(); |
| 695 | /* Last char is still visible, erase it (and more) */ | 698 | /* Last char is still visible, erase it (and more) */ |
| 696 | printf(SEQ_CLEAR_TILL_END_OF_SCREEN); | 699 | fputs(SEQ_CLEAR_TILL_END_OF_SCREEN, stderr); |
| 697 | input_backward(cursor - j); /* back to old pos cursor */ | 700 | input_backward(cursor - j); /* back to old pos cursor */ |
| 698 | } | 701 | } |
| 699 | 702 | ||
| @@ -1110,8 +1113,8 @@ static void remove_chunk(int16_t *int_buf, int beg, int end) | |||
| 1110 | if (dbg_bmp) { | 1113 | if (dbg_bmp) { |
| 1111 | int i; | 1114 | int i; |
| 1112 | for (i = 0; int_buf[i]; i++) | 1115 | for (i = 0; int_buf[i]; i++) |
| 1113 | bb_putchar((unsigned char)int_buf[i]); | 1116 | bb_putchar_stderr((unsigned char)int_buf[i]); |
| 1114 | bb_putchar('\n'); | 1117 | bb_putchar_stderr('\n'); |
| 1115 | } | 1118 | } |
| 1116 | } | 1119 | } |
| 1117 | /* Caller ensures that match_buf points to a malloced buffer | 1120 | /* Caller ensures that match_buf points to a malloced buffer |
| @@ -1294,7 +1297,7 @@ static void showfiles(void) | |||
| 1294 | int nc; | 1297 | int nc; |
| 1295 | 1298 | ||
| 1296 | for (nc = 1; nc < ncols && n+nrows < nfiles; n += nrows, nc++) { | 1299 | for (nc = 1; nc < ncols && n+nrows < nfiles; n += nrows, nc++) { |
| 1297 | printf("%s%-*s", matches[n], | 1300 | fprintf(stderr, "%s%-*s", matches[n], |
| 1298 | (int)(column_width - unicode_strwidth(matches[n])), "" | 1301 | (int)(column_width - unicode_strwidth(matches[n])), "" |
| 1299 | ); | 1302 | ); |
| 1300 | } | 1303 | } |
| @@ -1650,7 +1653,7 @@ void FAST_FUNC show_history(const line_input_t *st) | |||
| 1650 | if (!st) | 1653 | if (!st) |
| 1651 | return; | 1654 | return; |
| 1652 | for (i = 0; i < st->cnt_history; i++) | 1655 | for (i = 0; i < st->cnt_history; i++) |
| 1653 | printf("%4d %s\n", i, st->history[i]); | 1656 | fprintf(stderr, "%4d %s\n", i, st->history[i]); |
| 1654 | } | 1657 | } |
| 1655 | 1658 | ||
| 1656 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY | 1659 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY |
| @@ -2090,7 +2093,7 @@ static void ask_terminal(void) | |||
| 2090 | pfd.events = POLLIN; | 2093 | pfd.events = POLLIN; |
| 2091 | if (safe_poll(&pfd, 1, 0) == 0) { | 2094 | if (safe_poll(&pfd, 1, 0) == 0) { |
| 2092 | S.sent_ESC_br6n = 1; | 2095 | S.sent_ESC_br6n = 1; |
| 2093 | fputs_stdout(ESC"[6n"); | 2096 | fputs(ESC"[6n", stderr); |
| 2094 | fflush_all(); /* make terminal see it ASAP! */ | 2097 | fflush_all(); /* make terminal see it ASAP! */ |
| 2095 | } | 2098 | } |
| 2096 | } | 2099 | } |
| @@ -2857,13 +2860,13 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
| 2857 | /* Control-k -- clear to end of line */ | 2860 | /* Control-k -- clear to end of line */ |
| 2858 | command_ps[cursor] = BB_NUL; | 2861 | command_ps[cursor] = BB_NUL; |
| 2859 | command_len = cursor; | 2862 | command_len = cursor; |
| 2860 | printf(SEQ_CLEAR_TILL_END_OF_SCREEN); | 2863 | fputs(SEQ_CLEAR_TILL_END_OF_SCREEN, stderr); |
| 2861 | break; | 2864 | break; |
| 2862 | case CTRL('L'): | 2865 | case CTRL('L'): |
| 2863 | vi_case(CTRL('L')|VI_CMDMODE_BIT:) | 2866 | vi_case(CTRL('L')|VI_CMDMODE_BIT:) |
| 2864 | /* Control-l -- clear screen */ | 2867 | /* Control-l -- clear screen */ |
| 2865 | /* cursor to top,left; clear to the end of screen */ | 2868 | /* cursor to top,left; clear to the end of screen */ |
| 2866 | printf(ESC"[H" ESC"[J"); | 2869 | fputs(ESC"[H" ESC"[J", stderr); |
| 2867 | draw_full(command_len - cursor); | 2870 | draw_full(command_len - cursor); |
| 2868 | break; | 2871 | break; |
| 2869 | #if MAX_HISTORY > 0 | 2872 | #if MAX_HISTORY > 0 |
| @@ -3050,8 +3053,8 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
| 3050 | beep(); | 3053 | beep(); |
| 3051 | } else { | 3054 | } else { |
| 3052 | command_ps[cursor] = ic; | 3055 | command_ps[cursor] = ic; |
| 3053 | bb_putchar(ic); | 3056 | bb_putchar_stderr(ic); |
| 3054 | bb_putchar('\b'); | 3057 | bb_putchar_stderr('\b'); |
| 3055 | } | 3058 | } |
| 3056 | break; | 3059 | break; |
| 3057 | case '\x1b': /* ESC */ | 3060 | case '\x1b': /* ESC */ |
| @@ -3249,7 +3252,10 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
| 3249 | #undef read_line_input | 3252 | #undef read_line_input |
| 3250 | int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize) | 3253 | int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize) |
| 3251 | { | 3254 | { |
| 3252 | fputs_stdout(prompt); | 3255 | /* https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html |
| 3256 | * says that shells must write $PSn to stderr, not stdout. | ||
| 3257 | */ | ||
| 3258 | fputs(prompt, stderr); | ||
| 3253 | fflush_all(); | 3259 | fflush_all(); |
| 3254 | if (!fgets(command, maxsize, stdin)) | 3260 | if (!fgets(command, maxsize, stdin)) |
| 3255 | return -1; | 3261 | return -1; |
diff --git a/libbb/popcnt.c b/libbb/popcnt.c new file mode 100644 index 000000000..fe8cd240f --- /dev/null +++ b/libbb/popcnt.c | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * Utility routines. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2024 Denys Vlasenko | ||
| 6 | * | ||
| 7 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
| 8 | */ | ||
| 9 | #include "libbb.h" | ||
| 10 | |||
| 11 | unsigned FAST_FUNC bb_popcnt_32(uint32_t m) | ||
| 12 | { | ||
| 13 | /* replace each 2 bit group with the count of set bits in it */ | ||
| 14 | /* 00->00 01->01 10->01 11->10 */ | ||
| 15 | m = m - ((m >> 1) & 0x55555555); | ||
| 16 | /* in each 4 bit group, add two 2-bit counts */ | ||
| 17 | m = (m & 0x33333333) + ((m >> 2) & 0x33333333); | ||
| 18 | /* in each 8 bit group, add two 4-bit counts (in fact, 3-bit, 0nnn with n=0..4) */ | ||
| 19 | m = (m + (m >> 4)) & 0x0f0f0f0f; | ||
| 20 | #if 1 /* assume 32*32->32 multiply is fast */ | ||
| 21 | m = m * 0x01010101; /* top byte = m + (m<<8) + (m<<16) + (m<<24) */ | ||
| 22 | return m >> 24; | ||
| 23 | #else | ||
| 24 | /* 0000aaaa0000bbbb0000cccc0000dddd */ | ||
| 25 | /* + 0000aaaa0000bbbb0000cccc */ | ||
| 26 | /* = 0000xxxx000_a+b_000xxxxx000_c+d_ (we don't care about x bits) */ | ||
| 27 | m += m >> 8; /* in each 16-bit group, lowest 5 bits is the count */ | ||
| 28 | /* 0000xxxx000_a+b_000xxxxx000_c+d_ */ | ||
| 29 | /* + 0000xxxx000_a+b_ */ | ||
| 30 | /* = 0000xxxx000xxxxx00xxxxxx00a+b+cd */ | ||
| 31 | m += m >> 16; /* in each 32-bit group, lowest 6 bits is the count */ | ||
| 32 | return m & 0x3f; /* clear x bits */ | ||
| 33 | #endif | ||
| 34 | } | ||
| 35 | |||
| 36 | #if ULONG_MAX > 0xffffffff | ||
| 37 | unsigned FAST_FUNC bb_popcnt_long(unsigned long m) | ||
| 38 | { | ||
| 39 | BUILD_BUG_ON(sizeof(m) != 8); | ||
| 40 | /* 64-bit version of bb_popcnt_32 exists, but it uses 64-bit constants, | ||
| 41 | * which are awkward to generate on assembly level on most CPUs. | ||
| 42 | * For now, just add two 32-bit counts: | ||
| 43 | */ | ||
| 44 | return bb_popcnt_32((uint32_t)m) + bb_popcnt_32((uint32_t)(m >> 32)); | ||
| 45 | } | ||
| 46 | #endif | ||
