// File: ctSkennerton[P]fxtract/util/bitmat.c
// Function: sse_trans
void
sse_trans(uint8_t const *inp, uint8_t *out, int nrows, int ncols)
{
#   define INP(x,y) inp[(x)*ncols/8 + (y)/8]
#   define OUT(x,y) out[(y)*nrows/8 + (x)/8]
    int rr, cc, i, h;
    union { XMM x; uint8_t b[16]; } tmp;

    // Do the main body in 16x8 blocks:
    for (rr = 0; rr <= nrows - 16; rr += 16)
        for (cc = 0; cc < ncols; cc += 8) {
            for (i = 0; i < 16; ++i)
                tmp.b[i] = INP(rr + i, cc);
            for (i = 8; --i >= 0; tmp.x = _mm_slli_epi64(tmp.x, 1))
                *(uint16_t*)&OUT(rr, cc + i) = _mm_movemask_epi8(tmp.x);
        }

    if (rr == nrows) return;

    // The remainder is a block of 8x16n+8 bits (n >= 0).
    //  Do a PAIR of 8x8 blocks in each step:
    for (cc = 0; cc <= ncols - 16; cc += 16) {
        for (i = 0; i < 8; ++i)
            tmp.b[i] = h = *(uint16_t const*)&INP(rr + i, cc),
            tmp.b[i + 8] = h >> 8;
        for (i = 8; --i >= 0; tmp.x = _mm_slli_epi64(tmp.x, 1))
            OUT(rr, cc + i) = h = _mm_movemask_epi8(tmp.x),
            OUT(rr, cc + i + 8) = h >> 8;
    }

    if (cc == ncols) return;

    //  Do the remaining 8x8 block:
    for (i = 0; i < 8; ++i)
        tmp.b[i] = INP(rr + i, cc);
    for (i = 8; --i >= 0; tmp.x = _mm_slli_epi64(tmp.x, 1))
        OUT(rr, cc + i) = _mm_movemask_epi8(tmp.x);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x98(%rbp)
movq %rsi, -0xa0(%rbp)
movl %edx, -0xa4(%rbp)
movl %ecx, -0xa8(%rbp)
movl $0x0, -0xac(%rbp)
movl -0xac(%rbp), %eax
movl -0xa4(%rbp), %ecx
subl $0x10, %ecx
cmpl %ecx, %eax
jg 0x3d2c
movl $0x0, -0xb0(%rbp)
movl -0xb0(%rbp), %eax
cmpl -0xa8(%rbp), %eax
jge 0x3d16
movl $0x0, -0xb4(%rbp)
cmpl $0x10, -0xb4(%rbp)
jge 0x3c3e
movq -0x98(%rbp), %rax
movq %rax, -0xd8(%rbp)
movl -0xac(%rbp), %eax
addl -0xb4(%rbp), %eax
imull -0xa8(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0xb0(%rbp), %eax
movl $0x8, %esi
cltd
idivl %esi
movl %eax, %edx
movq -0xd8(%rbp), %rax
addl %edx, %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %cl
movslq -0xb4(%rbp), %rax
movb %cl, -0xd0(%rbp,%rax)
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x3bcc
movl $0x8, -0xb4(%rbp)
movl -0xb4(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0xb4(%rbp)
cmpl $0x0, %eax
jl 0x3d00
movdqa -0xd0(%rbp), %xmm0
movdqa %xmm0, -0x70(%rbp)
movdqa -0x70(%rbp), %xmm0
pmovmskb %xmm0, %eax
movw %ax, -0xe2(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movl -0xb0(%rbp), %eax
addl -0xb4(%rbp), %eax
imull -0xa4(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0xac(%rbp), %eax
movl $0x8, %esi
cltd
idivl %esi
movw -0xe2(%rbp), %dx
movl %eax, %esi
movq -0xe0(%rbp), %rax
addl %esi, %ecx
movslq %ecx, %rcx
movw %dx, (%rax,%rcx)
movdqa -0xd0(%rbp), %xmm0
movdqa %xmm0, -0x10(%rbp)
movl $0x1, -0x14(%rbp)
movdqa -0x10(%rbp), %xmm0
movl -0x14(%rbp), %eax
movd %eax, %xmm1
psllq %xmm1, %xmm0
movdqa %xmm0, -0xd0(%rbp)
jmp 0x3c48
jmp 0x3d02
movl -0xb0(%rbp), %eax
addl $0x8, %eax
movl %eax, -0xb0(%rbp)
jmp 0x3bb0
jmp 0x3d18
movl -0xac(%rbp), %eax
addl $0x10, %eax
movl %eax, -0xac(%rbp)
jmp 0x3b8f
movl -0xac(%rbp), %eax
cmpl -0xa4(%rbp), %eax
jne 0x3d3f
jmp 0x409a
movl $0x0, -0xb0(%rbp)
movl -0xb0(%rbp), %eax
movl -0xa8(%rbp), %ecx
subl $0x10, %ecx
cmpl %ecx, %eax
jg 0x3f46
movl $0x0, -0xb4(%rbp)
cmpl $0x8, -0xb4(%rbp)
jge 0x3e09
movq -0x98(%rbp), %rax
movq %rax, -0xf0(%rbp)
movl -0xac(%rbp), %eax
addl -0xb4(%rbp), %eax
imull -0xa8(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0xb0(%rbp), %eax
movl $0x8, %esi
cltd
idivl %esi
movl %eax, %edx
movq -0xf0(%rbp), %rax
addl %edx, %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx), %eax
movl %eax, -0xb8(%rbp)
movb %al, %cl
movslq -0xb4(%rbp), %rax
movb %cl, -0xd0(%rbp,%rax)
movl -0xb8(%rbp), %eax
sarl $0x8, %eax
movb %al, %cl
movl -0xb4(%rbp), %eax
addl $0x8, %eax
cltq
movb %cl, -0xd0(%rbp,%rax)
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x3d6a
movl $0x8, -0xb4(%rbp)
movl -0xb4(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0xb4(%rbp)
cmpl $0x0, %eax
jl 0x3f30
movdqa -0xd0(%rbp), %xmm0
movdqa %xmm0, -0x80(%rbp)
movdqa -0x80(%rbp), %xmm0
pmovmskb %xmm0, %eax
movl %eax, -0xb8(%rbp)
movb %al, -0x109(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0x108(%rbp)
movl -0xb0(%rbp), %eax
addl -0xb4(%rbp), %eax
imull -0xa4(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0xac(%rbp), %eax
movl $0x8, %esi
cltd
idivl %esi
movb -0x109(%rbp), %dl
movl %eax, %esi
movq -0x108(%rbp), %rax
addl %esi, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0xb8(%rbp), %eax
sarl $0x8, %eax
movb %al, -0xf9(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0xf8(%rbp)
movl -0xb0(%rbp), %eax
addl -0xb4(%rbp), %eax
addl $0x8, %eax
imull -0xa4(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0xac(%rbp), %eax
movl $0x8, %esi
cltd
idivl %esi
movb -0xf9(%rbp), %dl
movl %eax, %esi
movq -0xf8(%rbp), %rax
addl %esi, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movdqa -0xd0(%rbp), %xmm0
movdqa %xmm0, -0x30(%rbp)
movl $0x1, -0x34(%rbp)
movdqa -0x30(%rbp), %xmm0
movl -0x34(%rbp), %eax
movd %eax, %xmm1
psllq %xmm1, %xmm0
movdqa %xmm0, -0xd0(%rbp)
jmp 0x3e13
jmp 0x3f32
movl -0xb0(%rbp), %eax
addl $0x10, %eax
movl %eax, -0xb0(%rbp)
jmp 0x3d49
movl -0xb0(%rbp), %eax
cmpl -0xa8(%rbp), %eax
jne 0x3f59
jmp 0x409a
movl $0x0, -0xb4(%rbp)
cmpl $0x8, -0xb4(%rbp)
jge 0x3fd5
movq -0x98(%rbp), %rax
movq %rax, -0x118(%rbp)
movl -0xac(%rbp), %eax
addl -0xb4(%rbp), %eax
imull -0xa8(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0xb0(%rbp), %eax
movl $0x8, %esi
cltd
idivl %esi
movl %eax, %edx
movq -0x118(%rbp), %rax
addl %edx, %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %cl
movslq -0xb4(%rbp), %rax
movb %cl, -0xd0(%rbp,%rax)
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x3f63
movl $0x8, -0xb4(%rbp)
movl -0xb4(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0xb4(%rbp)
cmpl $0x0, %eax
jl 0x409a
movdqa -0xd0(%rbp), %xmm0
movdqa %xmm0, -0x90(%rbp)
movdqa -0x90(%rbp), %xmm0
pmovmskb %xmm0, %eax
movb %al, -0x121(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0x120(%rbp)
movl -0xb0(%rbp), %eax
addl -0xb4(%rbp), %eax
imull -0xa4(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0xac(%rbp), %eax
movl $0x8, %esi
cltd
idivl %esi
movb -0x121(%rbp), %dl
movl %eax, %esi
movq -0x120(%rbp), %rax
addl %esi, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movdqa -0xd0(%rbp), %xmm0
movdqa %xmm0, -0x50(%rbp)
movl $0x1, -0x54(%rbp)
movdqa -0x50(%rbp), %xmm0
movl -0x54(%rbp), %eax
movd %eax, %xmm1
psllq %xmm1, %xmm0
movdqa %xmm0, -0xd0(%rbp)
jmp 0x3fdf
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)