// File: Alcaro[P]bridges/arlib/string.cpp
// Function: string::natcompare3(cstring, cstring, bool)
int string::natcompare3(cstring a, cstring b, bool case_insensitive)
{
	const uint8_t* ab = a.bytes().ptr();
	const uint8_t* bb = b.bytes().ptr();
	const uint8_t* abe = ab + a.length();
	const uint8_t* bbe = bb + b.length();
	
	int ret_zero = 0; // negative = 'a' is first
	int ret_case = 0;
	
	while (ab < abe && bb < bbe)
	{
		if (isdigit(*ab) && isdigit(*bb))
		{
			while (ab < abe && *ab == '0' &&
			       bb < bbe && *bb == '0')
			{
				ab++;
				bb++;
			}
			while (ab < abe && *ab == '0')
			{
				if (!ret_zero) ret_zero = 1;
				ab++;
			}
			while (bb < bbe && *bb == '0')
			{
				if (!ret_zero) ret_zero = -1;
				bb++;
			}
			
			const uint8_t* abs = ab;
			const uint8_t* bbs = bb;
			
			while (ab < abe && isdigit(*ab)) ab++;
			while (bb < bbe && isdigit(*bb)) bb++;
			
			if (ab-abs > bb-bbs) return 1; // a's digit sequence is longer -> a is greater
			if (ab-abs < bb-bbs) return -1;
			// same length - compare char by char (no leading zero, same length, so first difference wins)
			while (abs < ab)
			{
				if (*abs != *bbs) return *abs - *bbs;
				abs++;
				bbs++;
			}
		}
		else
		{
			uint8_t ac = *ab;
			uint8_t bc = *bb;
			if (ac != bc)
			{
				if (ret_case == 0) ret_case = ac - bc;
				if (case_insensitive) ac = toupper(ac);
				if (case_insensitive) bc = toupper(bc);
				if (ac != bc) return ac - bc;
			}
			ab++;
			bb++;
		}
	}
	
	if (bb < bbe) return -1;
	if (ab < abe) return 1;
	
	if (ret_zero) return ret_zero;
	if (ret_case) return ret_case;
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movb %r8b, %al
movq %rdi, -0xf0(%rbp)
movq %rsi, -0xe8(%rbp)
movq %rdx, -0x100(%rbp)
movq %rcx, -0xf8(%rbp)
andb $0x1, %al
movb %al, -0x101(%rbp)
leaq -0xf0(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
leaq -0x78(%rbp), %rcx
movq %rcx, -0x38(%rbp)
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x170(%rbp)
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
cmpl $0x0, %eax
jl 0x3c29e
movq -0x170(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x5cc0
movq -0x170(%rbp), %rsi
movsbl %al, %eax
xorl $0xf, %eax
movzbl %al, %eax
movl %eax, %edx
leaq -0x78(%rbp), %rdi
callq 0x5ed0
jmp 0x3c2b6
movq -0x170(%rbp), %rax
movq (%rax), %rsi
movl 0x8(%rax), %eax
movl %eax, %edx
leaq -0x78(%rbp), %rdi
callq 0x5ed0
movups -0x78(%rbp), %xmm0
movaps %xmm0, -0x60(%rbp)
movq -0x60(%rbp), %rcx
movq -0x58(%rbp), %rax
movq %rcx, -0x120(%rbp)
movq %rax, -0x118(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x62c0
movq %rax, -0x110(%rbp)
leaq -0x100(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
leaq -0xa8(%rbp), %rcx
movq %rcx, -0x18(%rbp)
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x178(%rbp)
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
cmpl $0x0, %eax
jl 0x3c35f
movq -0x178(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rdi
callq 0x5cc0
movq -0x178(%rbp), %rsi
movsbl %al, %eax
xorl $0xf, %eax
movzbl %al, %eax
movl %eax, %edx
leaq -0xa8(%rbp), %rdi
callq 0x5ed0
jmp 0x3c37a
movq -0x178(%rbp), %rax
movq (%rax), %rsi
movl 0x8(%rax), %eax
movl %eax, %edx
leaq -0xa8(%rbp), %rdi
callq 0x5ed0
movups -0xa8(%rbp), %xmm0
movaps %xmm0, -0x90(%rbp)
movq -0x90(%rbp), %rcx
movq -0x88(%rbp), %rax
movq %rcx, -0x138(%rbp)
movq %rax, -0x130(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x62c0
movq %rax, -0x128(%rbp)
movq -0x110(%rbp), %rax
movq %rax, -0x188(%rbp)
leaq -0xf0(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rax
movq %rax, -0x180(%rbp)
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
cmpl $0x0, %eax
jl 0x3c421
movq -0x180(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
xorl $0xf, %eax
movzbl %al, %eax
movl %eax, -0xb4(%rbp)
jmp 0x3c431
movq -0x180(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0xb4(%rbp)
movq -0x188(%rbp), %rax
movl -0xb4(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x140(%rbp)
movq -0x128(%rbp), %rax
movq %rax, -0x198(%rbp)
leaq -0x100(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0x190(%rbp)
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
cmpl $0x0, %eax
jl 0x3c4b2
movq -0x190(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
xorl $0xf, %eax
movzbl %al, %eax
movl %eax, -0xcc(%rbp)
jmp 0x3c4c2
movq -0x190(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0xcc(%rbp)
movq -0x198(%rbp), %rax
movl -0xcc(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x148(%rbp)
movl $0x0, -0x14c(%rbp)
movl $0x0, -0x150(%rbp)
movq -0x110(%rbp), %rcx
xorl %eax, %eax
cmpq -0x140(%rbp), %rcx
movb %al, -0x199(%rbp)
jae 0x3c51c
movq -0x128(%rbp), %rax
cmpq -0x148(%rbp), %rax
setb %al
movb %al, -0x199(%rbp)
movb -0x199(%rbp), %al
testb $0x1, %al
jne 0x3c52b
jmp 0x3c930
movq -0x110(%rbp), %rax
movzbl (%rax), %edi
callq 0x3c9b0
testb $0x1, %al
jne 0x3c543
jmp 0x3c84f
movq -0x128(%rbp), %rax
movzbl (%rax), %edi
callq 0x3c9b0
testb $0x1, %al
jne 0x3c55b
jmp 0x3c84f
jmp 0x3c55d
movq -0x110(%rbp), %rcx
xorl %eax, %eax
cmpq -0x140(%rbp), %rcx
movb %al, -0x19a(%rbp)
jae 0x3c5ba
movq -0x110(%rbp), %rax
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl $0x30, %ecx
movb %al, -0x19a(%rbp)
jne 0x3c5ba
movq -0x128(%rbp), %rcx
xorl %eax, %eax
cmpq -0x148(%rbp), %rcx
movb %al, -0x19a(%rbp)
jae 0x3c5ba
movq -0x128(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x30, %eax
sete %al
movb %al, -0x19a(%rbp)
movb -0x19a(%rbp), %al
testb $0x1, %al
jne 0x3c5c6
jmp 0x3c5ef
movq -0x110(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x110(%rbp)
movq -0x128(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x128(%rbp)
jmp 0x3c55d
jmp 0x3c5f1
movq -0x110(%rbp), %rcx
xorl %eax, %eax
cmpq -0x140(%rbp), %rcx
movb %al, -0x19b(%rbp)
jae 0x3c61f
movq -0x110(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x30, %eax
sete %al
movb %al, -0x19b(%rbp)
movb -0x19b(%rbp), %al
testb $0x1, %al
jne 0x3c62b
jmp 0x3c652
cmpl $0x0, -0x14c(%rbp)
jne 0x3c63e
movl $0x1, -0x14c(%rbp)
movq -0x110(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x110(%rbp)
jmp 0x3c5f1
jmp 0x3c654
movq -0x128(%rbp), %rcx
xorl %eax, %eax
cmpq -0x148(%rbp), %rcx
movb %al, -0x19c(%rbp)
jae 0x3c682
movq -0x128(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x30, %eax
sete %al
movb %al, -0x19c(%rbp)
movb -0x19c(%rbp), %al
testb $0x1, %al
jne 0x3c68e
jmp 0x3c6b5
cmpl $0x0, -0x14c(%rbp)
jne 0x3c6a1
movl $0xffffffff, -0x14c(%rbp) # imm = 0xFFFFFFFF
movq -0x128(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x128(%rbp)
jmp 0x3c654
movq -0x110(%rbp), %rax
movq %rax, -0x158(%rbp)
movq -0x128(%rbp), %rax
movq %rax, -0x160(%rbp)
movq -0x110(%rbp), %rcx
xorl %eax, %eax
cmpq -0x140(%rbp), %rcx
movb %al, -0x19d(%rbp)
jae 0x3c6fe
movq -0x110(%rbp), %rax
movzbl (%rax), %edi
callq 0x3c9b0
movb %al, -0x19d(%rbp)
movb -0x19d(%rbp), %al
testb $0x1, %al
jne 0x3c70a
jmp 0x3c71e
movq -0x110(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x110(%rbp)
jmp 0x3c6d1
jmp 0x3c720
movq -0x128(%rbp), %rcx
xorl %eax, %eax
cmpq -0x148(%rbp), %rcx
movb %al, -0x19e(%rbp)
jae 0x3c74d
movq -0x128(%rbp), %rax
movzbl (%rax), %edi
callq 0x3c9b0
movb %al, -0x19e(%rbp)
movb -0x19e(%rbp), %al
testb $0x1, %al
jne 0x3c759
jmp 0x3c76d
movq -0x128(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x128(%rbp)
jmp 0x3c720
movq -0x110(%rbp), %rax
movq -0x158(%rbp), %rcx
subq %rcx, %rax
movq -0x128(%rbp), %rcx
movq -0x160(%rbp), %rdx
subq %rdx, %rcx
cmpq %rcx, %rax
jle 0x3c7a3
movl $0x1, -0xdc(%rbp)
jmp 0x3c9a0
movq -0x110(%rbp), %rax
movq -0x158(%rbp), %rcx
subq %rcx, %rax
movq -0x128(%rbp), %rcx
movq -0x160(%rbp), %rdx
subq %rdx, %rcx
cmpq %rcx, %rax
jge 0x3c7d9
movl $0xffffffff, -0xdc(%rbp) # imm = 0xFFFFFFFF
jmp 0x3c9a0
jmp 0x3c7db
movq -0x158(%rbp), %rax
cmpq -0x110(%rbp), %rax
jae 0x3c84a
movq -0x158(%rbp), %rax
movzbl (%rax), %eax
movq -0x160(%rbp), %rcx
movzbl (%rcx), %ecx
cmpl %ecx, %eax
je 0x3c824
movq -0x158(%rbp), %rax
movzbl (%rax), %eax
movq -0x160(%rbp), %rcx
movzbl (%rcx), %ecx
subl %ecx, %eax
movl %eax, -0xdc(%rbp)
jmp 0x3c9a0
movq -0x158(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x158(%rbp)
movq -0x160(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x160(%rbp)
jmp 0x3c7db
jmp 0x3c92b
movq -0x110(%rbp), %rax
movb (%rax), %al
movb %al, -0x161(%rbp)
movq -0x128(%rbp), %rax
movb (%rax), %al
movb %al, -0x162(%rbp)
movzbl -0x161(%rbp), %eax
movzbl -0x162(%rbp), %ecx
cmpl %ecx, %eax
je 0x3c907
cmpl $0x0, -0x150(%rbp)
jne 0x3c8a2
movzbl -0x161(%rbp), %eax
movzbl -0x162(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x150(%rbp)
testb $0x1, -0x101(%rbp)
je 0x3c8bd
movzbl -0x161(%rbp), %edi
callq 0x3c1d0
movb %al, -0x161(%rbp)
testb $0x1, -0x101(%rbp)
je 0x3c8d8
movzbl -0x162(%rbp), %edi
callq 0x3c1d0
movb %al, -0x162(%rbp)
movzbl -0x161(%rbp), %eax
movzbl -0x162(%rbp), %ecx
cmpl %ecx, %eax
je 0x3c905
movzbl -0x161(%rbp), %eax
movzbl -0x162(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0xdc(%rbp)
jmp 0x3c9a0
jmp 0x3c907
movq -0x110(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x110(%rbp)
movq -0x128(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x128(%rbp)
jmp 0x3c4ed
movq -0x128(%rbp), %rax
cmpq -0x148(%rbp), %rax
jae 0x3c94c
movl $0xffffffff, -0xdc(%rbp) # imm = 0xFFFFFFFF
jmp 0x3c9a0
movq -0x110(%rbp), %rax
cmpq -0x140(%rbp), %rax
jae 0x3c968
movl $0x1, -0xdc(%rbp)
jmp 0x3c9a0
cmpl $0x0, -0x14c(%rbp)
je 0x3c97f
movl -0x14c(%rbp), %eax
movl %eax, -0xdc(%rbp)
jmp 0x3c9a0
cmpl $0x0, -0x150(%rbp)
je 0x3c996
movl -0x150(%rbp), %eax
movl %eax, -0xdc(%rbp)
jmp 0x3c9a0
movl $0x0, -0xdc(%rbp)
movl -0xdc(%rbp), %eax
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
nop