Skip to content

Instantly share code, notes, and snippets.

@iamgreaser
Created February 20, 2020 05:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iamgreaser/4315ebca8b9d665231d119cff8ddd950 to your computer and use it in GitHub Desktop.
Save iamgreaser/4315ebca8b9d665231d119cff8ddd950 to your computer and use it in GitHub Desktop.
ceil(log2(x)) implementation for HiFive1 RevB
int log2_ceil(uint32_t v)
{
if ( v == 0 ) {
return -1;
} else if ( v == 1 ) {
return 0;
} else if (((int32_t)(v-1)) < 0) {
return 32;
} else {
for ( ;; ) {
uint32_t mcycle_beg, mcycle_end;
uint32_t v_result;
uint32_t v_mid;
uint32_t mcycle_delta;
asm volatile (
"divu %[v_mid], %[vnum], %[vden]\n"
"csrr %[mcycle_beg], mcycle\n"
"mv %[v_result], %[v_mid]\n"
"csrr %[mcycle_end], mcycle\n"
: [mcycle_beg] "=&r"(mcycle_beg)
, [mcycle_end] "=&r"(mcycle_end)
, [v_result] "=&r"(v_result)
, [v_mid] "=&r"(v_mid)
: [vnum] "r"(v-1)
, [vden] "r"(1)
:
);
(void)v_mid;
(void)v_result;
mcycle_delta = mcycle_end - mcycle_beg;
// If the cycle count jumped up, we probably hit an interrupt
if ( mcycle_delta < 42 ) {
return (mcycle_delta+1)-5;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment