// File: /workspace/github_c_makefile_star2_O3/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 0x7a9c
cmpl $0x5, %eax
je 0x1a58
leaq 0x10(%r13), %rdi
callq 0x7a9c
cmpl $0x5, %eax
jne 0x1a89
movups 0x77e7(%rip), %xmm0     # 0x9246
leaq 0xba7a(%rip), %rax      # 0xd4e0
movups %xmm0, 0x1a(%rax)
movups 0x77cb(%rip), %xmm0     # 0x923c
movaps %xmm0, 0x10(%rax)
movups 0x77b0(%rip), %xmm0     # 0x922c
movaps %xmm0, (%rax)
movl $0x1, %edi
callq 0x5b10
movq %rbp, %rdi
callq 0x7a9c
movl %eax, %r14d
leaq 0x10(%r13), %r15
movq %r15, %rdi
callq 0x7a9c
cmpl $0x4, %r14d
jne 0x1b59
movq %rbx, %r14
cmpl $0x4, %eax
jne 0x1b65
movq %rbp, %rdi
movq %r15, %rsi
callq 0x7aec
testb %al, %al
jne 0x1af6
movups 0x77a6(%rip), %xmm0     # 0x9272
leaq 0xba0d(%rip), %rax      # 0xd4e0
movups %xmm0, 0x1c(%rax)
movups 0x7788(%rip), %xmm0     # 0x9266
movaps %xmm0, 0x10(%rax)
movups 0x776d(%rip), %xmm0     # 0x9256
movaps %xmm0, (%rax)
movl $0x1, %edi
callq 0x5b10
leaq 0x7785(%rip), %rsi      # 0x9282
movq 0x8(%rsp), %r15
movq %r15, %rdi
movq (%rsp), %rcx
movq %rcx, %rdx
movq %rbx, %r8
xorl %eax, %eax
callq 0x171c
movq %rbp, %rdi
movl $0x1, %esi
callq 0x1990
leaq 0xb656(%rip), %r12      # 0xd180
cmpl $0x1, %eax
je 0x1c1a
cmpl $0x4, %eax
jne 0x1c54
leaq 0x774f(%rip), %rsi      # 0x9292
movq %r15, %rdi
movq (%rsp), %rcx
movq %rcx, %rdx
xorl %eax, %eax
callq 0x171c
jmp 0x1c1a
movq (%rsp), %r14
movq %r13, %r12
cmpl $0x4, %eax
jne 0x1b9e
addq $0x10, %r12
movq %r12, %rdi
movl $0x1, %esi
callq 0x1990
cmpl $0x1, %eax
movq 0x8(%rsp), %r15
je 0x1bff
cmpl $0x4, %eax
jne 0x1bc4
leaq 0x766e(%rip), %rsi      # 0x91fa
movq %r15, %rdi
movq %r14, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x171c
jmp 0x1bff
leaq 0x76dd(%rip), %rsi      # 0x9282
movq 0x8(%rsp), %rdi
movq (%rsp), %rcx
movq %rcx, %rdx
movq %rbx, %r8
xorl %eax, %eax
callq 0x171c
leaq 0xb5be(%rip), %r12      # 0xd180
jmp 0x1c1a
leaq 0x763e(%rip), %rsi      # 0x9209
movq %r15, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x171c
leaq 0x7637(%rip), %rsi      # 0x9215
movq %r15, %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x171c
leaq 0x7631(%rip), %rsi      # 0x9223
movq %r15, %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x171c
leaq 0x767c(%rip), %rsi      # 0x9282
movq %r15, %rdi
movq (%rsp), %rcx
movq %rcx, %rdx
movq %rbx, %r8
xorl %eax, %eax
callq 0x171c
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 0x75ae(%rip), %rsi      # 0x9209
movq %r15, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x171c
leaq 0x7633(%rip), %rsi      # 0x92a1
movq %r15, %rdi
movq (%rsp), %r14
movq %r14, %rdx
xorl %eax, %eax
callq 0x171c
leaq 0x759d(%rip), %rsi      # 0x9223
movq %r15, %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x171c
jmp 0x1c1a