// File: /workspace/github_c_makefile_star2_O0/ejunjsh[P]mycc/types.c
// Function: modify_type
struct ASTnode *modify_type(struct ASTnode *tree, int rtype,
			    struct symtable *rctype, int op) {
  int ltype;
  int lsize, rsize;

  ltype = tree->type;

  // 对于A_LOGOR 和 A_LOGAND， 这两个类型必须是整型或者指针类型
  if (op==A_LOGOR || op==A_LOGAND) {
    if (!inttype(ltype) && !ptrtype(ltype))
      return(NULL);
      //TODO:？？
    if (!inttype(ltype) && !ptrtype(rtype))
      return(NULL);
    return (tree);
  }

  // TODO:还没有实现复合结构
  if (ltype == P_STRUCT || ltype == P_UNION)
    fatal("Don't know how to do this yet");
  if (rtype == P_STRUCT || rtype == P_UNION)
    fatal("Don't know how to do this yet");

  // 都是整型
  if (inttype(ltype) && inttype(rtype)) {

    // 类型一样，直接返回
    if (ltype == rtype)
      return (tree);

    // 获得类型大小
    lsize = typesize(ltype, NULL);
    rsize = typesize(rtype, NULL);

    // 当前类型大小大于rtype类型，不兼容，我们不能截断
    if (lsize > rsize)
      return (NULL);

    // 如果当前小于rtype，增容
    if (rsize > lsize)
      return (mkastunary(A_WIDEN, rtype, NULL, tree, NULL, 0));
  }

  // 对于指针
  if (ptrtype(ltype) && ptrtype(rtype)) {
    // 指针可以比较
    if (op >= A_EQ && op <= A_GE)
      return (tree);

    // 对于非二元操作，相同类型，可以直接返回
    // 或者当前类型是一个`void *`类型
    if (op == 0 && (ltype == rtype || ltype == pointer_to(P_VOID)))
      return (tree);
  }

  // 只有在加减操作才进行倍数操作
  // 例如：int* p; int* a=p+1,实际上a的值是p的值加上4，4是整型类型大小，所以4是要作为倍数来修改原来的树
  if (op == A_ADD || op == A_SUBTRACT ||
      op == A_ASPLUS || op == A_ASMINUS) {

    // 当前是整型，rtype是指针类型，同时它的原来类型大小是大于一
    // 就要把当前类型倍数改成rtype的原来类型的大小
    if (inttype(ltype) && ptrtype(rtype)) {
      rsize = genprimsize(value_at(rtype));
      if (rsize > 1)
	    return (mkastunary(A_SCALE, rtype, rctype, tree, NULL, rsize)); // 包装原来那棵tree
      else
	    return (tree);		// 大小为一，不用修改倍数，直接返回
    }
  }

  // 到这里，代表类型不兼容
  return (NULL);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x28(%rbp)
cmpl $0x8, -0x24(%rbp)
je 0xb82c
cmpl $0x9, -0x24(%rbp)
jne 0xb887
movl -0x28(%rbp), %edi
callq 0xb6e0
cmpl $0x0, %eax
jne 0xb853
movl -0x28(%rbp), %edi
callq 0xb720
cmpl $0x0, %eax
jne 0xb853
movq $0x0, -0x8(%rbp)
jmp 0xba37
movl -0x28(%rbp), %edi
callq 0xb6e0
cmpl $0x0, %eax
jne 0xb87a
movl -0x14(%rbp), %edi
callq 0xb720
cmpl $0x0, %eax
jne 0xb87a
movq $0x0, -0x8(%rbp)
jmp 0xba37
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xba37
cmpl $0x50, -0x28(%rbp)
je 0xb893
cmpl $0x60, -0x28(%rbp)
jne 0xb89f
leaq 0x2b45(%rip), %rdi      # 0xe3df
callq 0x8110
cmpl $0x50, -0x14(%rbp)
je 0xb8ab
cmpl $0x60, -0x14(%rbp)
jne 0xb8b7
leaq 0x2b2d(%rip), %rdi      # 0xe3df
callq 0x8110
movl -0x28(%rbp), %edi
callq 0xb6e0
cmpl $0x0, %eax
je 0xb94c
movl -0x14(%rbp), %edi
callq 0xb6e0
cmpl $0x0, %eax
je 0xb94c
movl -0x28(%rbp), %eax
cmpl -0x14(%rbp), %eax
jne 0xb8ea
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xba37
movl -0x28(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
callq 0xb7c0
movl %eax, -0x2c(%rbp)
movl -0x14(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
callq 0xb7c0
movl %eax, -0x30(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jle 0xb91d
movq $0x0, -0x8(%rbp)
jmp 0xba37
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jle 0xb94a
movl -0x14(%rbp), %esi
movq -0x10(%rbp), %rcx
movl $0x21, %edi
xorl %eax, %eax
movl %eax, %r8d
xorl %r9d, %r9d
movq %r8, %rdx
callq 0xada0
movq %rax, -0x8(%rbp)
jmp 0xba37
jmp 0xb94c
movl -0x28(%rbp), %edi
callq 0xb720
cmpl $0x0, %eax
je 0xb9b5
movl -0x14(%rbp), %edi
callq 0xb720
cmpl $0x0, %eax
je 0xb9b5
cmpl $0xd, -0x24(%rbp)
jl 0xb97f
cmpl $0x12, -0x24(%rbp)
jg 0xb97f
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xba37
cmpl $0x0, -0x24(%rbp)
jne 0xb9b3
movl -0x28(%rbp), %eax
cmpl -0x14(%rbp), %eax
je 0xb9a6
movl -0x28(%rbp), %eax
movl %eax, -0x34(%rbp)
movl $0x10, %edi
callq 0xb740
movl %eax, %ecx
movl -0x34(%rbp), %eax
cmpl %ecx, %eax
jne 0xb9b3
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xba37
jmp 0xb9b5
cmpl $0x15, -0x24(%rbp)
je 0xb9cd
cmpl $0x16, -0x24(%rbp)
je 0xb9cd
cmpl $0x2, -0x24(%rbp)
je 0xb9cd
cmpl $0x3, -0x24(%rbp)
jne 0xba2f
movl -0x28(%rbp), %edi
callq 0xb6e0
cmpl $0x0, %eax
je 0xba2d
movl -0x14(%rbp), %edi
callq 0xb720
cmpl $0x0, %eax
je 0xba2d
movl -0x14(%rbp), %edi
callq 0xb780
movl %eax, %edi
callq 0x75d0
movl %eax, -0x30(%rbp)
cmpl $0x1, -0x30(%rbp)
jle 0xba23
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rdx
movq -0x10(%rbp), %rcx
movl -0x30(%rbp), %r9d
movl $0x26, %edi
xorl %eax, %eax
movl %eax, %r8d
callq 0xada0
movq %rax, -0x8(%rbp)
jmp 0xba37
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xba37
jmp 0xba2f
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x40, %rsp
popq %rbp
retq