// File: /workspace/github_c_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %esi, %r14d
movq %rdi, %rbx
movl 0x8(%rdi), %r13d
movl %ecx, %eax
andl $-0x2, %eax
cmpl $0x8, %eax
jne 0x8e9b
testb $0xf, %r13b
sete %al
leal -0x41(%r13), %ecx
cmpl $-0x21, %ecx
setae %cl
testb %cl, %al
jne 0x8f8e
testb $0xf, %r13b
sete %al
testb $0xf, %r14b
sete %cl
orb %al, %cl
je 0x8f8e
jmp 0x8ff5
movl %ecx, %r12d
movq %rdx, -0x38(%rbp)
cmpl $0x60, %r13d
je 0x8eae
cmpl $0x50, %r13d
jne 0x8eba
leaq 0x315e(%rip), %rdi      # 0xc013
callq 0x688f
cmpl $0x60, %r14d
je 0x8ec6
cmpl $0x50, %r14d
jne 0x8ed2
leaq 0x3146(%rip), %rdi      # 0xc013
callq 0x688f
testb $0xf, %r13b
setne %al
leal -0x41(%r13), %ecx
cmpl $-0x21, %ecx
setb %r15b
orb %al, %r15b
jne 0x8f02
testb $0xf, %r14b
setne %al
leal -0x41(%r14), %ecx
cmpl $-0x21, %ecx
setb %cl
orb %al, %cl
je 0x8f89
testb $0xf, %r13b
sete %al
testb $0xf, %r14b
sete %cl
orb %al, %cl
je 0x8f30
xorl %eax, %eax
cmpl $0x16, %r12d
ja 0x8ff7
movl $0x60000c, %ecx         # imm = 0x60000C
btl %r12d, %ecx
jb 0x8f51
jmp 0x8ff7
leal -0xd(%r12), %eax
cmpl $0x6, %eax
jb 0x8f8e
xorl %eax, %eax
cmpl $0x16, %r12d
ja 0x8ff7
movl $0x60000c, %ecx         # imm = 0x60000C
btl %r12d, %ecx
jae 0x8fa8
testb $0xf, %r14b
sete %al
orb %r15b, %al
jne 0x8ff5
leal -0x1(%r14), %edi
callq 0x616c
cmpl $0x2, %eax
jl 0x8f8e
movl $0x26, %edi
movl %r14d, %esi
movq -0x38(%rbp), %rdx
movq %rbx, %rcx
xorl %r8d, %r8d
movl %eax, %r9d
jmp 0x901f
cmpl %r14d, %r13d
jne 0x8f93
movq %rbx, %rax
jmp 0x8ff7
cmpl $0x60, %r13d
je 0x8f9f
cmpl $0x50, %r13d
jne 0x8fc4
movl 0x28, %ecx
jmp 0x8fce
testl %r12d, %r12d
jne 0x8ff7
cmpl %r14d, %r13d
sete %al
cmpl $0x11, %r13d
sete %cl
orb %al, %cl
je 0x8f14
jmp 0x8f8e
movl %r13d, %edi
callq 0x616c
movl %eax, %ecx
cmpl $0x60, %r14d
je 0x8fda
cmpl $0x50, %r14d
jne 0x8fe3
movl 0x28, %eax
jmp 0x8ff1
movl %r14d, %edi
movl %ecx, -0x2c(%rbp)
callq 0x616c
movl -0x2c(%rbp), %ecx
cmpl %eax, %ecx
jle 0x9006
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jge 0x8f02
movl $0x21, %edi
movl %r14d, %esi
xorl %edx, %edx
movq %rbx, %rcx
xorl %r8d, %r8d
xorl %r9d, %r9d
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x885b