Skip to content

Instantly share code, notes, and snippets.

@mancap314
Created June 1, 2026 20:44
Show Gist options
  • Select an option

  • Save mancap314/9874e040f171100477cc280c816085df to your computer and use it in GitHub Desktop.

Select an option

Save mancap314/9874e040f171100477cc280c816085df to your computer and use it in GitHub Desktop.
rotator in C
/* rewrite in C and assess performance of python script:
* https://raw.githubusercontent.com/azeria-labs/rotator/master/rotator.py to
* find out if a given integer is a valid arm register immediate value (see:
* https://azeria-labs.com/memory-instructions-load-and-store-part-4/) */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <time.h>
#endif
#define MAX_BITS (32)
#define ROR(v, r, m) \
((v & ((1ULL << m) - 1)) >> (r % m)) | \
((v << (m - (r % m))) & ((1ULL << m) - 1))
/* High resolution clock */
uint64_t highres_clock_ns(void) {
#ifdef _WIN32
static LARGE_INTEGER freq = {0};
LARGE_INTEGER counter;
if (freq.QuadPart == 0) {
QueryPerformanceFrequency(&freq);
}
QueryPerformanceCounter(&counter);
/* Convert ticks to nanoseconds */
return (uint64_t)((double)counter.QuadPart * 1e9 / freq.QuadPart);
#else
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t)ts.tv_sec * 1000000000ULL + (uint64_t)ts.tv_nsec;
#endif
}
/* return -1 if input is not a valid arm immediate number, otherwise the value
* of its rotation field */
uint64_t is_valid_immediate_number(uint64_t input) {
for (uint64_t n = 1; n < 256; n++) {
for (uint64_t i = 0; i < 31; i += 2) {
uint64_t rotated = ROR(n, i, MAX_BITS);
if (rotated == input)
return i;
}
}
return -1;
}
/* test all the integers 1..n_to_test, store the value of their rotation field
* in i_arr.
* Return the average time (in nanoseconds) to compute if an integer is a valid
* arm immediate value */
float assess_time(uint64_t n_to_test, uint64_t i_arr[n_to_test - 1]) {
uint64_t total_time = 0;
uint64_t start, end;
uint64_t i;
for (uint64_t n = 1; n < n_to_test; n++) {
start = highres_clock_ns();
i = is_valid_immediate_number(n);
end = highres_clock_ns();
total_time += end - start;
i_arr[n - 1] = i;
}
float avg_time = (float)total_time / (float)(n_to_test - 1);
return avg_time;
}
int main(void) {
uint64_t n_to_test = 1000;
uint64_t *i_arr = malloc((n_to_test - 1) * sizeof(uint64_t));
if (NULL == i_arr) {
fputs("[ERROR] Could not malloc i_arr", stderr);
return EXIT_FAILURE;
}
float avg_time = assess_time(n_to_test, i_arr);
fprintf(stdout, "[INFO] Integers until %li tested in %f ns average time\n",
n_to_test, avg_time);
for (uint64_t i = 0; i < n_to_test - 1; i++)
fprintf(stdout, "%c%li%c", i == 0 ? '[' : ' ', i_arr[i],
i == n_to_test - 2 ? ']' : ',');
fputc('\n', stdout);
free(i_arr);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment