+ // this is floyd's cycle-finding algorithm.
+ //
+ // consider the sequence s_0 = 0, s_1 = f(0), s_2 = f(f(0)), ...,
+ // s_{i+1} = f(s_i). since B is finite, there must be some smallest
+ // t and c such that s(t) = s(t + c); then we have s_i = s_j iff
+ // i >= t, j >= t, and i == j (mod c).
+ //
+ // the algorithm sets two cursors advancing through the sequence: a
+ // /tortoise/ which advances one step at a time, and a /hare/ which
+ // advances by two, so when the tortoise is at element s_i, the hare
+ // is at s_{2i}. the hare will run around the cycle and catch the
+ // tortoise when i >= t and i == 2 i (mod c); the latter is simply i
+ // == 0 (mod c), which therefore happens first when i = k = t +
+ // (-t mod c).
+ //
+ // i'm not sure what good xlatb does here that mov al, [rbx + al]
+ // doesn't.
+
+ xor eax, eax // tortoise starts at 0
+ xor edx, edx // hare starts at 0
+0: xlatb // advance tortoise
+ xchg rax, rdx // switch to hare
+ xlatb // advance hare ...
+ xlatb // ... twice
+ xchg rax, rdx // switch back
+ cmp al, dl // hare caught the tortoise?
+ jnz 0b // no -- go around again
+
+ // now we trace the initial tail: reset the tortoise to s_0, and slow
+ // the hare down so that both take only a single step in each
+ // iteration. this loop terminates when i >= t and i == i + 2 k
+ // (mod c). we know k is a multiple of c, so the latter condition
+ // always holds, so this finds the first step of the cycle.
+
+ xor eax, eax // reset the tortoise
+0: xlatb // advance tortoise
+ xchg rax, rdx // switch to hare
+ xlatb // advance hare
+ xchg rax, rdx // and switch back
+ cmp al, dl // done?
+ jnz 0b // no -- iterate
+
+#elif defined(__i386__)
+
+ xor eax, eax // tortoise starts at 0
+ xor edx, edx // hare starts at 0
+0: xlatb // advance tortoise
+ xchg eax, edx // switch to hare
+ xlatb // advance hare ...
+ xlatb // ... twice
+ xchg eax, edx // switch back
+ cmp al, dl // hare caught the tortoise?
+ jnz 0b // no -- go around again
+
+ xor eax, eax // reset the tortoise
+0: xlatb // advance tortoise
+ xchg eax, edx // switch to hare
+ xlatb // advance hare
+ xchg eax, edx // and switch back
+ cmp al, dl // done?
+ jnz 0b // no -- iterate