Ideally I'd like to do it without looping. In the code below I certainly loop.
However, is there an assembly instruction that could do this faster? Since arithmetic shifts are done in a barrel shifter (I think), in one cycle, I thought - maybe.
// # sign bit is BIT31, not interesting // #1111111 11111111 11111111 11111111 // 0 returned // #0000000 11111111 11111111 11111111 // 1234567 7 returned // #0000000 00000000 00000000 00000000 // 1234567 89012345 67890123 45678901 31 returned unsigned Get_Num_High_ZeroBits (const signed unsigned_31bits) { // Only [BIT30..BIT0] are valid unsigned ibit; xassert (unsigned_31bits >= 0); if (unsigned_31bits == 0) { // separate test to avoid looping forever below ibit = 0; // To return 31 as max } else { ibit = 30; // To return 0 as min after the final inc while ((unsigned_31bits bitand (1<<ibit)) == 0) { // 1 << 30 sets BIT30 ibit--; } ibit++; // final inc to avoid doing an (ibit-1) inside the loop } return (31-ibit); } void Test_Get_Num_High_ZeroBits (void) { /* Test passed: zb 0 zb 7 zb 31 */ signed val; val = 0x7FFFFFFF; // Sign bit only is zero, so it's still positive debug_print_special ("zb %u\n", Get_Num_High_ZeroBits (val)); // 0 val = 0x00FFFFFF; debug_print_special ("zb %u\n", Get_Num_High_ZeroBits (val)); // 7 val = 0x00000000; debug_print_special ("zb %u\n", Get_Num_High_ZeroBits (val)); // 31 }