void revbin_permute(double _Complex *f, unsigned long n) {
  if (n <= 64) {
    revbin_permute_leq_64(f, n);
    return;
  }
  const unsigned long ldn = ld(n);
  const unsigned long nh = (n >> 1);
  const unsigned long n1 = n - 1;
  const unsigned long nx1 = nh - 2;
  const unsigned long nx2 = n1 - nx1;
  unsigned long k = 0, r = 0;
  while (k < (n / 4)) {
    if (r > k) {
      idx_swap(f, k, r);
      idx_swap(f, n1 ^ k, n1 ^ r);
      idx_swap(f, nx1 ^ k, nx1 ^ r);
      idx_swap(f, nx2 ^ k, nx2 ^ r);
    }
    ++k;
    r ^= nh;
    if (r > k) {
      idx_swap(f, k, r);
      idx_swap(f, n1 ^ k, n1 ^ r);
    }
    ++k;
    r = revbin(k, ldn);
    if (r > k) {
      idx_swap(f, k, r);
      idx_swap(f, n1 ^ k, n1 ^ r);
    }
    ++k;
    r ^= nh;
    if (r > k) {
      idx_swap(f, k, r);
      idx_swap(f, nx1 ^ k, nx1 ^ r);
    }
    ++k;
    r = revbin(k, ldn);
  }
}


