+
+/**
+ * urshift - 128-bit Unsigned Right Shift.
+ * @plow: in/out - lower 64-bit integer.
+ * @phigh: in/out - higher 64-bit integer.
+ * @shift: in - bytes to shift, between 0 and 127.
+ *
+ * Result is zero-extended and stored in plow/phigh, which are
+ * input/output variables. Shift values outside the range will
+ * be mod to 128. In other words, the caller is responsible to
+ * verify/assert both the shift range and plow/phigh pointers.
+ */
+void urshift(uint64_t *plow, uint64_t *phigh, int32_t shift)
+{
+ shift &= 127;
+ if (shift == 0) {
+ return;
+ }
+
+ uint64_t h = *phigh >> (shift & 63);
+ if (shift >= 64) {
+ *plow = h;
+ *phigh = 0;
+ } else {
+ *plow = (*plow >> (shift & 63)) | (*phigh << (64 - (shift & 63)));
+ *phigh = h;
+ }