Created
June 1, 2026 20:44
-
-
Save mancap314/9874e040f171100477cc280c816085df to your computer and use it in GitHub Desktop.
rotator in C
This file contains hidden or 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
| /* 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