// File: rossy[P]crossc/SPIRV-Cross/spirv_glsl.cpp
// Function: spirv_cross::CompilerGLSL::optimize_read_modify_write(spirv_cross::SPIRType const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
bool CompilerGLSL::optimize_read_modify_write(const SPIRType &type, const string &lhs, const string &rhs)
{
	// Do this with strings because we have a very clear pattern we can check for and it avoids
	// adding lots of special cases to the code emission.
	if (rhs.size() < lhs.size() + 3)
		return false;

	// Do not optimize matrices. They are a bit awkward to reason about in general
	// (in which order does operation happen?), and it does not work on MSL anyways.
	if (type.vecsize > 1 && type.columns > 1)
		return false;

	auto index = rhs.find(lhs);
	if (index != 0)
		return false;

	// TODO: Shift operators, but it's not important for now.
	auto op = rhs.find_first_of("+-/*%|&^", lhs.size() + 1);
	if (op != lhs.size() + 1)
		return false;

	// Check that the op is followed by space. This excludes && and ||.
	if (rhs[op + 1] != ' ')
		return false;

	char bop = rhs[op];
	auto expr = rhs.substr(lhs.size() + 3);
	// Try to find increments and decrements. Makes it look neater as += 1, -= 1 is fairly rare to see in real code.
	// Find some common patterns which are equivalent.
	if ((bop == '+' || bop == '-') && (expr == "1" || expr == "uint(1)" || expr == "1u" || expr == "int(1u)"))
		statement(lhs, bop, bop, ";");
	else
		statement(lhs, " ", bop, "= ", expr, ";");
	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7290
movq %rax, -0x78(%rbp)
movq -0x20(%rbp), %rdi
callq 0x7290
movq %rax, %rcx
movq -0x78(%rbp), %rax
addq $0x3, %rcx
cmpq %rcx, %rax
jae 0x88f92
movb $0x0, -0x1(%rbp)
jmp 0x891b9
movq -0x18(%rbp), %rax
cmpl $0x1, 0x14(%rax)
jbe 0x88faf
movq -0x18(%rbp), %rax
cmpl $0x1, 0x18(%rax)
jbe 0x88faf
movb $0x0, -0x1(%rbp)
jmp 0x891b9
movq -0x28(%rbp), %rdi
movq -0x20(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x76e0
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x88fd4
movb $0x0, -0x1(%rbp)
jmp 0x891b9
movq -0x28(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x20(%rbp), %rdi
callq 0x7290
movq -0x90(%rbp), %rdi
movq %rax, %rdx
addq $0x1, %rdx
leaq 0xbb13e(%rip), %rsi     # 0x14413b
callq 0x71b0
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x20(%rbp), %rdi
callq 0x7290
movq %rax, %rcx
movq -0x88(%rbp), %rax
addq $0x1, %rcx
cmpq %rcx, %rax
je 0x89036
movb $0x0, -0x1(%rbp)
jmp 0x891b9
movq -0x28(%rbp), %rdi
movq -0x38(%rbp), %rsi
addq $0x1, %rsi
callq 0x73e0
movsbl (%rax), %eax
cmpl $0x20, %eax
je 0x89058
movb $0x0, -0x1(%rbp)
jmp 0x891b9
movq -0x28(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x73e0
movb (%rax), %al
movb %al, -0x39(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x20(%rbp), %rdi
callq 0x7290
movq -0x98(%rbp), %rsi
movq %rax, %rdx
addq $0x3, %rdx
leaq -0x60(%rbp), %rdi
movq $-0x1, %rcx
callq 0x73a0
movsbl -0x39(%rbp), %eax
cmpl $0x2b, %eax
je 0x890b2
movsbl -0x39(%rbp), %eax
cmpl $0x2d, %eax
jne 0x89178
leaq 0xbb29f(%rip), %rsi     # 0x144358
leaq -0x60(%rbp), %rdi
callq 0x2f7c0
movb %al, -0x99(%rbp)
jmp 0x890ca
movb -0x99(%rbp), %al
testb $0x1, %al
jne 0x89142
jmp 0x890d6
leaq 0xbb067(%rip), %rsi     # 0x144144
leaq -0x60(%rbp), %rdi
callq 0x2f7c0
movb %al, -0x9a(%rbp)
jmp 0x890ee
movb -0x9a(%rbp), %al
testb $0x1, %al
jne 0x89142
jmp 0x890fa
leaq 0xbb04b(%rip), %rsi     # 0x14414c
leaq -0x60(%rbp), %rdi
callq 0x2f7c0
movb %al, -0x9b(%rbp)
jmp 0x89112
movb -0x9b(%rbp), %al
testb $0x1, %al
jne 0x89142
jmp 0x8911e
leaq 0xbb02a(%rip), %rsi     # 0x14414f
leaq -0x60(%rbp), %rdi
callq 0x2f7c0
movb %al, -0x9c(%rbp)
jmp 0x89136
movb -0x9c(%rbp), %al
testb $0x1, %al
jne 0x89142
jmp 0x89178
movq -0x80(%rbp), %rdi
movq -0x20(%rbp), %rsi
leaq 0xbff55(%rip), %r8      # 0x1490a6
leaq -0x39(%rbp), %rcx
movq %rcx, %rdx
callq 0xa4a10
jmp 0x8915f
jmp 0x891ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x7708
jmp 0x891c7
movq -0x80(%rbp), %rdi
movq -0x20(%rbp), %rsi
leaq 0xbff1f(%rip), %rcx     # 0x1490a6
movq %rsp, %rax
movq %rcx, (%rax)
leaq 0xb5709(%rip), %rdx     # 0x13e89d
leaq 0xbfe75(%rip), %r8      # 0x149010
leaq -0x39(%rbp), %rcx
leaq -0x60(%rbp), %r9
callq 0xa4b50
jmp 0x891aa
jmp 0x891ac
movb $0x1, -0x1(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x7708
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xb0, %rsp
popq %rbp
retq
movq -0x68(%rbp), %rdi
callq 0x7640