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