// File: /workspace/github_c_makefile_star2_O3/Oric4ever[P]lcc65/6502/build/../src/tree.c
// Function: root
Tree root(p) Tree p; {
	if (p == 0)
		return p;
	switch (generic(p->op)) {
	case COND: {
		Tree q = p->kids[1];
		assert(q && q->op == RIGHT);
		if (p->u.sym && q->kids[0] && generic(q->kids[0]->op) == ASGN)
			q->kids[0] = root(q->kids[0]->kids[1]);
		else
			q->kids[0] = root(q->kids[0]);
		if (p->u.sym && q->kids[1] && generic(q->kids[1]->op) == ASGN)
			q->kids[1] = root(q->kids[1]->kids[1]);
		else
			q->kids[1] = root(q->kids[1]);
		if (p->u.sym)
			release(p->u.sym);
		p->u.sym = 0;
		if (q->kids[0] == 0 && q->kids[1] == 0)
			p = root(p->kids[0]);
		}
		break;
	case AND: case OR:
		if ((p->kids[1] = root(p->kids[1])) == 0)
			p = root(p->kids[0]);
		break;
	case NOT:
		return root(p->kids[0]);
	case RIGHT:
		if (p->kids[1] == 0)
			return root(p->kids[0]);
		if (p->kids[0] && p->kids[0]->op == CALL+B
		&&  p->kids[1] && p->kids[1]->op == INDIR+B)
			/* avoid premature release of the CALL+B temporary */
			return p->kids[0];
		if (p->kids[0] && p->kids[0]->op == RIGHT
		&&  p->kids[1] == p->kids[0]->kids[0])
			/* de-construct e++ construction */
			return p->kids[0]->kids[1];
		/* fall thru */
	case EQ:  case NE:  case GT:   case GE:  case LE:  case LT:
	case ADD: case SUB: case MUL:  case DIV: case MOD:
	case LSH: case RSH: case BAND: case BOR: case BXOR:
		p = tree(RIGHT, p->type, root(p->kids[0]), root(p->kids[1]));
		return p->kids[0] || p->kids[1] ? p : 0;
	case INDIR:
		if (p->type->size == 0)
			warning("reference to `%t' elided\n", p->type);
		if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type))
			warning("reference to `volatile %t' elided\n", p->type);
		/* fall thru */
	case CVI: case CVF:  case CVD:   case CVU: case CVC: case CVS: case CVP:
	case NEG: case BCOM: case FIELD:
		return root(p->kids[0]);
	case ADDRL:
		if (p->u.sym->temporary)
			release(p->u.sym);
		/* fall thru */
	case ADDRG: case ADDRF: case CNST:
		return 0;
	case ARG: case ASGN: case CALL: case JUMP: case LABEL:
		break;
	default: assert(0);
	}
	return p;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x17d10
