// File: /workspace/github_cpp_makefile_star2_O3/lhartmann[P]orangepi-i2s-steppers/cnt.cpp
// Function: step()
uint32_t step() {
	uint32_t out = 0;
	
	// If motion has completed, prepare new move
	bool done = throttle.done();
	for (int s=0; s<NUM_STEPPERS; ++s) done = done && stepper[s].done();
	
	if (done) {
		// Reverse direction
		if (++forward == 16) forward = 0;
		
		// Move Duration (samples), considering max-speed.
		// Beware of this expression, RATE*MOVE may overflow.
		uint32_t duration = RATE * 1. * MOVE/MAXSPD;
		
		// Prepare the speed controllers
		for (int s=0; s<NUM_STEPPERS; ++s)
			stepper[s].prepare(MOVE/(s+1), duration);
		
		// Prepare the acceleration controller
		throttle.prepare(duration, ACCEL, ACCEL/100, ACCEL/100);
	}
	
	// Render movement
	out += forward*DIR_MASK;
	if (throttle.step()) {
		for (int s=0; s<NUM_STEPPERS; ++s) {
			if (stepper[s].step()) {
				out |= STEP_MASK<<s;
			}
		}
	}
	
	// Encode for I2S output:
	//   Apply selective transport delay (31 LSBs delayed by 1 clock)
	out = td(out);
	//   Fix word clock phase by shifting bits around.
	//   Hardware will delay 1 MSB by 1 clock, resyncing the word.
	out = (out<<1) | (out>>31); 
	
	return out;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movl 0x2ee8(%rip), %eax      # 0x4030
cmpl 0x2eea(%rip), %eax      # 0x4038
sete %dl
xorl %eax, %eax
leaq 0x2f36(%rip), %rcx      # 0x4090
testb $0x1, %dl
je 0x117a
leaq (%rax,%rax,4), %rdx
movl (%rcx,%rdx,4), %esi
movl 0x4(%rcx,%rdx,4), %edi
cmpl %edi, %esi
sete %dl
incq %rax
cmpq $0x4, %rax
jne 0x115a
jmp 0x1190
incq %rax
xorl %edx, %edx
cmpq $0x4, %rax
jne 0x115a
movl 0x2ef5(%rip), %ebx      # 0x4080
jmp 0x1223
movl 0x2eea(%rip), %ebx      # 0x4080
cmpl %edi, %esi
jne 0x1223
incl %ebx
xorl %eax, %eax
cmpl $0x10, %ebx
cmovel %eax, %ebx
movl %ebx, 0x2ed2(%rip)      # 0x4080
movl $0x10, %esi
movl $0x1, %edi
movabsq $-0x752fffff15a00, %r8  # imm = 0xFFF8AD00000EA600
movl $0x27100, %eax          # imm = 0x27100
xorl %edx, %edx
divl %edi
movl $0x0, -0x10(%rsi,%rcx)
movl %eax, -0xc(%rsi,%rcx)
movl %eax, -0x8(%rsi,%rcx)
movq %r8, -0x4(%rsi,%rcx)
addq $0x14, %rsi
incl %edi
cmpq $0x60, %rsi
jne 0x11c2
movabsq $0xbb81300000000, %rax  # imm = 0xBB81300000000
movq %rax, 0x2e33(%rip)      # 0x4030
movaps 0xe0c(%rip), %xmm0      # 0x2010
movups %xmm0, 0x2e2d(%rip)     # 0x4038
movb $0x0, 0x2e3e(%rip)      # 0x4050
movabsq $-0xefffffff100, %rax   # imm = 0xFFFFF10000000F00
movq %rax, 0x2e25(%rip)      # 0x4048
shll $0x10, %ebx
leaq 0x2e03(%rip), %rdi      # 0x4030
callq 0x1312
testb %al, %al
je 0x128c
leaq 0x2e63(%rip), %rax      # 0x40a0
xorl %edx, %edx
xorps %xmm0, %xmm0
xorl %ecx, %ecx
movl (%rax), %esi
addl -0x8(%rax), %esi
movl %esi, (%rax)
testl %esi, %esi
jle 0x1271
movl %esi, %edi
subl -0x4(%rax), %edi
movl %edi, (%rax)
movl -0x10(%rax), %edi
incl %edi
movl %edi, -0x10(%rax)
cmpl -0xc(%rax), %edi
jne 0x1271
leaq -0x10(%rax), %rdi
movups %xmm0, (%rdi)
movl $0x0, 0x10(%rdi)
movl $0x1, %edi
shll %cl, %edi
testl %esi, %esi
cmovlel %edx, %edi
orl %edi, %ebx
incq %rcx
addq $0x14, %rax
cmpq $0x4, %rcx
jne 0x1244
movq 0x2dcd(%rip), %rcx      # 0x4060
leaq 0x2dbe(%rip), %rax      # 0x4058
cmpq %rax, %rcx
je 0x12ad
addq $-0x4, %rcx
movq %rcx, 0x2db6(%rip)      # 0x4060
movq %rcx, %rax
movl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
andl (%rax), %ecx
movl %ebx, (%rax)
andl $0x80000000, %ebx       # imm = 0x80000000
orl %ecx, %ebx
roll %ebx
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq