// File: /workspace/github_cpp_makefile_star2_O1/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 0x7bf1(%rip), %rsi      # 0x1768a
leaq 0x7bef(%rip), %rdx      # 0x1768f
leaq 0x78(%rsp), %rbx
movq %rbx, %rdi
callq 0x86fe
movq %rbx, %rdi
movl $0x2, %esi
callq 0x4209
movq 0x78(%rsp), %rdi
cmpq %r15, %rdi
je 0xfad4
movq 0x88(%rsp), %rsi
incq %rsi
callq 0x3220
movq 0x8(%r14), %rax
movq (%rax), %rcx
movq 0x38(%rcx), %r15
movslq (%r14), %rcx
testq %rcx, %rcx
jle 0xfaf9
xorl %edx, %edx
movq (%rax,%rdx,8), %rsi
movb $0x0, 0x32(%rsi)
incq %rdx
cmpq %rdx, %rcx
jne 0xfae9
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
cmpl $0x0, (%r14)
movq %r14, 0x38(%rsp)
jle 0xfbc6
xorl %ebp, %ebp
leaq 0x40(%rsp), %r12
leaq 0x70(%rsp), %r13
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
cmpl $0x0, (%r14)
jle 0xfb92
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 0xdc7c
movq %rbx, 0x70(%rsp)
movq %r12, %rdi
movq %r13, %rsi
callq 0x13b18
incl %r14d
movq 0x38(%rsp), %rax
cmpl (%rax), %r14d
jl 0xfb3f
leaq 0x20(%rsp), %rdi
movq %r12, %rsi
callq 0x13a4e
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
movq 0x38(%rsp), %r14
je 0xfbbb
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x3220
incl %ebp
cmpl (%r14), %ebp
jl 0xfb25
cmpl $0x0, (%r14)
jle 0xfd02
xorl %ebp, %ebp
leaq 0x40(%rsp), %r15
movl (%r14), %eax
cmpl $0x2, %eax
jl 0xfc46
xorl %r14d, %r14d
xorl %r13d, %r13d
movq 0x20(%rsp), %rax
movq (%rax,%r14), %rcx
movq 0x18(%rax,%r14), %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 0x8630
movq %rbx, %rdi
movq %r12, %rsi
movl $0x2, %edx
movq %r15, %rcx
callq 0xde78
incq %r13
movq 0x38(%rsp), %rax
movslq (%rax), %rax
decq %rax
addq $0x18, %r14
cmpq %rax, %r13
jl 0xfbe5
movq 0x38(%rsp), %r14
jmp 0xfc48
decl %eax
movq 0x8(%r14), %rcx
movq (%rcx,%rbp,8), %rcx
movq 0x18(%rcx), %r12
cltq
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 0x8630
movq %r12, %rdi
movq %r13, %rsi
movl $0x2, %edx
movq %r15, %rcx
callq 0xe02c
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 0x8630
movq %r12, %rdi
movq %rbx, %rsi
movl $0x2, %edx
movq %r15, %rcx
callq 0xde78
incq %rbp
movslq (%r14), %rax
cmpq %rax, %rbp
jl 0xfbd7
movl (%r14), %ecx
testl %ecx, %ecx
jle 0x102d3
xorl %r12d, %r12d
leaq 0x1(%r12), %rax
movq %rax, 0x68(%rsp)
cltd
idivl %ecx
movq 0x10(%r14), %rax
movq %r12, 0x60(%rsp)
movzbl (%rax,%r12), %esi
movq %rdx, %r12
xorl $0x1, %esi
movzbl (%rax,%rdx), %eax
addl %esi, %eax
movl %eax, %edx
movl 0x1c(%rsp), %esi
imull %esi, %edx
cmpl $0x1, %esi
movl $0x0, %edi
cmovnel %edi, %eax
movl %edx, %esi
cmovel %edi, %esi
addl %ecx, %esi
cmpl %esi, %eax
movq %r12, 0x10(%rsp)
jge 0xfdd6
movl %eax, %ecx
movslq %edx, %rdx
movl %esi, %r15d
subq %rcx, %r15
shlq $0x3, %rdx
leaq (%rdx,%rdx,2), %r13
negq %r13
shll $0x3, %eax
leaq (%rax,%rax,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 (%rax,%r12,8), %rbp
leaq 0x40(%rsp), %r12
movq %r12, %rdi
movl $0x1, %esi
xorl %edx, %edx
movl $0x2, %ecx
movl $0x3, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0xde78
addq $0x18, %r14
decq %r15
movq 0x10(%rsp), %r12
jne 0xfd78
movq 0x38(%rsp), %r14
movq 0x10(%r14), %rax
movq 0x60(%rsp), %r13
cmpb $0x1, (%rax,%r13)
leaq 0x40(%rsp), %r15
jne 0xff0e
cmpb $0x1, (%rax,%r12)
jne 0xff0e
movq 0x8(%r14), %rax
movq (%rax,%r12,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 0xfe99
movq (%rax,%r12,8), %rbx
movq %r15, %rdi
movl $0x1, %esi
xorl %edx, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x8630
movq %rbp, %rdi
movq %rbx, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xe02c
movq 0x8(%r14), %rax
movq (%rax,%r12,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13,8), %rbp
movq %r15, %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xde78
jmp 0xff0e
movq (%rax,%r13,8), %rbx
movq %r15, %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x2, %ecx
movl $0x3, %r8d
callq 0x8630
movq %rbp, %rdi
movq %rbx, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xe02c
movq 0x8(%r14), %rax
movq (%rax,%r12,8), %rax
movq (%rax), %rbx
movq 0x20(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r12,8), %rbp
movq %r15, %rdi
movl $0x1, %esi
xorl %edx, %edx
movl $0x2, %ecx
movl $0x3, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xde78
movq 0x10(%r14), %rax
cmpb $0x0, (%rax,%r13)
movq 0x68(%rsp), %r12
jne 0x10190
movq 0x10(%rsp), %rcx
cmpb $0x1, (%rax,%rcx)
jne 0x10190
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 0x10073
movq 0x10(%rsp), %rdx
movq (%rax,%rdx,8), %rax
movq (%rax), %rbx
movq (%rcx,%rdx,8), %rbp
movq %r15, %rdi
movl $0x1, %esi
xorl %edx, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xe02c
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 %r15, %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x3, %ecx
movl $0x2, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xde78
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 %r15, %rdi
movl $0x2, %esi
xorl %edx, %edx
movl $0x1, %ecx
movl $0x3, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xe02c
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 %r15, %rdi
movl $0x2, %esi
movl $0x1, %edx
xorl %ecx, %ecx
movl $0x3, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xde78
jmp 0x10190
movq (%rax,%r13,8), %rax
movq (%rax), %rbx
movq (%rcx,%r13,8), %rbp
movq %r15, %rdi
movl $0x3, %esi
movl $0x1, %edx
xorl %ecx, %ecx
movl $0x2, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xe02c
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 %r15, %rdi
movl $0x3, %esi
xorl %edx, %edx
movl $0x1, %ecx
movl $0x2, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xde78
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 %r15, %rdi
xorl %esi, %esi
movl $0x1, %edx
movl $0x2, %ecx
movl $0x3, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xe02c
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 %r15, %rdi
movl $0x1, %esi
xorl %edx, %edx
movl $0x2, %ecx
movl $0x3, %r8d
callq 0x8630
movq %rbx, %rdi
movq %rbp, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xde78
movq 0x10(%r14), %rax
cmpb $0x0, (%rax,%r13)
jne 0x102c7
movq 0x10(%rsp), %rcx
cmpb $0x0, (%rax,%rcx)
jne 0x102c7
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 0x1024d
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rbx
movq %r15, %rdi
movl $0x2, %esi
xorl %edx, %edx
movl $0x1, %ecx
movl $0x3, %r8d
callq 0x8630
movq %rbp, %rdi
movq %rbx, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xe02c
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 %r15, %rdi
movl $0x2, %esi
movl $0x1, %edx
xorl %ecx, %ecx
movl $0x3, %r8d
callq 0x8630
movq %rbx, %rdi
movq %r13, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xde78
jmp 0x102c7
movq (%rax,%r13,8), %rbx
movq %r15, %rdi
movl $0x3, %esi
movl $0x1, %edx
xorl %ecx, %ecx
movl $0x2, %r8d
callq 0x8630
movq %rbp, %rdi
movq %rbx, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xe02c
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 %r15, %rdi
movl $0x3, %esi
xorl %edx, %edx
movl $0x1, %ecx
movl $0x2, %r8d
callq 0x8630
movq %rbx, %rdi
movq %r13, %rsi
movl $0x1, %edx
movq %r15, %rcx
callq 0xde78
movslq (%r14), %rcx
cmpq %rcx, %r12
jl 0xfd10
leaq 0x20(%rsp), %rdi
callq 0x13a7a
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 0x10371
movq 0x88(%rsp), %rsi
incq %rsi
callq 0x3220
jmp 0x10371
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x10348
jmp 0x1034d
jmp 0x10348
jmp 0x10348
movq %rax, %r14
movl $0xc0, %esi
movq %rbx, %rdi
callq 0x3220
jmp 0x10350
jmp 0x10348
movq %rax, %r14
jmp 0x10367
movq %rax, %r14
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x10367
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x3220
leaq 0x20(%rsp), %rdi
callq 0x13a7a
movq %r14, %rdi
callq 0x33e0
nop