movq %rdi, %r14
leaq 0x9140(%rip), %r13      # 0x20cb0
leaq 0x93a8(%rip), %r15      # 0x20f1f
xorl %ebx, %ebx
movl (%r14), %eax
addl $-0x10, %eax
shrl $0x4, %eax
cmpl $0x2a, %eax
ja 0x17d8c
movslq (%r13,%rax,4), %rax
addq %r13, %rax
jmpq *%rax
addq $0x10, %r14
movq %r14, %rcx
movq (%rcx), %r14
testq %r14, %r14
jne 0x17b79
jmp 0x17d12
movq 0x18(%r14), %rdi
callq 0x17b52
movq %rax, 0x18(%r14)
testq %rax, %rax
je 0x17b95
jmp 0x17ccb
leaq 0x10(%r14), %rcx
movq 0x18(%r14), %rax
testq %rax, %rax
je 0x17b9c
jmp 0x17d35
movq 0x18(%r14), %rbp
testq %rbp, %rbp
je 0x17d6d
cmpl $0x2a0, (%rbp)          # imm = 0x2A0
jne 0x17d6d
cmpq $0x0, 0x28(%r14)
movq 0x10(%rbp), %rdi
je 0x17c6b
testq %rdi, %rdi
je 0x17c69
movl (%rdi), %eax
andl $-0x10, %eax
cmpl $0x30, %eax
jne 0x17c6b
movq 0x18(%rdi), %rdi
jmp 0x17c6b
movq 0x8(%r14), %rsi
cmpl $0x0, 0x8(%rsi)
jne 0x17c20
movq %r15, %rdi
xorl %eax, %eax
callq 0x9bfd
movq 0x10(%r14), %rax
movq 0x8(%rax), %rax
movl (%rax), %ecx
cmpl $0xf, %ecx
jb 0x17c35
movq 0x10(%rax), %rcx
movl (%rcx), %ecx
cmpl $0x7, %ecx
jne 0x17b95
movq 0x10(%rax), %rax
movl (%rax), %eax
cmpl $0x1f, %eax
je 0x17c52
cmpl $0x10, %eax
jne 0x17b95
movq 0x8(%r14), %rsi
leaq 0x92dc(%rip), %rdi      # 0x20f39
xorl %eax, %eax
callq 0x9bfd
jmp 0x17b95
xorl %edi, %edi
callq 0x17b52
movq %rax, 0x10(%rbp)
leaq 0x18(%rbp), %r12
cmpq $0x0, 0x28(%r14)
movq 0x18(%rbp), %rdi
je 0x17c9a
testq %rdi, %rdi
je 0x17c98
movl (%rdi), %eax
andl $-0x10, %eax
cmpl $0x30, %eax
jne 0x17c9a
movq 0x18(%rdi), %rdi
jmp 0x17c9a
xorl %edi, %edi
callq 0x17b52
movq %rax, (%r12)
movq 0x28(%r14), %rdi
testq %rdi, %rdi
je 0x17cb1
callq 0x17731
movq $0x0, 0x28(%r14)
cmpq $0x0, 0x10(%rbp)
jne 0x17ccb
cmpq $0x0, 0x18(%rbp)
je 0x17b95
movq %r14, %rbx
jmp 0x17d12
movq 0x10(%r14), %rbx
movq 0x8(%r14), %r15
movq %rbx, %rdi
callq 0x17b52
movq %rax, %rbx
movq 0x18(%r14), %rdi
callq 0x17b52
movl $0x2a0, %edi            # imm = 0x2A0
movq %r15, %rsi
movq %rbx, %rdx
movq %rax, %rcx
callq 0x179e5
movq %rax, %rbx
cmpq $0x0, 0x10(%rax)
jne 0x17d12
cmpq $0x0, 0x18(%rbx)
jne 0x17d12
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x28(%r14), %rdi
testb $0x2, 0x1b(%rdi)
je 0x17d10
callq 0x17731
jmp 0x17d10
movq (%rcx), %rbx
testq %rbx, %rbx
je 0x17d56
movl (%rbx), %ecx
cmpl $0x2a0, %ecx            # imm = 0x2A0
je 0x17d5d
cmpl $0xd9, %ecx
jne 0x17cd4
cmpl $0x49, (%rax)
jne 0x17cd4
jmp 0x17d12
xorl %ebx, %ebx
jmp 0x17cd4
cmpq 0x10(%rbx), %rax
jne 0x17cd4
movq 0x18(%rbx), %rbx
jmp 0x17d12
leaq 0x918b(%rip), %rdi      # 0x20eff
leaq 0x909a(%rip), %rsi      # 0x20e15
leaq 0x9191(%rip), %rcx      # 0x20f13
movl $0x9a, %edx
callq 0x30d0
leaq 0x6408(%rip), %rdi      # 0x1e19b
leaq 0x907b(%rip), %rsi      # 0x20e15
leaq 0x9172(%rip), %rcx      # 0x20f13
movl $0xd2, %edx
callq 0x30d0