// File: /workspace/github_c_makefile_star2_O2/been-jamming[P]MinimalCC/expression.c
// Function: operation_subtract_func
void operation_subtract_func(char *reg_a, char *reg_b, value *value_a, value *value_b, FILE *output_file, type *output_type){
	type *pointer_type;
	type *pointer_type2;
	value *pointer_value;
	char *integer_reg;
	unsigned int pointer_size;

	if(peek_type(&(value_a->data_type)) == type_function || peek_type(&(value_b->data_type)) == type_function){
		snprintf(error_message, sizeof(error_message), "Subtraction of function type is undefined");
		do_error(1);
	}
	if(peek_type(&(value_a->data_type)) == type_pointer){
		if(peek_type(&(value_b->data_type)) == type_pointer){
			pointer_type = &(value_a->data_type);
			pointer_type2 = &(value_b->data_type);
			if(!types_equal(pointer_type, pointer_type2)){
				snprintf(error_message, sizeof(error_message), "Cannot subtract pointers to different types");
				do_error(1);
			}
			fileprint(output_file, "sub %s, %s, %s\n", reg_a, reg_a, reg_b);
			if(type_size(pointer_type, 1) == 4){
				fileprint(output_file, "sra %s, %s, 2\n", reg_a, reg_a);
			} else if(type_size(pointer_type, 1) != 1){
				fileprint(output_file, "li $t2, %d\n", type_size(pointer_type, 1));
				fileprint(output_file, "div %s, $t2\n", reg_a);
				fileprint(output_file, "mflo %s\n", reg_a);
			}
			*output_type = INT_TYPE;
			return;
		}
		pointer_value = value_a;
		integer_reg = reg_b;
	} else {
		if(peek_type(&(value_b->data_type)) == type_pointer){
			pointer_value = value_b;
			integer_reg = reg_a;
		} else {
			fileprint(output_file, "sub %s, %s, %s\n", reg_a, reg_a, reg_b);
			*output_type = INT_TYPE;
			return;
		}
	}
	pointer_size = type_size(&(pointer_value->data_type), 1);
	if(pointer_size == 4){
		fileprint(output_file, "sll %s, %s, 2\n", integer_reg, integer_reg);
	} else if(pointer_size != 1){
		fileprint(output_file, "li $t2, %d\n", pointer_size);
		fileprint(output_file, "mult %s, $t2\n", integer_reg);
		fileprint(output_file, "mflo %s\n", integer_reg);
	}
	fileprint(output_file, "sub %s, %s, %s\n", reg_a, reg_a, reg_b);

	*output_type = pointer_value->data_type;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %r9, 0x10(%rsp)
movq %r8, 0x8(%rsp)
movq %rcx, %r13
movq %rdx, %r12
movq %rsi, %rbx
movq %rdi, (%rsp)
leaq 0x10(%rdx), %rbp
movq %rbp, %rdi
callq 0x7603
cmpl $0x5, %eax
je 0x181d
leaq 0x10(%r13), %rdi
callq 0x7603
cmpl $0x5, %eax
jne 0x184c
movups 0x6a02(%rip), %xmm0     # 0x8226
leaq 0xacb5(%rip), %rax      # 0xc4e0
movups %xmm0, 0x1a(%rax)
movups 0x69e6(%rip), %xmm0     # 0x821c
movaps %xmm0, 0x10(%rax)
movups 0x69cb(%rip), %xmm0     # 0x820c
movaps %xmm0, (%rax)
pushq $0x1
popq %rdi
callq 0x56c5
movq %rbp, %rdi
callq 0x7603
movl %eax, %r14d
leaq 0x10(%r13), %r15
movq %r15, %rdi
callq 0x7603
cmpl $0x4, %r14d
jne 0x1918
movq %rbx, %r14
cmpl $0x4, %eax
jne 0x1924
movq %rbp, %rdi
movq %r15, %rsi
callq 0x7653
testb %al, %al
jne 0x18b7
movups 0x69c3(%rip), %xmm0     # 0x8252
leaq 0xac4a(%rip), %rax      # 0xc4e0
movups %xmm0, 0x1c(%rax)
movups 0x69a5(%rip), %xmm0     # 0x8246
movaps %xmm0, 0x10(%rax)
movups 0x698a(%rip), %xmm0     # 0x8236
movaps %xmm0, (%rax)
pushq $0x1
popq %rdi
callq 0x56c5
leaq 0x69a4(%rip), %rsi      # 0x8262
movq 0x8(%rsp), %r15
movq %r15, %rdi
movq (%rsp), %rcx
movq %rcx, %rdx
movq %rbx, %r8
xorl %eax, %eax
callq 0x14e8
pushq $0x1
popq %rsi
movq %rbp, %rdi
callq 0x1756
leaq 0xa897(%rip), %r12      # 0xc180
cmpl $0x1, %eax
je 0x19d7
cmpl $0x4, %eax
jne 0x1a11
leaq 0x6970(%rip), %rsi      # 0x8272
movq %r15, %rdi
movq (%rsp), %rcx
movq %rcx, %rdx
xorl %eax, %eax
callq 0x14e8
jmp 0x19d7
movq (%rsp), %r14
movq %r13, %r12
cmpl $0x4, %eax
jne 0x195b
addq $0x10, %r12
pushq $0x1
popq %rsi
movq %r12, %rdi
callq 0x1756
cmpl $0x1, %eax
movq 0x8(%rsp), %r15
je 0x19bc
cmpl $0x4, %eax
jne 0x1981
leaq 0x6891(%rip), %rsi      # 0x81da
movq %r15, %rdi
movq %r14, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x14e8
jmp 0x19bc
leaq 0x6900(%rip), %rsi      # 0x8262
movq 0x8(%rsp), %rdi
movq (%rsp), %rcx
movq %rcx, %rdx
movq %rbx, %r8
xorl %eax, %eax
callq 0x14e8
leaq 0xa801(%rip), %r12      # 0xc180
jmp 0x19d7
leaq 0x6861(%rip), %rsi      # 0x81e9
movq %r15, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x14e8
leaq 0x685a(%rip), %rsi      # 0x81f5
movq %r15, %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x14e8
leaq 0x6854(%rip), %rsi      # 0x8203
movq %r15, %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x14e8
leaq 0x689f(%rip), %rsi      # 0x8262
movq %r15, %rdi
movq (%rsp), %rcx
movq %rcx, %rdx
movq %rbx, %r8
xorl %eax, %eax
callq 0x14e8
movups (%r12), %xmm0
movups 0x10(%r12), %xmm1
movups 0x20(%r12), %xmm2
movups 0x30(%r12), %xmm3
movq 0x10(%rsp), %rax
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x67d1(%rip), %rsi      # 0x81e9
movq %r15, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x14e8
leaq 0x6856(%rip), %rsi      # 0x8281
movq %r15, %rdi
movq (%rsp), %r14
movq %r14, %rdx
xorl %eax, %eax
callq 0x14e8
leaq 0x67c0(%rip), %rsi      # 0x8203
movq %r15, %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x14e8
jmp 0x19d7