// File: /workspace/github_c_makefile_star2_O1/martincameron[P]towntalk/optimizer.c
// Function: compile_arithmetic_expression
static struct instruction* compile_arithmetic_expression( struct arithmetic_statement *stmt, struct expression *expr, int top, char *message ) {
	struct instruction *insn;
	struct expression *parameter;
	enum arithmetic_op oper = get_arithmetic_op( expr );
	if( top > 6 ) {
		insn = add_instruction( &stmt->insns, PUSH_EXPR, 0, expr, message );
	} else if( oper ) {
		parameter = expr->parameters;
		insn = compile_arithmetic_expression( stmt, parameter, top, message );
		while( insn && parameter->next ) {
			parameter = parameter->next;
			insn = compile_arithmetic_expression( stmt, parameter, top + 1, message );
			if( insn ) {
				if( insn->oper == PUSH_CONST ) {
					insn->oper = oper + AND_CONST - AND_STACK;
				} else if( insn->oper == PUSH_LOCAL ) {
					insn->oper = oper + AND_LOCAL - AND_STACK;
				} else {
					insn = add_instruction( &stmt->insns, oper, 0, parameter, message );
				}
			}
		}
	} else if( expr->evaluate == evaluate_number_literal_expression ) {
		insn = add_instruction( &stmt->insns, PUSH_CONST, expr->index, expr, message );
		if( insn ) {
			insn->value = ( ( struct value_expression * ) expr )->num;
		}
	} else if( expr->evaluate == evaluate_local ) {
		insn = add_instruction( &stmt->insns, PUSH_LOCAL, expr->index, expr, message );
	} else if( expr->evaluate == evaluate_local_post_inc ) {
		insn = add_instruction( &stmt->insns, PUSH_LOCAL_PI, expr->index, expr, message );
	} else if( expr->evaluate == evaluate_local_post_dec ) {
		insn = add_instruction( &stmt->insns, PUSH_LOCAL_PD, expr->index, expr, message );
	} else if( expr->evaluate == evaluate_index_expression && expr->parameters->evaluate == evaluate_local ) {
		insn = compile_arithmetic_expression( stmt, expr->parameters->next, top, message );
		if( insn ) {
			insn = add_instruction( &stmt->insns, PUSH_ARRAY, expr->parameters->index, expr, message );
		}
	} else if( expr->evaluate == evaluate_chr_expression && expr->parameters->evaluate == evaluate_local ) {
		insn = compile_arithmetic_expression( stmt, expr->parameters->next, top, message );
		if( insn ) {
			insn = add_instruction( &stmt->insns, PUSH_STRING, expr->parameters->index, expr, message );
		}
	} else if( expr->evaluate == evaluate_unpack_expression && expr->parameters->evaluate == evaluate_global ) {
		insn = compile_arithmetic_expression( stmt, expr->parameters->next, top, message );
		if( insn ) {
			insn = add_instruction( &stmt->insns, PUSH_UNPACK, 0, expr->parameters, message );
		}
	} else if( expr->evaluate == evaluate_global ) {
		insn = add_instruction( &stmt->insns, PUSH_GLOBAL, 0, expr, message );
	} else {
		insn = add_instruction( &stmt->insns, PUSH_EXPR, 0, expr, message );
	}
	return insn;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %rbx
movl %edx, %ebp
movq %rsi, %r15
movq %rdi, %r14
movq 0x18(%rsi), %r13
xorl %r12d, %r12d
cmpq 0x9d22(%rip), %r13      # 0x18fd0
jne 0xf2d9
movl 0x4(%r15), %esi
leaq 0x3f8d(%rip), %rdi      # 0x13248
movl $0xc, %edx
callq 0x3110
testq %rax, %rax
je 0xf2d9
leaq 0x3f77(%rip), %rcx      # 0x13248
subl %ecx, %eax
addl $0x17, %eax
movl %eax, %r12d
cmpl $0x7, %ebp
jl 0xf305
addq $0x28, %r14
movq %r14, %rdi
movl $0xb, %esi
xorl %edx, %edx
movq %r15, %rcx
movq %rbx, %r8
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xf560
testl %r12d, %r12d
je 0xf3ab
movq 0x8(%r15), %r15
movq %r14, %rdi
movq %r15, %rsi
movl %ebp, %edx
movq %rbx, %rcx
callq 0xf28a
testq %rax, %rax
je 0xf54f
movq 0x10(%r15), %r15
testq %r15, %r15
je 0xf551
incl %ebp
leal 0x16(%r12), %eax
movl %eax, 0x4(%rsp)
leal 0xb(%r12), %eax
movl %eax, (%rsp)
leaq 0x28(%r14), %r13
movq %r14, %rdi
movq %r15, %rsi
movl %ebp, %edx
movq %rbx, %rcx
callq 0xf28a
testq %rax, %rax
je 0xf375
movl (%rax), %ecx
cmpl $0x2, %ecx
je 0xf379
cmpl $0x1, %ecx
jne 0xf381
movl (%rsp), %ecx
jmp 0xf37d
xorl %eax, %eax
jmp 0xf394
movl 0x4(%rsp), %ecx
movl %ecx, (%rax)
jmp 0xf394
movq %r13, %rdi
movl %r12d, %esi
xorl %edx, %edx
movq %r15, %rcx
movq %rbx, %r8
callq 0xf560
testq %rax, %rax
je 0xf54f
movq 0x10(%r15), %r15
testq %r15, %r15
jne 0xf34f
jmp 0xf551
cmpq 0x9c0e(%rip), %r13      # 0x18fc0
je 0xf457
cmpq 0x9be9(%rip), %r13      # 0x18fa8
je 0xf487
cmpq 0x9bc4(%rip), %r13      # 0x18f90
je 0xf49c
cmpq 0x9ba7(%rip), %r13      # 0x18f80
je 0xf4b1
cmpq 0x9c0a(%rip), %r13      # 0x18ff0
jne 0xf3fd
movq 0x8(%r15), %rax
movq 0x18(%rax), %rcx
cmpq 0x9bb1(%rip), %rcx      # 0x18fa8
je 0xf4c6
cmpq 0x9b84(%rip), %r13      # 0x18f88
jne 0xf41b
movq 0x8(%r15), %rax
movq 0x18(%rax), %rcx
cmpq 0x9b93(%rip), %rcx      # 0x18fa8
je 0xf4f4
cmpq 0x9b56(%rip), %r13      # 0x18f78
jne 0xf439
movq 0x8(%r15), %rax
movq 0x18(%rax), %rcx
cmpq 0x9b95(%rip), %rcx      # 0x18fc8
je 0xf522
addq $0x28, %r14
cmpq 0x9b84(%rip), %r13      # 0x18fc8
jne 0xf2e2
movq %r14, %rdi
movl $0x4, %esi
jmp 0xf2ea
addq $0x28, %r14
movl 0x4(%r15), %edx
movq %r14, %rdi
movl $0x1, %esi
movq %r15, %rcx
movq %rbx, %r8
callq 0xf560
testq %rax, %rax
je 0xf54f
movl 0x28(%r15), %ecx
movl %ecx, 0x10(%rax)
jmp 0xf551
addq $0x28, %r14
movl 0x4(%r15), %edx
movq %r14, %rdi
movl $0x2, %esi
jmp 0xf2ec
addq $0x28, %r14
movl 0x4(%r15), %edx
movq %r14, %rdi
movl $0x7, %esi
jmp 0xf2ec
addq $0x28, %r14
movl 0x4(%r15), %edx
movq %r14, %rdi
movl $0x9, %esi
jmp 0xf2ec
movq 0x10(%rax), %rsi
movq %r14, %rdi
movl %ebp, %edx
movq %rbx, %rcx
callq 0xf28a
testq %rax, %rax
je 0xf54f
addq $0x28, %r14
movq 0x8(%r15), %rax
movl 0x4(%rax), %edx
movq %r14, %rdi
movl $0xd, %esi
jmp 0xf2ec
movq 0x10(%rax), %rsi
movq %r14, %rdi
movl %ebp, %edx
movq %rbx, %rcx
callq 0xf28a
testq %rax, %rax
je 0xf54f
addq $0x28, %r14
movq 0x8(%r15), %rax
movl 0x4(%rax), %edx
movq %r14, %rdi
movl $0xf, %esi
jmp 0xf2ec
movq 0x10(%rax), %rsi
movq %r14, %rdi
movl %ebp, %edx
movq %rbx, %rcx
callq 0xf28a
testq %rax, %rax
je 0xf54f
addq $0x28, %r14
movq 0x8(%r15), %rcx
movq %r14, %rdi
movl $0x10, %esi
xorl %edx, %edx
jmp 0xf2ef
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq