// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq %rdx, 0x50(%rsp)
movq %rcx, 0x48(%rsp)
movq %r8, 0x40(%rsp)
movq %r9, 0x38(%rsp)
movq 0x50(%rsp), %rdi
addq $0x10, %rdi
callq 0xbdb0
cmpl $0x5, %eax
je 0x1c38
movq 0x48(%rsp), %rdi
addq $0x10, %rdi
callq 0xbdb0
cmpl $0x5, %eax
jne 0x1c5c
leaq 0xf8f1(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0xb7e5(%rip), %rdx      # 0xd430
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movq 0x50(%rsp), %rdi
addq $0x10, %rdi
callq 0xbdb0
cmpl $0x4, %eax
jne 0x1dd7
movq 0x48(%rsp), %rdi
addq $0x10, %rdi
callq 0xbdb0
cmpl $0x4, %eax
jne 0x1dc1
movq 0x50(%rsp), %rax
addq $0x10, %rax
movq %rax, 0x30(%rsp)
movq 0x48(%rsp), %rax
addq $0x10, %rax
movq %rax, 0x28(%rsp)
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0xbec0
cmpb $0x0, %al
jne 0x1cdd
leaq 0xf870(%rip), %rdi      # 0x11530
movl $0x100, %esi            # imm = 0x100
leaq 0xb78e(%rip), %rdx      # 0xd45a
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x87b0
movq 0x40(%rsp), %rdi
movq 0x60(%rsp), %rdx
movq 0x60(%rsp), %rcx
movq 0x58(%rsp), %r8
leaq 0xb78e(%rip), %rsi      # 0xd486
movb $0x0, %al
callq 0x16f0
movq 0x30(%rsp), %rdi
movl $0x1, %esi
callq 0x1a40
cmpl $0x4, %eax
jne 0x1d32
movq 0x40(%rsp), %rdi
movq 0x60(%rsp), %rdx
movq 0x60(%rsp), %rcx
leaq 0xb76d(%rip), %rsi      # 0xd496
movb $0x0, %al
callq 0x16f0
jmp 0x1da6
movq 0x30(%rsp), %rdi
movl $0x1, %esi
callq 0x1a40
cmpl $0x1, %eax
je 0x1da4
movq 0x40(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x30(%rsp), %rdi
movl $0x1, %esi
callq 0x1a40
movq 0x8(%rsp), %rdi
movl %eax, %edx
leaq 0xb6a0(%rip), %rsi      # 0xd40d
movb $0x0, %al
callq 0x16f0
movq 0x40(%rsp), %rdi
movq 0x60(%rsp), %rdx
leaq 0xb720(%rip), %rsi      # 0xd4a5
movb $0x0, %al
callq 0x16f0
movq 0x40(%rsp), %rdi
movq 0x60(%rsp), %rdx
leaq 0xb68a(%rip), %rsi      # 0xd427
movb $0x0, %al
callq 0x16f0
jmp 0x1da6
movq 0x38(%rsp), %rdi
leaq 0xf416(%rip), %rsi      # 0x111c8
movl $0x40, %edx
callq 0x1120
jmp 0x1f06
movq 0x50(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x58(%rsp), %rax
movq %rax, 0x18(%rsp)
jmp 0x1e3f
movq 0x48(%rsp), %rdi
addq $0x10, %rdi
callq 0xbdb0
cmpl $0x4, %eax
jne 0x1e00
movq 0x48(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x18(%rsp)
jmp 0x1e3d
movq 0x40(%rsp), %rdi
movq 0x60(%rsp), %rdx
movq 0x60(%rsp), %rcx
movq 0x58(%rsp), %r8
leaq 0xb66b(%rip), %rsi      # 0xd486
movb $0x0, %al
callq 0x16f0
movq 0x38(%rsp), %rdi
leaq 0xf39a(%rip), %rsi      # 0x111c8
movl $0x40, %edx
callq 0x1120
jmp 0x1f06
jmp 0x1e3f
movq 0x20(%rsp), %rdi
addq $0x10, %rdi
movl $0x1, %esi
callq 0x1a40
movl %eax, 0x14(%rsp)
cmpl $0x4, 0x14(%rsp)
jne 0x1e7c
movq 0x40(%rsp), %rdi
movq 0x18(%rsp), %rdx
movq 0x18(%rsp), %rcx
leaq 0xb58b(%rip), %rsi      # 0xd3fe
movb $0x0, %al
callq 0x16f0
jmp 0x1ecc
cmpl $0x1, 0x14(%rsp)
je 0x1eca
movq 0x40(%rsp), %rdi
movl 0x14(%rsp), %edx
leaq 0xb57a(%rip), %rsi      # 0xd40d
movb $0x0, %al
callq 0x16f0
movq 0x40(%rsp), %rdi
movq 0x18(%rsp), %rdx
leaq 0xb56e(%rip), %rsi      # 0xd419
movb $0x0, %al
callq 0x16f0
movq 0x40(%rsp), %rdi
movq 0x18(%rsp), %rdx
leaq 0xb564(%rip), %rsi      # 0xd427
movb $0x0, %al
callq 0x16f0
jmp 0x1ecc
movq 0x40(%rsp), %rdi
movq 0x60(%rsp), %rdx
movq 0x60(%rsp), %rcx
movq 0x58(%rsp), %r8
leaq 0xb59f(%rip), %rsi      # 0xd486
movb $0x0, %al
callq 0x16f0
movq 0x38(%rsp), %rdi
movq 0x20(%rsp), %rsi
addq $0x10, %rsi
movl $0x40, %edx
callq 0x1120
addq $0x68, %rsp
retq
nopl (%rax,%rax)