// File: /workspace/github_c_makefile_star2_O3/lucvoo[P]sparse-dev/evaluate.c
// Function: evaluate_offsetof
static struct symbol *evaluate_offsetof(struct expression *expr)
{
	struct expression *e = expr->down;
	struct symbol *ctype = expr->in;
	int class;

	if (expr->op == '.') {
		struct symbol *field;
		int offset = 0;
		if (!ctype) {
			expression_error(expr, "expected structure or union");
			return NULL;
		}
		examine_symbol_type(ctype);
		class = classify_type(ctype, &ctype);
		if (class != TYPE_COMPOUND) {
			expression_error(expr, "expected structure or union");
			return NULL;
		}

		field = find_identifier(expr->ident, ctype->symbol_list, &offset);
		if (!field) {
			expression_error(expr, "unknown member");
			return NULL;
		}
		ctype = field;
		expr->type = EXPR_VALUE;
		expr->flags = CEF_SET_ICE;
		expr->value = offset;
		expr->taint = 0;
		expr->ctype = size_t_ctype;
	} else {
		if (!ctype) {
			expression_error(expr, "expected structure or union");
			return NULL;
		}
		examine_symbol_type(ctype);
		class = classify_type(ctype, &ctype);
		if (class != (TYPE_COMPOUND | TYPE_PTR)) {
			expression_error(expr, "expected array");
			return NULL;
		}
		ctype = ctype->ctype.base_type;
		if (!expr->index) {
			expr->type = EXPR_VALUE;
			expr->flags = CEF_SET_ICE;
			expr->value = 0;
			expr->taint = 0;
			expr->ctype = size_t_ctype;
		} else {
			struct expression *idx = expr->index, *m;
			struct symbol *i_type = evaluate_expression(idx);
			unsigned old_idx_flags;
			int i_class = classify_type(i_type, &i_type);

			if (!is_int(i_class)) {
				expression_error(expr, "non-integer index");
				return NULL;
			}
			unrestrict(idx, i_class, &i_type);
			old_idx_flags = idx->flags;
			idx = cast_to(idx, size_t_ctype);
			idx->flags = old_idx_flags;
			m = alloc_const_expression(expr->pos,
						   bits_to_bytes(ctype->bit_size));
			m->ctype = size_t_ctype;
			m->flags = CEF_SET_INT;
			expr->type = EXPR_BINOP;
			expr->left = idx;
			expr->right = m;
			expr->op = '*';
			expr->ctype = size_t_ctype;
			expr->flags = m->flags & idx->flags & ~CEF_CONST_MASK;
		}
	}
	if (e) {
		struct expression *copy = __alloc_expression(0);
		*copy = *expr;
		if (e->type == EXPR_OFFSETOF)
			e->in = ctype;
		if (!evaluate_expression(e))
			return NULL;
		expr->type = EXPR_BINOP;
		expr->flags = e->flags & copy->flags & ~CEF_CONST_MASK;
		expr->op = '+';
		expr->ctype = size_t_ctype;
		expr->left = copy;
		expr->right = e;
	}
	return size_t_ctype;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x28(%rdi), %r14
movq 0x20(%rdi), %r15
cmpl $0x2e, 0x4(%rdi)
jne 0x35e2c
movl $0x0, 0x4(%rsp)
leaq 0x14752(%rip), %r12     # 0x4a4ef
testq %r15, %r15
je 0x35f26
movq %r15, %rdi
callq 0x2b0b8
movzbl (%r15), %eax
cmpl $0x3, %eax
jne 0x35dbf
movq 0x60(%r15), %r15
movzbl (%r15), %eax
cmpl $0xa, %eax
jne 0x35ddf
movq %r15, %rdi
callq 0x2b0b8
movq %rax, %r15
movzbl (%rax), %eax
cmpl $0x3, %eax
jne 0x35ddf
movq 0x60(%r15), %r15
movzbl (%r15), %eax
cmpl $0x9, %eax
jne 0x35dec
movq 0x60(%r15), %r15
movzbl (%r15), %eax
addl $-0x7, %eax
cmpl $0x1, %eax
ja 0x35f26
movq 0x30(%rbx), %rdi
movq 0x98(%r15), %rsi
leaq 0x4(%rsp), %rdx
callq 0x37a8b
testq %rax, %rax
je 0x35f1f
movq %rax, %r15
movw $0x3001, (%rbx)         # imm = 0x3001
movslq 0x4(%rsp), %rax
movq %rax, 0x20(%rbx)
jmp 0x35f55
testq %r15, %r15
je 0x35f07
movq %r15, %rdi
callq 0x2b0b8
movzbl (%r15), %eax
cmpl $0x3, %eax
jne 0x35e4e
movq 0x60(%r15), %r15
movzbl (%r15), %eax
cmpl $0xa, %eax
jne 0x35e6e
movq %r15, %rdi
callq 0x2b0b8
movq %rax, %r15
movzbl (%rax), %eax
cmpl $0x3, %eax
jne 0x35e6e
movq 0x60(%r15), %r15
movzbl (%r15), %eax
cmpl $0x9, %eax
jne 0x35e7b
movq 0x60(%r15), %r15
movzbl (%r15), %eax
cmpl $0x6, %eax
jne 0x35f10
movq 0x60(%r15), %r15
movq 0x30(%rbx), %r12
testq %r12, %r12
je 0x35f48
movq %r12, %rdi
callq 0x32223
movzbl (%rax), %ecx
cmpl $0x3, %ecx
jne 0x35eac
movq 0x60(%rax), %rax
movzbl (%rax), %ecx
cmpl $0xa, %ecx
jne 0x35ec8
movq %rax, %rdi
callq 0x2b0b8
movzbl (%rax), %ecx
cmpl $0x3, %ecx
jne 0x35ec8
movq 0x60(%rax), %rax
movzbl (%rax), %ecx
cmpl $0x9, %ecx
jne 0x35ed4
movq 0x60(%rax), %rax
movzbl (%rax), %ecx
cmpl $0x2, %ecx
jne 0x35ef3
movq 0x60(%rax), %rdx
cmpq 0x2a0a4(%rip), %rdx     # 0x5ff88
je 0x35f9e
cmpq 0x2a05f(%rip), %rdx     # 0x5ff50
je 0x35efe
movl $0x6800, %edx           # imm = 0x6800
btq %rcx, %rdx
jb 0x35f6f
leaq 0x14719(%rip), %rsi     # 0x4a61e
jmp 0x35f17
leaq 0x145e1(%rip), %rsi     # 0x4a4ef
jmp 0x35f17
leaq 0x146f8(%rip), %rsi     # 0x4a60f
xorl %r15d, %r15d
movq %rbx, %rdi
jmp 0x35f2f
leaq 0x146da(%rip), %r12     # 0x4a600
xorl %r15d, %r15d
movq %rbx, %rdi
movq %r12, %rsi
xorl %eax, %eax
callq 0x11b04
movq %r15, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movw $0x3001, (%rbx)         # imm = 0x3001
movq $0x0, 0x20(%rbx)
movl $0x0, 0x28(%rbx)
leaq 0x2e6bd(%rip), %rax     # 0x64620
movq (%rax), %rax
movq %rax, 0x10(%rbx)
jmp 0x36049
leal -0xf(%rcx), %edx
cmpl $-0x2, %edx
jb 0x35f9e
cmpl $0xe, %ecx
jne 0x35f80
movq 0x60(%rax), %rax
movq %rax, %rdi
callq 0x237c5
movq 0x8(%r12), %rdi
leaq 0x13eff(%rip), %rsi     # 0x49e93
movq %rax, %rdx
xorl %eax, %eax
callq 0x118fc
movb 0x1(%r12), %bpl
leaq 0x2e676(%rip), %rax     # 0x64620
movq (%rax), %rsi
movq %r12, %rdi
callq 0x32aa9
movq %rax, %r12
movb %bpl, 0x1(%rax)
movl 0x50(%r15), %eax
testl %eax, %eax
js 0x35fd9
leaq 0x2e735(%rip), %rcx     # 0x64700
movl (%rcx), %ecx
addl %ecx, %eax
decl %eax
cltd
idivl %ecx
movslq %eax, %rbp
jmp 0x35fe0
movq $-0x1, %rbp
movq 0x8(%rbx), %r13
xorl %edi, %edi
callq 0x2f9f5
movzwl 0x2(%rax), %ecx
shll $0x10, %ecx
movq %r13, 0x8(%rax)
movq %rbp, 0x20(%rax)
orl $0x3101, %ecx           # imm = 0x3101
movl %ecx, (%rax)
leaq 0x2e617(%rip), %rsi     # 0x64620
movq (%rsi), %rdx
movq %rdx, 0x10(%rax)
movl %ecx, (%rax)
movl $0xffffff00, %ecx       # imm = 0xFFFFFF00
andl (%rbx), %ecx
orl $0x5, %ecx
movl %ecx, (%rbx)
movq %r12, 0x20(%rbx)
movq %rax, 0x28(%rbx)
movl $0x2a, 0x4(%rbx)
movq (%rsi), %rdx
movq %rdx, 0x10(%rbx)
movl (%rax), %eax
andl (%r12), %eax
andl $0xf400, %eax           # imm = 0xF400
andl $0xffff0005, %ecx       # imm = 0xFFFF0005
orl %eax, %ecx
movl %ecx, (%rbx)
testq %r14, %r14
je 0x360d5
xorl %edi, %edi
callq 0x2f9f5
movq %rax, %r12
movaps (%rbx), %xmm0
movaps 0x10(%rbx), %xmm1
movaps 0x20(%rbx), %xmm2
movaps 0x30(%rbx), %xmm3
movaps %xmm3, 0x30(%rax)
movaps %xmm2, 0x20(%rax)
movaps %xmm1, 0x10(%rax)
movaps %xmm0, (%rax)
cmpb $0x1e, (%r14)
jne 0x36084
movq %r15, 0x20(%r14)
movq %r14, %rdi
callq 0x32223
testq %rax, %rax
je 0x360e4
movl $0xffffff00, %eax       # imm = 0xFFFFFF00
andl (%rbx), %eax
orl $0x5, %eax
movl %eax, (%rbx)
movl (%r14), %ecx
andl (%r12), %ecx
andl $0xf400, %ecx           # imm = 0xF400
andl $0xffff0005, %eax       # imm = 0xFFFF0005
orl %ecx, %eax
movl %eax, (%rbx)
movl $0x2b, 0x4(%rbx)
leaq 0x2e55f(%rip), %rax     # 0x64620
movq (%rax), %r15
movq %r15, 0x10(%rbx)
movq %r12, 0x20(%rbx)
movq %r14, 0x28(%rbx)
jmp 0x35f36
leaq 0x2e544(%rip), %rax     # 0x64620
movq (%rax), %r15
jmp 0x35f36
xorl %r15d, %r15d
jmp 0x35f36