Created
June 12, 2019 10:04
-
-
Save kaworu/f832e373814c5805a18643245fd96c27 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <stdio.h> | |
/* Unsigned comparisons */ | |
/* Return 1 if condition is true, 0 otherwise */ | |
int ct_isnonzero_u32(uint32_t x) | |
{ | |
return (x|-x)>>31; | |
} | |
/* Generate a mask: 0xFFFFFFFF if bit != 0, 0 otherwise */ | |
uint32_t ct_mask_u32(uint32_t bit) | |
{ | |
return -(uint32_t)ct_isnonzero_u32(bit); | |
} | |
/* Conditionally return x or y depending on whether bit is set */ | |
/* Equivalent to: return bit ? x : y */ | |
uint32_t ct_select_u32(uint32_t x, uint32_t y, uint32_t bit) | |
{ | |
uint32_t m = ct_mask_u32(bit); | |
return (x&m) | (y&~m); | |
/* return ((x^y)&m)^y; */ | |
} | |
unsigned select (unsigned a, unsigned b, unsigned bit) | |
{ | |
/* -0 = 0, -1 = 0xff....ff */ | |
unsigned mask = - bit; | |
unsigned ret = mask & (a^b); | |
ret = ret ^ a; | |
return ret; | |
} | |
/* Conditionally return a or b depending on whether bit is set */ | |
/* Equivalent to: return bit ? a : b */ | |
unsigned proposed (unsigned a, unsigned b, unsigned bit) | |
{ | |
unsigned isnonzero = (bit | -bit) >> (sizeof(unsigned) * 8 - 1); | |
/* -0 = 0, -1 = 0xff....ff */ | |
unsigned mask = -isnonzero; | |
unsigned ret = mask & (b^a); | |
ret = ret ^ b; | |
return ret; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
for (unsigned i = 0; i <= 2; i++) { | |
printf("---\n"); | |
printf("select ('a', 'b', %u)=%c\n", i, select('a', 'b', i)); | |
printf("proposed ('a', 'b', %u)=%c\n", i, proposed('a', 'b', i)); | |
printf("ct_select_u32('a', 'b', %u)=%c\n", i, ct_select_u32('a', 'b', i)); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment