1. The most general algorithm:
- mask bit
[10111010] => [00010000]
- clone word
a=[00010000], b=[00010000] - shift bit in first word to MSB, and to LSB in second word
a=[10000000], b=[00000001] - subtract c = a - b
c=[01111111] - add missing MSB c = c OR a
c=[11111111]
- shift bit to MSB
a=[10000000] - arithmetic shift right
a=[11111111]
#include <stdlib.h> #include <stdio.h> #include <stdint.h> uint32_t fill1(uint32_t a, int bit) { uint32_t b; b = a = a & (1 << bit); a <<= 31 - bit; b >>= bit; return (a - b) | a; } uint32_t fill2(uint32_t a, int bit) { a <<= 31 - bit; return (int32_t)(a) >> 31; } uint32_t fill386(uint32_t a, int bit) { uint32_t result; __asm__ __volatile__ ( "bt %1, %0\n" "sbb %0, %0\n" : "=r" (result) : "r" (bit), "0" (a) ); return result; } int main(int argc, char* argv[]) { uint32_t x, i; if (argc > 1) x = (unsigned long)strtol(argv[1], NULL, 0); printf("input = %08x\n", x); for (i=0; i < 32; i++) printf("bit %2d: fill1 = %08x, fill2 = %08x, fill386 = %08x\n", i, fill1(x, i), fill2(x, i), fill386(x, i) ); return EXIT_SUCCESS; }
Brak komentarzy:
Prześlij komentarz