// File: /workspace/github_cpp_makefile_star2_O3/MarkCBell[P]twister/./twister/kernel/twister.cpp
// Function: annulus::twist(Sign)
void annulus::twist(Sign whichway)
{
	// There's a much worse way to do this, which for
	// obscenely large values of "length" (>6?)
	// actually uses fewer tetrahedra.
	// (The idea is: retriangulate the annulus so that 
	// it has length 1 and then do the twist(s).  Then
	// undo the retriangulation.  But this is pointless, 
	// SnapPea will totally change the triangulation, 
	// anyway.   A more general notion is to perform a long 
	// twist by conjugating it to a short one...)
	
	// Every speed bump consists of "length" identical layers.
	// Don't peel them apart.  
	// Never look inside a speed bump.  Trust us.
	output_debugging("twist", 2);
	
	manifold *M = sq[0]->home;
	
	for (int i = 0; i < length; i++)
		sq[i]->set_status(false);
	
	std::vector< std::vector<tetra *> > tet;
	int i, j;
	
	// Create a bunch of tetrahedra. We'll refer
	// to tet[i][j] as the new tetrahedron in the
	// i^th row (from the bottom) and j^th column
	// (from the left). 
	
	for( i = 0; i < length; i++ )
	{
		std::vector<tetra *> next_row;
		for( j = 0; j < length; j++ )
			next_row.push_back(new tetra(M, speedbump));
		
		tet.push_back(next_row);
	}
	
	// First thing to do is glue all tetras in a column
	// along their "blue faces".  (For terminology, refer
	// to a certain paper tablecloth in the new Thai
	// restaurant on Bancroft above Telegraph.)
	// Thus loop over j first (sorry 'bout that). 
	// While we're at it we'll attach the last 
	// and first blue face to the ceiling and floor.
	//
	// Keep gluing 'til you're blue in the face.
	
	for( j = 0; j < length; j++ ) 
	{
		for( i = 0; i < length - 1; i++ )
			tet[i][j]->gluesym(tet[i+1][j], 2, perm(0,1,3,2));
		
		// Attach the top of the column to the ceiling and the bottom of the column to the floor.
		sq[j]->topright->subbedby(tet[length-1][j], 2, (upright[j]) ? perm(0,1,2,3) : perm(1,3,2,0));
		sq[j]->topright->gluesym(tet[0][j], 2, (upright[j]) ? perm(0,1,3,2) : perm(1,2,3,0));
	}
	
	// That finishes off the blue faces.  
	// Now to glue neighboring columns together
	// along the "red" faces. While we're at it
	// we'll attach the left-over red faces to the 
	// ceiling and floor. This is a bit tricky, so 
	// watch carefully. Follow the red card...
	
	for( j = 0; j < length; j++ )
	{
		int next = (j+1) % length;
		int begin, end;
		
		// Assuming here that true == 1 and false == 0.
		int offset = whichway*(!upright[j] + upright[next]);
		
		if (whichway == plus)
		{
			begin = offset;
			end = length;
		}
		else
		{
			begin = 0;
			end = length + offset;
		}
		
		// Gluing the columns together.
		for( i = begin; i < end; i++ )
			tet[i][j]->gluesym(tet[i - offset][next], 1, perm(1,0,2,3));
		
		// Now glue the left over red faces on top to the 
		// ceiling using subbedby. Then glue remaining red
		// faces (on the bottom) to the newly available floor.
		
		if ( upright[j] && upright[next] )
		{
			// The offset is whichway*1.
			if (whichway == plus)
			{
				sq[next]->topleft->subbedby(tet[length - 1][next], 1, perm(1,0,3,2));
				sq[next]->topleft->gluesym(tet[0][j], 1, perm(0,1,3,2));
			}
			else
			{
				sq[next]->topleft->subbedby(tet[length - 1][j], 1, perm(0,1,2,3));
				sq[next]->topleft->gluesym(tet[0][next], 1, perm(1,0,2,3));
			}
		}      
		if ( upright[j] && !upright[next] )
		{
			// The offset is zero, so there are 
			// no left-over red faces.  :)
		}      
		
		if ( !upright[j] && upright[next] )
		{
			// The offset is whichway*2.
			if (whichway == plus)
			{
				sq[next]->topleft->subbedby(tet[length - 1][next], 1, perm(1, 0, 3, 2));
				sq[next]->topleft->gluesym(tet[1][j], 1, perm(0,1,3,2));
				
				sq[j]->topleft->subbedby(tet[length - 2][next], 1, perm(2, 0, 1, 3));
				sq[j]->topleft->gluesym(tet[0][j], 1, perm(2,1,0,3));
			}
			else
			{
				sq[j]->topleft->subbedby(tet[length - 1][j], 1, perm(3, 1, 0, 2));
				sq[j]->topleft->gluesym(tet[1][next], 1, perm(3, 0, 1, 2));
				
				sq[next]->topleft->subbedby(tet[length - 2][j], 1, perm(0,1,2,3));
				sq[next]->topleft->gluesym(tet[0][next], 1, perm(1,0,2,3));
			}
		}      
		if ( !upright[j] && !upright[next] )
		{
			// The offset is whichway*1.
			if (whichway == plus)
			{
				sq[j]->topleft->subbedby(tet[length - 1][next], 1, perm(2, 0, 1, 3));
				sq[j]->topleft->gluesym(tet[0][j], 1, perm(2,1,0,3));
			}
			else
			{
				sq[j]->topleft->subbedby(tet[length - 1][j], 1, perm(3, 1, 0, 2));
				sq[j]->topleft->gluesym(tet[0][next], 1, perm(3, 0, 1, 2));
			}
		}      
		// Isn't that all perfectly clear?
		// No?  Well, is my face is red!
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movl %esi, 0x1c(%rsp)
movq %rdi, %r14
leaq 0x88(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x7b79(%rip), %rsi      # 0x176ca
leaq 0x7b77(%rip), %rdx      # 0x176cf
leaq 0x78(%rsp), %rbx
movq %rbx, %rdi
callq 0x892e
movq %rbx, %rdi
movl $0x2, %esi
callq 0x4229
movq 0x78(%rsp), %rdi
cmpq %r15, %rdi
je 0xfb8c
movq 0x88(%rsp), %rsi
incq %rsi
callq 0x3220
movslq (%r14), %rcx
testq %rcx, %rcx
jle 0x103af
movq 0x8(%r14), %rax
movq (%rax), %rdx
movq 0x38(%rdx), %r15
xorl %edx, %edx
movq (%rax,%rdx,8), %rsi
movb $0x0, 0x32(%rsi)
incq %rdx
cmpq %rdx, %rcx
jne 0xfba5
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
testl %ecx, %ecx
jle 0x103c0
xorl %ebp, %ebp
leaq 0x40(%rsp), %r12
leaq 0x70(%rsp), %r13
movq %r14, 0x38(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
testl %ecx, %ecx
jle 0xfc4a
xorl %r14d, %r14d
movl $0xc0, %edi
callq 0x3210
movq %rax, %rbx
movq $0x0, (%rsp)
movq %rax, %rdi
movq %r15, %rsi
movl $0x1, %edx
movl $0x3, %ecx
movl $0x2, %r8d
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
callq 0xde5c
movq %rbx, 0x70(%rsp)
movq %r12, %rdi
movq %r13, %rsi
callq 0x13bf4
incl %r14d
movq 0x38(%rsp), %rax
cmpl (%rax), %r14d
jl 0xfbf7
leaq 0x20(%rsp), %rdi
movq %r12, %rsi
callq 0x13b1c
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
movq 0x38(%rsp), %r14
je 0xfc73
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x3220
incl %ebp
movl (%r14), %ecx
cmpl %ecx, %ebp
jl 0xfbdf
testl %ecx, %ecx
jle 0x103c0
xorl %ebp, %ebp
leaq 0x40(%rsp), %r15
cmpl $0x2, %ecx
jl 0xfcf6
xorl %r13d, %r13d
xorl %r14d, %r14d
movq 0x20(%rsp), %rax
movq (%rax,%r13), %rcx
movq 0x18(%rax,%r13), %rax
movq (%rcx,%rbp,8), %rbx
movq (%rax,%rbp,8), %r12
movq %r15, %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x8860
movq %rbx, %rdi
movq %r12, %rsi
movl $0x2, %edx
movq %r15, %rcx
callq 0xe04e
incq %r14
movq 0x38(%rsp), %rax
movslq (%rax), %rax
decq %rax
addq $0x18, %r13
cmpq %rax, %r14
jl 0xfc9a
jmp 0xfcfb
decl %ecx
movslq %ecx, %rax
movq 0x38(%rsp), %r14
movq 0x8(%r14), %rcx
movq (%rcx,%rbp,8), %rcx
movq 0x18(%rcx), %r12
movq 0x20(%rsp), %rcx
leaq (%rax,%rax,2), %rax
movq (%rcx,%rax,8), %rax
movq (%rax,%rbp,8), %r13
movq 0x10(%r14), %rax
movzbl (%rax,%rbp), %eax
leal (%rax,%rax,2), %r8d
xorb $0x1, %al
movzbl %al, %esi
leal 0x1(,%rsi,2), %edx
movq %r15, %rdi
movl $0x2, %ecx
callq 0x8860
movq %r12, %rdi
movq %r13, %rsi
movl $0x2, %edx
movq %r15, %rcx
callq 0xe200
movq 0x8(%r14), %rax
movq (%rax,%rbp,8), %rax
movq 0x18(%rax), %r12
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%rbp,8), %rbx
movq 0x10(%r14), %rax
movzbl (%rax,%rbp), %r8d
movl %r8d, %eax
xorb $0x1, %al
movzbl %al, %esi
movl $0x2, %edx
subl %r8d, %edx
addl %r8d, %r8d
movq %r15, %rdi
movl $0x3, %ecx
callq 0x8860
movq %r12, %rdi
movq %rbx, %rsi
movl $0x2, %edx
movq %r15, %rcx
callq 0xe04e
incq %rbp
movslq (%r14), %rcx
cmpq %rcx, %rbp
jl 0xfc8f
testl %ecx, %ecx
jle 0x103c0
xorl %r15d, %r15d
leaq 0x40(%rsp), %r12
xorl %eax, %eax
movq %rax, %r13
incq %rax
movq %rax, 0x68(%rsp)
cltd
idivl %ecx
movq 0x10(%r14), %rax
movzbl (%rax,%r13), %esi
movl %esi, %edi
xorl $0x1, %edi
movq %rdx, 0x10(%rsp)
movzbl (%rax,%rdx), %edx
addl %edi, %edx
movl %edx, %edi
movl 0x1c(%rsp), %r8d
imull %r8d, %edi
cmpl $0x1, %r8d
cmovnel %r15d, %edx
movl %edi, %r8d
cmovel %r15d, %r8d
addl %ecx, %r8d
cmpl %r8d, %edx
jge 0xfeb1
movq %r13, 0x60(%rsp)
movl %edx, %eax
movslq %edi, %rcx
movl %r8d, %r15d
subq %rax, %r15
shlq $0x3, %rcx
leaq (%rcx,%rcx,2), %r13
negq %r13
shll $0x3, %edx
leaq (%rdx,%rdx,2), %r14
movq 0x20(%rsp), %rax
movq (%rax,%r14), %rcx
addq %r14, %rax
movq 0x60(%rsp), %rdx
movq (%rcx,%rdx,8), %rbx
movq (%r13,%rax), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rbp
leaq 0x40(%rsp), %r12
movq %r12, %rdi
movl $0x1, %esi
xorl %edx, %edx
movl $0x2, %ecx
movl $0x3, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe04e
addq $0x18, %r14
decq %r15
jne 0xfe39
movq 0x38(%rsp), %r14
movq 0x10(%r14), %rax
movq 0x60(%rsp), %r13
movb (%rax,%r13), %sil
xorl %r15d, %r15d
leaq 0x40(%rsp), %r12
testb $0x1, %sil
je 0xffe8
movq 0x10(%rsp), %rcx
cmpb $0x1, (%rax,%rcx)
jne 0xffe8
movq 0x8(%r14), %rax
movq 0x10(%rsp), %rdx
movq (%rax,%rdx,8), %rax
movq (%rax), %rbp
movslq (%r14), %rax
movq 0x20(%rsp), %rcx
leaq (%rax,%rax,2), %rax
movq -0x18(%rcx,%rax,8), %rax
cmpl $0x1, 0x1c(%rsp)
jne 0xff6e
movq (%rax,%rdx,8), %rbx
movq %r12, %rdi
movl $0x1, %esi
xorl %edx, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x8860
movq %rbp, %rdi
movq %rbx, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe200
movq 0x8(%r14), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13,8), %rbp
movq %r12, %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe04e
jmp 0xffe8
movq (%rax,%r13,8), %rbx
movq %r12, %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x2, %ecx
movl $0x3, %r8d
callq 0x8860
movq %rbp, %rdi
movq %rbx, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe200
movq 0x8(%r14), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%rcx,8), %rbp
movq %r12, %rdi
movl $0x1, %esi
xorl %edx, %edx
movl $0x2, %ecx
movl $0x3, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe04e
movq 0x10(%r14), %rax
cmpb $0x0, (%rax,%r13)
jne 0x10265
movq 0x10(%rsp), %rcx
cmpb $0x1, (%rax,%rcx)
jne 0x10265
movq 0x8(%r14), %rax
movslq (%r14), %rcx
movq 0x20(%rsp), %rdx
leaq (%rcx,%rcx,2), %rcx
movq -0x18(%rdx,%rcx,8), %rcx
cmpl $0x1, 0x1c(%rsp)
jne 0x10148
movq 0x10(%rsp), %rdx
movq (%rax,%rdx,8), %rax
movq (%rax), %rbx
movq (%rcx,%rdx,8), %rbp
movq %r12, %rdi
movl $0x1, %esi
xorl %edx, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe200
movq 0x8(%r14), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq 0x18(%rax), %rax
movq (%rax,%r13,8), %rbp
movq %r12, %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe04e
movq 0x8(%r14), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rbx
movslq (%r14), %rax
movq 0x20(%rsp), %rcx
leaq (%rax,%rax,2), %rax
movq -0x30(%rcx,%rax,8), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rbp
movq %r12, %rdi
movl $0x2, %esi
xorl %edx, %edx
movl $0x1, %ecx
movl $0x3, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe200
movq 0x8(%r14), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13,8), %rbp
movq %r12, %rdi
movl $0x2, %esi
movl $0x1, %edx
xorl %ecx, %ecx
movl $0x3, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe04e
jmp 0x10265
movq (%rax,%r13,8), %rax
movq (%rax), %rbx
movq (%rcx,%r13,8), %rbp
movq %r12, %rdi
movl $0x3, %esi
movl $0x1, %edx
xorl %ecx, %ecx
movl $0x2, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe200
movq 0x8(%r14), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rbp
movq %r12, %rdi
movl $0x3, %esi
xorl %edx, %edx
movl $0x1, %ecx
movl $0x2, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe04e
movq 0x8(%r14), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rbx
movslq (%r14), %rax
movq 0x20(%rsp), %rcx
leaq (%rax,%rax,2), %rax
movq -0x30(%rcx,%rax,8), %rax
movq (%rax,%r13,8), %rbp
movq %r12, %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x2, %ecx
movl $0x3, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe200
movq 0x8(%r14), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%rcx,8), %rbp
movq %r12, %rdi
movl $0x1, %esi
xorl %edx, %edx
movl $0x2, %ecx
movl $0x3, %r8d
callq 0x8860
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe04e
movq 0x10(%r14), %rax
cmpb $0x0, (%rax,%r13)
jne 0x1039c
movq 0x10(%rsp), %rcx
cmpb $0x0, (%rax,%rcx)
jne 0x1039c
movq 0x8(%r14), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rbp
movslq (%r14), %rax
movq 0x20(%rsp), %rcx
leaq (%rax,%rax,2), %rax
movq -0x18(%rcx,%rax,8), %rax
cmpl $0x1, 0x1c(%rsp)
jne 0x10322
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rbx
movq %r12, %rdi
movl $0x2, %esi
xorl %edx, %edx
movl $0x1, %ecx
movl $0x3, %r8d
callq 0x8860
movq %rbp, %rdi
movq %rbx, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe200
movq 0x8(%r14), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13,8), %r13
movq %r12, %rdi
movl $0x2, %esi
movl $0x1, %edx
xorl %ecx, %ecx
movl $0x3, %r8d
callq 0x8860
movq %rbx, %rdi
movq %r13, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe04e
jmp 0x1039c
movq (%rax,%r13,8), %rbx
movq %r12, %rdi
movl $0x3, %esi
movl $0x1, %edx
xorl %ecx, %ecx
movl $0x2, %r8d
callq 0x8860
movq %rbp, %rdi
movq %rbx, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe200
movq 0x8(%r14), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %r13
movq %r12, %rdi
movl $0x3, %esi
xorl %edx, %edx
movl $0x1, %ecx
movl $0x2, %r8d
callq 0x8860
movq %rbx, %rdi
movq %r13, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xe04e
movslq (%r14), %rcx
movq 0x68(%rsp), %rax
cmpq %rcx, %rax
jl 0xfdca
jmp 0x103c0
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x13b48
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
movq 0x78(%rsp), %rdi
cmpq %r15, %rdi
je 0x1045e
movq 0x88(%rsp), %rsi
incq %rsi
callq 0x3220
jmp 0x1045e
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x10423
jmp 0x1043a
jmp 0x10423
jmp 0x10423
jmp 0x10423
movq %rax, %r14
jmp 0x10454
movq %rax, %r14
movl $0xc0, %esi
movq %rbx, %rdi
callq 0x3220
jmp 0x1043d
movq %rax, %r14
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x10454
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x3220
leaq 0x20(%rsp), %rdi
callq 0x13b48
movq %r14, %rdi
callq 0x33e0