// File: /workspace/github_cpp_makefile_star2_O2/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 $0xa8, %rsp
movl %esi, 0x1c(%rsp)
movq %rdi, 0x10(%rsp)
leaq 0x58a1(%rip), %rsi      # 0x11622
leaq 0x88(%rsp), %rdi
leaq 0x20(%rsp), %rdx
callq 0x3e82
leaq 0x88(%rsp), %rdi
pushq $0x2
popq %rsi
callq 0x3d1a
leaq 0x88(%rsp), %rdi
callq 0x3458
movq 0x10(%rsp), %rdx
movq 0x8(%rdx), %rax
movq (%rax), %rcx
movq 0x38(%rcx), %r15
movl (%rdx), %ecx
xorl %edx, %edx
testl %ecx, %ecx
movl $0x0, %esi
cmovgl %ecx, %esi
cmpq %rdx, %rsi
je 0xbde0
movq (%rax,%rdx,8), %rdi
movb $0x0, 0x32(%rdi)
incq %rdx
jmp 0xbdce
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %rax
andq $0x0, 0x10(%rax)
movaps %xmm0, (%rax)
xorl %edx, %edx
pushq $0x2
popq %rbx
leaq 0x40(%rsp), %r14
leaq 0x80(%rsp), %rbp
movl %edx, 0x38(%rsp)
cmpl %ecx, %edx
jge 0xbe94
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
andq $0x0, 0x50(%rsp)
xorl %r12d, %r12d
cmpl %ecx, %r12d
jge 0xbe6d
movl $0xc0, %edi
callq 0x3240
movq %rax, %r13
andq $0x0, (%rsp)
movq %rax, %rdi
movq %r15, %rsi
pushq $0x1
popq %rdx
pushq $0x3
popq %rcx
movl %ebx, %r8d
pushq $-0x1
popq %r9
callq 0xa3fa
movq %r13, 0x80(%rsp)
movq %r14, %rdi
movq %rbp, %rsi
callq 0xf298
incl %r12d
movq 0x10(%rsp), %rax
movl (%rax), %ecx
jmp 0xbe1f
leaq 0x20(%rsp), %rdi
movq %r14, %rsi
callq 0xf0d0
movq %r14, %rdi
callq 0xf264
movl 0x38(%rsp), %edx
incl %edx
movq 0x10(%rsp), %rax
movl (%rax), %ecx
jmp 0xbe02
xorl %ebp, %ebp
leaq 0x40(%rsp), %r15
movslq %ecx, %rax
cmpq %rax, %rbp
jge 0xbfd1
xorl %edx, %edx
xorl %r12d, %r12d
movq %rbp, 0x38(%rsp)
decl %ecx
movslq %ecx, %rax
cmpq %rax, %r12
jge 0xbf1a
movq 0x20(%rsp), %rax
movq (%rax,%rdx), %rcx
movq %rdx, %rbx
movq 0x18(%rax,%rdx), %rax
movq (%rcx,%rbp,8), %r14
movq (%rax,%rbp,8), %r13
movq %r15, %rdi
xorl %esi, %esi
pushq $0x1
popq %rdx
pushq $0x3
popq %rcx
movq %r15, %rbp
pushq $0x2
popq %r15
movl %r15d, %r8d
callq 0x6790
movq %r14, %rdi
movq %r13, %rsi
movl %r15d, %edx
movq %rbp, %rcx
callq 0xa5d2
movq 0x10(%rsp), %rax
movl (%rax), %ecx
movq %rbx, %rdx
addq $0x18, %rdx
incq %r12
movq %rbp, %r15
movq 0x38(%rsp), %rbp
jmp 0xbeb1
movq 0x10(%rsp), %rdx
movq 0x8(%rdx), %rcx
movq (%rcx,%rbp,8), %rcx
movq 0x18(%rcx), %r14
movq 0x20(%rsp), %rcx
imulq $0x18, %rax, %rax
movq (%rcx,%rax), %rax
movq (%rax,%rbp,8), %r13
movq 0x10(%rdx), %rax
movzbl (%rax,%rbp), %eax
leal (%rax,%rax,2), %r8d
xorb $0x1, %al
movzbl %al, %esi
leal 0x1(,%rsi,2), %edx
movq %r15, %rdi
pushq $0x2
popq %rbx
movl %ebx, %ecx
callq 0x6790
movq %r14, %rdi
movq %r13, %rsi
movl %ebx, %edx
movq %r15, %rcx
callq 0xa734
movq 0x10(%rsp), %rcx
movq 0x8(%rcx), %rax
movq (%rax,%rbp,8), %rax
movq 0x18(%rax), %r14
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%rbp,8), %r13
movq 0x10(%rcx), %rax
movzbl (%rax,%rbp), %r8d
movl %r8d, %eax
xorb $0x1, %al
movzbl %al, %esi
movl %ebx, %edx
subl %r8d, %edx
addl %r8d, %r8d
movq %r15, %rdi
pushq $0x3
popq %rcx
callq 0x6790
movq %r14, %rdi
movq %r13, %rsi
movl %ebx, %edx
movq %r15, %rcx
callq 0xa5d2
incq %rbp
movq 0x10(%rsp), %rax
movl (%rax), %ecx
jmp 0xbe9b
xorl %eax, %eax
movq %rax, %r13
movslq %ecx, %rax
cmpq %rax, %r13
jge 0xc521
leaq 0x1(%r13), %rax
movq %rax, 0x60(%rsp)
cltd
idivl %ecx
movq 0x10(%rsp), %rax
movq 0x10(%rax), %rax
movb (%rax,%r13), %sil
xorb $0x1, %sil
movq %rdx, 0x38(%rsp)
addb (%rax,%rdx), %sil
movzbl %sil, %ebx
movl %ebx, %eax
movl 0x1c(%rsp), %edx
imull %edx, %eax
cmpl $0x1, %edx
movl $0x0, %esi
cmovnel %esi, %ebx
movslq %eax, %rdx
cmovel %esi, %eax
addl %ecx, %eax
cltq
movq %rax, 0x78(%rsp)
imulq $0x18, %rbx, %rsi
imulq $-0x18, %rdx, %rax
movq %rax, 0x70(%rsp)
movq %r13, 0x68(%rsp)
cmpq 0x78(%rsp), %rbx
jge 0xc0a9
movq 0x20(%rsp), %rax
movq (%rax,%rsi), %rcx
movq %rsi, %r15
addq %rsi, %rax
movq (%rcx,%r13,8), %r14
movq 0x70(%rsp), %rcx
movq (%rcx,%rax), %rax
movq 0x38(%rsp), %rcx
movq (%rax,%rcx,8), %r12
leaq 0x40(%rsp), %r13
movq %r13, %rdi
pushq $0x1
popq %rbp
movl %ebp, %esi
xorl %edx, %edx
pushq $0x2
popq %rcx
pushq $0x3
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r13, %rcx
callq 0xa5d2
incq %rbx
movq %r15, %rsi
addq $0x18, %rsi
movq 0x68(%rsp), %r13
jmp 0xc041
movq 0x10(%rsp), %rax
movq 0x10(%rax), %rax
cmpb $0x1, (%rax,%r13)
leaq 0x40(%rsp), %r15
pushq $0x1
popq %rbp
movq 0x38(%rsp), %rbx
jne 0xc1ca
cmpb $0x1, (%rax,%rbx)
jne 0xc1ca
movq 0x10(%rsp), %rcx
movslq (%rcx), %rax
imulq $0x18, %rax, %rax
movq 0x8(%rcx), %rcx
movq (%rcx,%rbx,8), %rcx
movq (%rcx), %r14
movq 0x20(%rsp), %rcx
movq -0x18(%rcx,%rax), %rax
cmpl $0x1, 0x1c(%rsp)
jne 0xc164
movq (%rax,%rbx,8), %r12
movq %r15, %rdi
movl %ebp, %esi
xorl %edx, %edx
pushq $0x3
popq %rcx
pushq $0x2
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa734
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax,%rbx,8), %rax
movq (%rax), %r14
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13,8), %r12
movq %r15, %rdi
xorl %esi, %esi
movl %ebp, %edx
pushq $0x3
popq %rcx
pushq $0x2
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa5d2
jmp 0xc1ca
movq (%rax,%r13,8), %r12
movq %r15, %rdi
xorl %esi, %esi
movl %ebp, %edx
pushq $0x2
popq %rcx
pushq $0x3
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa734
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax,%rbx,8), %rax
movq (%rax), %r14
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%rbx,8), %r12
movq %r15, %rdi
movl %ebp, %esi
xorl %edx, %edx
pushq $0x2
popq %rcx
pushq $0x3
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa5d2
movq 0x10(%rsp), %rax
movq 0x10(%rax), %rax
cmpb $0x0, (%rax,%r13)
jne 0xc3fc
cmpb $0x1, (%rax,%rbx)
jne 0xc3fc
movq 0x10(%rsp), %rcx
movslq (%rcx), %rax
imulq $0x18, %rax, %rax
movq 0x8(%rcx), %rcx
movq 0x20(%rsp), %rdx
movq -0x18(%rdx,%rax), %rax
cmpl $0x1, 0x1c(%rsp)
jne 0xc307
movq (%rcx,%rbx,8), %rcx
movq (%rcx), %r14
movq (%rax,%rbx,8), %r12
movq %r15, %rdi
movl %ebp, %esi
xorl %edx, %edx
pushq $0x3
popq %rcx
pushq $0x2
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa734
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax,%rbx,8), %rax
movq (%rax), %r14
movq 0x20(%rsp), %rax
movq 0x18(%rax), %rax
movq (%rax,%r13,8), %r12
movq %r15, %rdi
xorl %esi, %esi
movl %ebp, %edx
pushq $0x3
popq %rcx
pushq $0x2
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa5d2
movq 0x10(%rsp), %rcx
movq 0x8(%rcx), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %r14
movslq (%rcx), %rax
movq 0x20(%rsp), %rcx
imulq $0x18, %rax, %rax
movq -0x30(%rcx,%rax), %rax
movq (%rax,%rbx,8), %r12
movq %r15, %rdi
pushq $0x2
popq %rsi
xorl %edx, %edx
movl %ebp, %ecx
pushq $0x3
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa734
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %r14
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13,8), %r12
movq %r15, %rdi
pushq $0x2
popq %rsi
movl %ebp, %edx
xorl %ecx, %ecx
pushq $0x3
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa5d2
jmp 0xc3fc
movq (%rcx,%r13,8), %rcx
movq (%rcx), %r14
movq (%rax,%r13,8), %r12
movq %r15, %rdi
pushq $0x3
popq %rsi
movl %ebp, %edx
xorl %ecx, %ecx
pushq $0x2
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa734
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %r14
movq 0x20(%rsp), %rax
movq 0x18(%rax), %rax
movq (%rax,%rbx,8), %r12
movq %r15, %rdi
pushq $0x3
popq %rsi
xorl %edx, %edx
movl %ebp, %ecx
pushq $0x2
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa5d2
movq 0x10(%rsp), %rcx
movq 0x8(%rcx), %rax
movq (%rax,%rbx,8), %rax
movq (%rax), %r14
movslq (%rcx), %rax
movq 0x20(%rsp), %rcx
imulq $0x18, %rax, %rax
movq -0x30(%rcx,%rax), %rax
movq (%rax,%r13,8), %r12
movq %r15, %rdi
xorl %esi, %esi
movl %ebp, %edx
pushq $0x2
popq %rcx
pushq $0x3
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa734
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax,%rbx,8), %rax
movq (%rax), %r14
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%rbx,8), %r12
movq %r15, %rdi
movl %ebp, %esi
xorl %edx, %edx
pushq $0x2
popq %rcx
pushq $0x3
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa5d2
movq 0x10(%rsp), %rax
movq 0x10(%rax), %rax
cmpb $0x0, (%rax,%r13)
jne 0xc510
cmpb $0x0, (%rax,%rbx)
jne 0xc510
movq 0x10(%rsp), %rcx
movslq (%rcx), %rax
imulq $0x18, %rax, %rax
movq 0x8(%rcx), %rcx
movq (%rcx,%r13,8), %rcx
movq (%rcx), %r14
movq 0x20(%rsp), %rcx
movq -0x18(%rcx,%rax), %rax
cmpl $0x1, 0x1c(%rsp)
jne 0xc4aa
movq (%rax,%rbx,8), %rbx
movq %r15, %rdi
pushq $0x2
popq %rsi
xorl %edx, %edx
movl %ebp, %ecx
pushq $0x3
popq %r8
callq 0x6790
movq %r14, %rdi
movq %rbx, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa734
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13,8), %r14
movq %r15, %rdi
pushq $0x2
popq %rsi
movl %ebp, %edx
xorl %ecx, %ecx
pushq $0x3
popq %r8
callq 0x6790
movq %rbx, %rdi
movq %r14, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa5d2
jmp 0xc510
movq (%rax,%r13,8), %r12
movq %r15, %rdi
pushq $0x3
popq %rsi
movl %ebp, %edx
xorl %ecx, %ecx
pushq $0x2
popq %r8
callq 0x6790
movq %r14, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa734
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %r14
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%rbx,8), %rbx
movq %r15, %rdi
pushq $0x3
popq %rsi
xorl %edx, %edx
movl %ebp, %ecx
pushq $0x2
popq %r8
callq 0x6790
movq %r14, %rdi
movq %rbx, %rsi
movl %ebp, %edx
movq %r15, %rcx
callq 0xa5d2
movq 0x10(%rsp), %rax
movl (%rax), %ecx
movq 0x60(%rsp), %rax
jmp 0xbfd3
leaq 0x20(%rsp), %rdi
callq 0xf0fc
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x3458
jmp 0xc5aa
movq %rax, %rbx
jmp 0xc5aa
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc58e
jmp 0xc593
jmp 0xc58e
jmp 0xc58e
movq %rax, %rbx
movl $0xc0, %esi
movq %r13, %rdi
callq 0x3250
jmp 0xc596
jmp 0xc58e
movq %rax, %rbx
jmp 0xc5a0
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0xf264
leaq 0x20(%rsp), %rdi
callq 0xf0fc
movq %rbx, %rdi
callq 0x33d0