x86 assembly (clang, -O0):
<revbin_permute>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
cmpq   $0x40,-0x10(%rbp)
ja     116f <revbin_permute+0x2f>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    $0x0,%al
call   1050 <revbin_permute_leq_64@plt>
jmp    1372 <revbin_permute+0x232>
mov    -0x10(%rbp),%rdi
mov    $0x0,%al
call   1060 <ld@plt>
cltq
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
shr    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
sub    $0x1,%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
sub    $0x2,%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
sub    -0x30(%rbp),%rax
mov    %rax,-0x38(%rbp)
movq   $0x0,-0x40(%rbp)
movq   $0x0,-0x48(%rbp)
mov    -0x40(%rbp),%rax
mov    -0x10(%rbp),%rcx
shr    $0x2,%rcx
cmp    %rcx,%rax
jae    1372 <revbin_permute+0x232>
mov    -0x48(%rbp),%rax
cmp    -0x40(%rbp),%rax
jbe    1247 <revbin_permute+0x107>
mov    -0x8(%rbp),%rdi
mov    -0x40(%rbp),%rsi
mov    -0x48(%rbp),%rdx
mov    $0x0,%al
call   1030 <idx_swap@plt>
mov    -0x8(%rbp),%rdi
mov    -0x28(%rbp),%rsi
xor    -0x40(%rbp),%rsi
mov    -0x28(%rbp),%rdx
xor    -0x48(%rbp),%rdx
mov    $0x0,%al
call   1030 <idx_swap@plt>
mov    -0x8(%rbp),%rdi
mov    -0x30(%rbp),%rsi
xor    -0x40(%rbp),%rsi
mov    -0x30(%rbp),%rdx
xor    -0x48(%rbp),%rdx
mov    $0x0,%al
call   1030 <idx_swap@plt>
mov    -0x8(%rbp),%rdi
mov    -0x38(%rbp),%rsi
xor    -0x40(%rbp),%rsi
mov    -0x38(%rbp),%rdx
xor    -0x48(%rbp),%rdx
mov    $0x0,%al
call   1030 <idx_swap@plt>
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
mov    -0x20(%rbp),%rax
xor    -0x48(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x40(%rbp),%rax
jbe    129b <revbin_permute+0x15b>
mov    -0x8(%rbp),%rdi
mov    -0x40(%rbp),%rsi
mov    -0x48(%rbp),%rdx
mov    $0x0,%al
call   1030 <idx_swap@plt>
mov    -0x8(%rbp),%rdi
mov    -0x28(%rbp),%rsi
xor    -0x40(%rbp),%rsi
mov    -0x28(%rbp),%rdx
xor    -0x48(%rbp),%rdx
mov    $0x0,%al
call   1030 <idx_swap@plt>
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    $0x0,%al
call   1040 <revbin@plt>
cltq
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x40(%rbp),%rax
jbe    12f8 <revbin_permute+0x1b8>
mov    -0x8(%rbp),%rdi
mov    -0x40(%rbp),%rsi
mov    -0x48(%rbp),%rdx
mov    $0x0,%al
call   1030 <idx_swap@plt>
mov    -0x8(%rbp),%rdi
mov    -0x28(%rbp),%rsi
xor    -0x40(%rbp),%rsi
mov    -0x28(%rbp),%rdx
xor    -0x48(%rbp),%rdx
mov    $0x0,%al
call   1030 <idx_swap@plt>
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
mov    -0x20(%rbp),%rax
xor    -0x48(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x40(%rbp),%rax
jbe    134c <revbin_permute+0x20c>
mov    -0x8(%rbp),%rdi
mov    -0x40(%rbp),%rsi
mov    -0x48(%rbp),%rdx
mov    $0x0,%al
call   1030 <idx_swap@plt>
mov    -0x8(%rbp),%rdi
mov    -0x30(%rbp),%rsi
xor    -0x40(%rbp),%rsi
mov    -0x30(%rbp),%rdx
xor    -0x48(%rbp),%rdx
mov    $0x0,%al
call   1030 <idx_swap@plt>
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    $0x0,%al
call   1040 <revbin@plt>
cltq
mov    %rax,-0x48(%rbp)
jmp    11c0 <revbin_permute+0x80>
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<revbin_permute>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %rsi,%r14
mov    %rdi,%r12
cmp    $0x40,%rsi
ja     1175 <revbin_permute+0x35>
mov    %r12,%rdi
mov    %r14,%rsi
xor    %eax,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1050 <revbin_permute_leq_64@plt>
mov    %r14,%rdi
xor    %eax,%eax
call   1060 <ld@plt>
cltq
mov    %rax,0x18(%rsp)
mov    %r14,%rax
shr    %rax
lea    -0x1(%r14),%r15
mov    %rax,0x10(%rsp)
add    $0xfffffffffffffffe,%rax
mov    %r15,%rcx
mov    %rax,0x8(%rsp)
sub    %rax,%rcx
mov    %rcx,0x20(%rsp)
shr    $0x2,%r14
xor    %ebx,%ebx
xor    %r13d,%r13d
jmp    11df <revbin_permute+0x9f>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
add    $0x4,%r13
mov    %r13,%rdi
mov    0x18(%rsp),%rsi
xor    %eax,%eax
call   1040 <revbin@plt>
movslq %eax,%rbx
cmp    %r14,%r13
jae    12f7 <revbin_permute+0x1b7>
cmp    %r13,%rbx
jbe    1240 <revbin_permute+0x100>
mov    %r12,%rdi
mov    %r13,%rsi
mov    %rbx,%rdx
xor    %eax,%eax
call   1030 <idx_swap@plt>
mov    %r13,%rsi
xor    %r15,%rsi
mov    %rbx,%rdx
xor    %r15,%rdx
mov    %r12,%rdi
xor    %eax,%eax
call   1030 <idx_swap@plt>
mov    %r13,%rsi
mov    0x8(%rsp),%rax
xor    %rax,%rsi
mov    %rbx,%rdx
xor    %rax,%rdx
mov    %r12,%rdi
xor    %eax,%eax
call   1030 <idx_swap@plt>
mov    %r13,%rsi
mov    0x20(%rsp),%rax
xor    %rax,%rsi
mov    %rbx,%rdx
xor    %rax,%rdx
mov    %r12,%rdi
xor    %eax,%eax
call   1030 <idx_swap@plt>
lea    0x1(%r13),%rbp
xor    0x10(%rsp),%rbx
cmp    %rbp,%rbx
jbe    1274 <revbin_permute+0x134>
mov    %r12,%rdi
mov    %rbp,%rsi
mov    %rbx,%rdx
xor    %eax,%eax
call   1030 <idx_swap@plt>
xor    %r15,%rbp
xor    %r15,%rbx
mov    %r12,%rdi
mov    %rbp,%rsi
mov    %rbx,%rdx
xor    %eax,%eax
call   1030 <idx_swap@plt>
lea    0x2(%r13),%rbp
mov    %rbp,%rdi
mov    0x18(%rsp),%rsi
xor    %eax,%eax
call   1040 <revbin@plt>
movslq %eax,%rbx
cmp    %rbx,%rbp
jae    12b5 <revbin_permute+0x175>
mov    %r12,%rdi
mov    %rbp,%rsi
mov    %rbx,%rdx
xor    %eax,%eax
call   1030 <idx_swap@plt>
xor    %r15,%rbp
mov    %r15,%rdx
xor    %rbx,%rdx
mov    %r12,%rdi
mov    %rbp,%rsi
xor    %eax,%eax
call   1030 <idx_swap@plt>
lea    0x3(%r13),%rbp
xor    0x10(%rsp),%rbx
cmp    %rbp,%rbx
jbe    11c0 <revbin_permute+0x80>
mov    %r12,%rdi
mov    %rbp,%rsi
mov    %rbx,%rdx
xor    %eax,%eax
call   1030 <idx_swap@plt>
mov    0x8(%rsp),%rax
xor    %rax,%rbp
xor    %rax,%rbx
mov    %r12,%rdi
mov    %rbp,%rsi
mov    %rbx,%rdx
xor    %eax,%eax
call   1030 <idx_swap@plt>
jmp    11c0 <revbin_permute+0x80>
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @revbin_permute({ double, double }* %0, i64 %1) {
%3 = alloca { double, double }*
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64
store { double, double }* %0, { double, double }** %3
store i64 %1, i64* %4
%12 = load i64, i64* %4
%13 = icmp ule i64 %12, 64
br i1 %13, label %14, label %18
14: ; preds = %2
%15 = load { double, double }*, { double, double }** %3
%16 = load i64, i64* %4
%17 = call i32 ({ double, double }*, i64, ...) bitcast (i32 (...)* @revbin_permute_leq_64 to i32 ({ double, double }*, i64, ...)*)({ double, double }* %15, i64 %16)
br label %143
18: ; preds = %2
%19 = load i64, i64* %4
%20 = call i32 (i64, ...) bitcast (i32 (...)* @ld to i32 (i64, ...)*)(i64 %19)
%21 = sext i32 %20 to i64
store i64 %21, i64* %5
%22 = load i64, i64* %4
%23 = lshr i64 %22, 1
store i64 %23, i64* %6
%24 = load i64, i64* %4
%25 = sub i64 %24, 1
store i64 %25, i64* %7
%26 = load i64, i64* %6
%27 = sub i64 %26, 2
store i64 %27, i64* %8
%28 = load i64, i64* %7
%29 = load i64, i64* %8
%30 = sub i64 %28, %29
store i64 %30, i64* %9
store i64 0, i64* %10
store i64 0, i64* %11
br label %31
31: ; preds = %136, %18
%32 = load i64, i64* %10
%33 = load i64, i64* %4
%34 = udiv i64 %33, 4
%35 = icmp ult i64 %32, %34
br i1 %35, label %36, label %143
36: ; preds = %31
%37 = load i64, i64* %11
%38 = load i64, i64* %10
%39 = icmp ugt i64 %37, %38
br i1 %39, label %40, label %69
40: ; preds = %36
%41 = load { double, double }*, { double, double }** %3
%42 = load i64, i64* %10
%43 = load i64, i64* %11
%44 = call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %41, i64 %42, i64 %43)
%45 = load { double, double }*, { double, double }** %3
%46 = load i64, i64* %7
%47 = load i64, i64* %10
%48 = xor i64 %46, %47
%49 = load i64, i64* %7
%50 = load i64, i64* %11
%51 = xor i64 %49, %50
%52 = call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %45, i64 %48, i64 %51)
%53 = load { double, double }*, { double, double }** %3
%54 = load i64, i64* %8
%55 = load i64, i64* %10
%56 = xor i64 %54, %55
%57 = load i64, i64* %8
%58 = load i64, i64* %11
%59 = xor i64 %57, %58
%60 = call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %53, i64 %56, i64 %59)
%61 = load { double, double }*, { double, double }** %3
%62 = load i64, i64* %9
%63 = load i64, i64* %10
%64 = xor i64 %62, %63
%65 = load i64, i64* %9
%66 = load i64, i64* %11
%67 = xor i64 %65, %66
%68 = call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %61, i64 %64, i64 %67)
br label %69
69: ; preds = %40, %36
%70 = load i64, i64* %10
%71 = add i64 %70, 1
store i64 %71, i64* %10
%72 = load i64, i64* %6
%73 = load i64, i64* %11
%74 = xor i64 %73, %72
store i64 %74, i64* %11
%75 = load i64, i64* %11
%76 = load i64, i64* %10
%77 = icmp ugt i64 %75, %76
br i1 %77, label %78, label %91
78: ; preds = %69
%79 = load { double, double }*, { double, double }** %3
%80 = load i64, i64* %10
%81 = load i64, i64* %11
%82 = call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %79, i64 %80, i64 %81)
%83 = load { double, double }*, { double, double }** %3
%84 = load i64, i64* %7
%85 = load i64, i64* %10
%86 = xor i64 %84, %85
%87 = load i64, i64* %7
%88 = load i64, i64* %11
%89 = xor i64 %87, %88
%90 = call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %83, i64 %86, i64 %89)
br label %91
91: ; preds = %78, %69
%92 = load i64, i64* %10
%93 = add i64 %92, 1
store i64 %93, i64* %10
%94 = load i64, i64* %10
%95 = load i64, i64* %5
%96 = call i32 (i64, i64, ...) bitcast (i32 (...)* @revbin to i32 (i64, i64, ...)*)(i64 %94, i64 %95)
%97 = sext i32 %96 to i64
store i64 %97, i64* %11
%98 = load i64, i64* %11
%99 = load i64, i64* %10
%100 = icmp ugt i64 %98, %99
br i1 %100, label %101, label %114
101: ; preds = %91
%102 = load { double, double }*, { double, double }** %3
%103 = load i64, i64* %10
%104 = load i64, i64* %11
%105 = call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %102, i64 %103, i64 %104)
%106 = load { double, double }*, { double, double }** %3
%107 = load i64, i64* %7
%108 = load i64, i64* %10
%109 = xor i64 %107, %108
%110 = load i64, i64* %7
%111 = load i64, i64* %11
%112 = xor i64 %110, %111
%113 = call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %106, i64 %109, i64 %112)
br label %114
114: ; preds = %101, %91
%115 = load i64, i64* %10
%116 = add i64 %115, 1
store i64 %116, i64* %10
%117 = load i64, i64* %6
%118 = load i64, i64* %11
%119 = xor i64 %118, %117
store i64 %119, i64* %11
%120 = load i64, i64* %11
%121 = load i64, i64* %10
%122 = icmp ugt i64 %120, %121
br i1 %122, label %123, label %136
123: ; preds = %114
%124 = load { double, double }*, { double, double }** %3
%125 = load i64, i64* %10
%126 = load i64, i64* %11
%127 = call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %124, i64 %125, i64 %126)
%128 = load { double, double }*, { double, double }** %3
%129 = load i64, i64* %8
%130 = load i64, i64* %10
%131 = xor i64 %129, %130
%132 = load i64, i64* %8
%133 = load i64, i64* %11
%134 = xor i64 %132, %133
%135 = call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %128, i64 %131, i64 %134)
br label %136
136: ; preds = %123, %114
%137 = load i64, i64* %10
%138 = add i64 %137, 1
store i64 %138, i64* %10
%139 = load i64, i64* %10
%140 = load i64, i64* %5
%141 = call i32 (i64, i64, ...) bitcast (i32 (...)* @revbin to i32 (i64, i64, ...)*)(i64 %139, i64 %140)
%142 = sext i32 %141 to i64
store i64 %142, i64* %11
br label %31
143: ; preds = %14, %31
ret void
}

