// File: /workspace/github_c_makefile_star2_O2/been-jamming[P]MinimalCC/expression.c
// Function: compile_operation
void compile_operation(value *first_value, value *next_value, operation op, FILE *output_file){
	char reg0_str_buffer[5] = {0, 0, 0, 0, 0};
	char reg1_str_buffer[5] = {0, 0, 0, 0, 0};
	char *reg0_str = "";
	char *reg1_str = "";
	type output_type;

	if(types_equal(&(first_value->data_type), &VOID_TYPE) || types_equal(&(next_value->data_type), &VOID_TYPE)){
		snprintf(error_message, sizeof(error_message), "Can't operate on void value");
		do_error(1);
	}

	if(first_value->data.type == data_register){
		snprintf(reg0_str_buffer, sizeof(reg0_str_buffer)/sizeof(char), "$s%d", first_value->data.reg);
		reg0_str = reg0_str_buffer;
	} else if(first_value->data.type == data_stack){
		reg0_str = "$t0";
		if(type_size(&(first_value->data_type), 0) == 4){
			fileprint(output_file, "lw $t0, %d($sp)\n", get_stack_pos(first_value->data));
		} else if(type_size(&(first_value->data_type), 0) == 1){
			fileprint(output_file, "lb $t0, %d($sp)\n", get_stack_pos(first_value->data));
		} else {
			snprintf(error_message, sizeof(error_message), "[INTERNAL] Unusable type size %d", type_size(&(first_value->data_type), 0));
			do_error(1);
		}
	}
	if(next_value->data.type == data_register){
		snprintf(reg1_str_buffer, sizeof(reg1_str_buffer)/sizeof(char), "$s%d", next_value->data.reg);
		reg1_str = reg1_str_buffer;
	} else if(next_value->data.type == data_stack){
		reg1_str = "$t1";
		if(type_size(&(next_value->data_type), 0) == 4){
			fileprint(output_file, "lw $t1, %d($sp)\n", get_stack_pos(next_value->data));
		} else if(type_size(&(next_value->data_type), 0) == 1){
			fileprint(output_file, "lb $t1, %d($sp)\n", get_stack_pos(next_value->data));
		} else {
			snprintf(error_message, sizeof(error_message), "[INTERNAL] Unusable type size %d", type_size(&(next_value->data_type), 0));
			do_error(1);
		}
	}
	operation_functions[op](reg0_str, reg1_str, first_value, next_value, output_file, &output_type);
	deallocate(next_value->data);
	if(first_value->data.type == data_stack){
		if(type_size(&output_type, 0) == 4){
			fileprint(output_file, "sw $t0, %d($sp)\n", get_stack_pos(first_value->data));
		} else if(type_size(&output_type, 0) == 1){
			fileprint(output_file, "sb $t0, %d($sp)\n", get_stack_pos(first_value->data));
		} else {
			snprintf(error_message, sizeof(error_message), "[INTERNAL] Unusable type size %d", type_size(&output_type, 0));
			do_error(1);
		}
	}
	first_value->data_type = output_type;
	first_value->is_reference = 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rcx, (%rsp)
movl %edx, %r15d
movq %rsi, %r12
movq %rdi, %rbx
xorl %eax, %eax
movb %al, 0x14(%rsp)
andl $0x0, 0x10(%rsp)
movb %al, 0xc(%rsp)
andl $0x0, 0x8(%rsp)
leaq 0x10(%rdi), %r14
leaq 0x73ae(%rip), %rsi      # 0xc1c0
movq %r14, %rdi
callq 0x7653
testb %al, %al
jne 0x4e33
leaq 0x10(%r12), %rdi
leaq 0x7396(%rip), %rsi      # 0xc1c0
callq 0x7653
testb %al, %al
je 0x4e57
movups 0x3c5f(%rip), %xmm0     # 0x8a99
leaq 0x769f(%rip), %rax      # 0xc4e0
movups %xmm0, 0xc(%rax)
movups 0x3c41(%rip), %xmm0     # 0x8a8d
movaps %xmm0, (%rax)
pushq $0x1
popq %rdi
callq 0x56c5
movl (%rbx), %eax
leaq 0x397f(%rip), %r13      # 0x87df
cmpl $0x1, %eax
je 0x4e8e
movq %r13, %rbp
testl %eax, %eax
jne 0x4f02
movl 0x4(%rbx), %ecx
leaq 0x3c2f(%rip), %rdx      # 0x8aa9
leaq 0x10(%rsp), %rbp
pushq $0x5
popq %rsi
movq %rbp, %rdi
xorl %eax, %eax
callq 0x10c0
jmp 0x4f02
movq %r14, %rdi
xorl %esi, %esi
callq 0x1756
cmpl $0x1, %eax
je 0x4eb6
cmpl $0x4, %eax
jne 0x4ed7
movq (%rbx), %rdi
movl 0x8(%rbx), %esi
callq 0x1393
leaq 0x3792(%rip), %rsi      # 0x8646
jmp 0x4ec8
movq (%rbx), %rdi
movl 0x8(%rbx), %esi
callq 0x1393
leaq 0x37b3(%rip), %rsi      # 0x867b
movq (%rsp), %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x14e8
jmp 0x4efb
leaq 0x7602(%rip), %rdi      # 0xc4e0
leaq 0x3bcd(%rip), %rdx      # 0x8ab2
movl $0x100, %esi            # imm = 0x100
movl %eax, %ecx
xorl %eax, %eax
callq 0x10c0
pushq $0x1
popq %rdi
callq 0x56c5
leaq 0x3bac(%rip), %rbp      # 0x8aae
movl (%r12), %eax
cmpl $0x1, %eax
je 0x4f33
testl %eax, %eax
jne 0x4faf
movl 0x4(%r12), %ecx
leaq 0x3b8a(%rip), %rdx      # 0x8aa9
leaq 0x8(%rsp), %r13
pushq $0x5
popq %rsi
movq %r13, %rdi
xorl %eax, %eax
callq 0x10c0
jmp 0x4faf
leaq 0x10(%r12), %rdi
xorl %esi, %esi
callq 0x1756
cmpl $0x1, %eax
je 0x4f60
cmpl $0x4, %eax
jne 0x4f84
movq (%r12), %rdi
movl 0x8(%r12), %esi
callq 0x1393
leaq 0x3949(%rip), %rsi      # 0x88a7
jmp 0x4f75
movq (%r12), %rdi
movl 0x8(%r12), %esi
callq 0x1393
leaq 0x3b62(%rip), %rsi      # 0x8ad7
movq (%rsp), %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x14e8
jmp 0x4fa8
leaq 0x7555(%rip), %rdi      # 0xc4e0
leaq 0x3b20(%rip), %rdx      # 0x8ab2
movl $0x100, %esi            # imm = 0x100
movl %eax, %ecx
xorl %eax, %eax
callq 0x10c0
pushq $0x1
popq %rdi
callq 0x56c5
leaq 0x3b24(%rip), %r13      # 0x8ad3
movl %r15d, %eax
leaq 0x7127(%rip), %r10      # 0xc0e0
leaq 0x18(%rsp), %r9
movq %rbp, %rdi
movq %r13, %rsi
movq %rbx, %rdx
movq %r12, %rcx
movq (%rsp), %r8
callq *(%r10,%rax,8)
movq (%r12), %rdi
movl 0x8(%r12), %esi
callq 0x1343
cmpl $0x1, (%rbx)
jne 0x5054
leaq 0x18(%rsp), %rdi
xorl %esi, %esi
callq 0x1756
cmpl $0x1, %eax
je 0x500f
cmpl $0x4, %eax
jne 0x5030
movq (%rbx), %rdi
movl 0x8(%rbx), %esi
callq 0x1393
leaq 0x35a8(%rip), %rsi      # 0x85b5
jmp 0x5021
movq (%rbx), %rdi
movl 0x8(%rbx), %esi
callq 0x1393
leaq 0x373c(%rip), %rsi      # 0x875d
movq (%rsp), %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x14e8
jmp 0x5054
leaq 0x74a9(%rip), %rdi      # 0xc4e0
leaq 0x3a74(%rip), %rdx      # 0x8ab2
movl $0x100, %esi            # imm = 0x100
movl %eax, %ecx
xorl %eax, %eax
callq 0x10c0
pushq $0x1
popq %rdi
callq 0x56c5
movups 0x18(%rsp), %xmm0
movups 0x28(%rsp), %xmm1
movups 0x38(%rsp), %xmm2
movups 0x48(%rsp), %xmm3
movups %xmm3, 0x30(%r14)
movups %xmm2, 0x20(%r14)
movups %xmm1, 0x10(%r14)
movups %xmm0, (%r14)
movb $0x0, 0x50(%rbx)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq