// File: /workspace/github_c_makefile_star2_O3/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
movl %eax, 0x10(%rsp)
movb %al, 0x14(%rsp)
movb %al, 0xc(%rsp)
movl %eax, 0x8(%rsp)
leaq 0x10(%rdi), %r14
leaq 0x7f7f(%rip), %rsi      # 0xd1c0
movq %r14, %rdi
callq 0x7aec
testb %al, %al
jne 0x5262
leaq 0x10(%r12), %rdi
leaq 0x7f67(%rip), %rsi      # 0xd1c0
callq 0x7aec
testb %al, %al
je 0x5288
movups 0x4850(%rip), %xmm0     # 0x9ab9
leaq 0x8270(%rip), %rax      # 0xd4e0
movups %xmm0, 0xc(%rax)
movups 0x4832(%rip), %xmm0     # 0x9aad
movaps %xmm0, (%rax)
movl $0x1, %edi
callq 0x5b10
movl (%rbx), %eax
leaq 0x456e(%rip), %r13      # 0x97ff
cmpl $0x1, %eax
je 0x52c1
movq %r13, %rbp
testl %eax, %eax
jne 0x5337
movl 0x4(%rbx), %ecx
leaq 0x481e(%rip), %rdx      # 0x9ac9
leaq 0x10(%rsp), %rbp
movl $0x5, %esi
movq %rbp, %rdi
xorl %eax, %eax
callq 0x10c0
jmp 0x5337
movq %r14, %rdi
xorl %esi, %esi
callq 0x1990
cmpl $0x1, %eax
je 0x52e9
cmpl $0x4, %eax
jne 0x530a
movq (%rbx), %rdi
movl 0x8(%rbx), %esi
callq 0x15ba
leaq 0x437f(%rip), %rsi      # 0x9666
jmp 0x52fb
movq (%rbx), %rdi
movl 0x8(%rbx), %esi
callq 0x15ba
leaq 0x43a0(%rip), %rsi      # 0x969b
movq (%rsp), %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x171c
jmp 0x5330
leaq 0x81cf(%rip), %rdi      # 0xd4e0
leaq 0x47ba(%rip), %rdx      # 0x9ad2
movl $0x100, %esi            # imm = 0x100
movl %eax, %ecx
xorl %eax, %eax
callq 0x10c0
movl $0x1, %edi
callq 0x5b10
leaq 0x4797(%rip), %rbp      # 0x9ace
movl (%r12), %eax
cmpl $0x1, %eax
je 0x536a
testl %eax, %eax
jne 0x53e8
movl 0x4(%r12), %ecx
leaq 0x4775(%rip), %rdx      # 0x9ac9
leaq 0x8(%rsp), %r13
movl $0x5, %esi
movq %r13, %rdi
xorl %eax, %eax
callq 0x10c0
jmp 0x53e8
leaq 0x10(%r12), %rdi
xorl %esi, %esi
callq 0x1990
cmpl $0x1, %eax
je 0x5397
cmpl $0x4, %eax
jne 0x53bb
movq (%r12), %rdi
movl 0x8(%r12), %esi
callq 0x15ba
leaq 0x4532(%rip), %rsi      # 0x98c7
jmp 0x53ac
movq (%r12), %rdi
movl 0x8(%r12), %esi
callq 0x15ba
leaq 0x474b(%rip), %rsi      # 0x9af7
movq (%rsp), %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x171c
jmp 0x53e1
leaq 0x811e(%rip), %rdi      # 0xd4e0
leaq 0x4709(%rip), %rdx      # 0x9ad2
movl $0x100, %esi            # imm = 0x100
movl %eax, %ecx
xorl %eax, %eax
callq 0x10c0
movl $0x1, %edi
callq 0x5b10
leaq 0x470b(%rip), %r13      # 0x9af3
movl %r15d, %eax
leaq 0x7cee(%rip), %r10      # 0xd0e0
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 0x156a
cmpl $0x1, (%rbx)
jne 0x548f
leaq 0x18(%rsp), %rdi
xorl %esi, %esi
callq 0x1990
cmpl $0x1, %eax
je 0x5448
cmpl $0x4, %eax
jne 0x5469
movq (%rbx), %rdi
movl 0x8(%rbx), %esi
callq 0x15ba
leaq 0x418f(%rip), %rsi      # 0x95d5
jmp 0x545a
movq (%rbx), %rdi
movl 0x8(%rbx), %esi
callq 0x15ba
leaq 0x4323(%rip), %rsi      # 0x977d
movq (%rsp), %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x171c
jmp 0x548f
leaq 0x8070(%rip), %rdi      # 0xd4e0
leaq 0x465b(%rip), %rdx      # 0x9ad2
movl $0x100, %esi            # imm = 0x100
movl %eax, %ecx
xorl %eax, %eax
callq 0x10c0
movl $0x1, %edi
callq 0x5b10
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