LLVM IR (-O2):
define void @revbin_permute({ double, double }* %0, i64 %1) {
%3 = icmp ult i64 %1, 65
br i1 %3, label %4, label %6
4: ; preds = %2
%5 = tail call i32 ({ double, double }*, i64, ...) bitcast (i32 (...)* @revbin_permute_leq_64 to i32 ({ double, double }*, i64, ...)*)({ double, double }* %0, i64 %1)
br label %62
6: ; preds = %2
%7 = tail call i32 (i64, ...) bitcast (i32 (...)* @ld to i32 (i64, ...)*)(i64 %1)
%8 = sext i32 %7 to i64
%9 = lshr i64 %1, 1
%10 = add i64 %1, -1
%11 = add nsw i64 %9, -2
%12 = sub i64 %10, %11
%13 = lshr i64 %1, 2
br label %14
14: ; preds = %6, %57
%15 = phi i64 [ %60, %57 ], [ 0, %6 ]
%16 = phi i64 [ %58, %57 ], [ 0, %6 ]
%17 = icmp ugt i64 %15, %16
br i1 %17, label %18, label %29
18: ; preds = %14
%19 = tail call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %0, i64 %16, i64 %15)
%20 = xor i64 %16, %10
%21 = xor i64 %15, %10
%22 = tail call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %0, i64 %20, i64 %21)
%23 = xor i64 %16, %11
%24 = xor i64 %15, %11
%25 = tail call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %0, i64 %23, i64 %24)
%26 = xor i64 %16, %12
%27 = xor i64 %15, %12
%28 = tail call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %0, i64 %26, i64 %27)
br label %29
29: ; preds = %18, %14
%30 = or i64 %16, 1
%31 = xor i64 %15, %9
%32 = icmp ugt i64 %31, %30
br i1 %32, label %33, label %38
33: ; preds = %29
%34 = tail call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %0, i64 %30, i64 %31)
%35 = xor i64 %30, %10
%36 = xor i64 %31, %10
%37 = tail call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %0, i64 %35, i64 %36)
br label %38
38: ; preds = %33, %29
%39 = or i64 %16, 2
%40 = tail call i32 (i64, i64, ...) bitcast (i32 (...)* @revbin to i32 (i64, i64, ...)*)(i64 %39, i64 %8)
%41 = sext i32 %40 to i64
%42 = icmp ult i64 %39, %41
br i1 %42, label %43, label %48
43: ; preds = %38
%44 = tail call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %0, i64 %39, i64 %41)
%45 = xor i64 %39, %10
%46 = xor i64 %10, %41
%47 = tail call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %0, i64 %45, i64 %46)
br label %48
48: ; preds = %43, %38
%49 = or i64 %16, 3
%50 = xor i64 %9, %41
%51 = icmp ugt i64 %50, %49
br i1 %51, label %52, label %57
52: ; preds = %48
%53 = tail call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %0, i64 %49, i64 %50)
%54 = xor i64 %49, %11
%55 = xor i64 %50, %11
%56 = tail call i32 ({ double, double }*, i64, i64, ...) bitcast (i32 (...)* @idx_swap to i32 ({ double, double }*, i64, i64, ...)*)({ double, double }* %0, i64 %54, i64 %55)
br label %57
57: ; preds = %52, %48
%58 = add nuw nsw i64 %16, 4
%59 = tail call i32 (i64, i64, ...) bitcast (i32 (...)* @revbin to i32 (i64, i64, ...)*)(i64 %58, i64 %8)
%60 = sext i32 %59 to i64
%61 = icmp ult i64 %58, %13
br i1 %61, label %14, label %62
62: ; preds = %57, %4
ret void
}