Skip to content

Instantly share code, notes, and snippets.

@dougallj
Last active June 17, 2022 06:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dougallj/f67f55f0b649a1c24e27cc4096e6fad7 to your computer and use it in GitHub Desktop.
Save dougallj/f67f55f0b649a1c24e27cc4096e6fad7 to your computer and use it in GitHub Desktop.
decodeLogicalImmediate, using division instead of a table
#include <stdint.h>
#include <stdbool.h>
#define DECODE_FAILURE 0 // not a valid logical immediate
static inline int nonzeroCountLeadingZeros32(uint32_t n) {
return __builtin_clz(n);
}
static inline uint64_t rotateRight64(uint64_t v, int n) {
return (v >> (n & 63)) | (v << (-n & 63));
}
// Division expression by @zwegner:
// https://twitter.com/zwegner/status/1454543857023062016
uint64_t decodeLogicalImmediate64(int N, int immr, int imms) {
unsigned pattern = (N << 6) | (~imms & 0x3F);
if (!(pattern & (pattern - 1))) return DECODE_FAILURE;
unsigned size = 0x80000000 >> nonzeroCountLeadingZeros32(pattern);
uint64_t mask = ~0ull / ((1ull << (size & 63)) | 1);
unsigned ones = (imms + 1) & (size - 1);
return rotateRight64(mask ^ (mask << ones), immr);
}
uint32_t decodeLogicalImmediate32(int N, int immr, int imms) {
if (N) return DECODE_FAILURE;
return (uint32_t)decodeLogicalImmediate64(N, immr, imms);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment