// File: /workspace/github_c_makefile_star2_O0/michaelforney[P]cproc/expr.c
// Function: builtinfunc
static struct expr *
builtinfunc(struct scope *s, enum builtinkind kind)
{
	struct expr *e, *toeval;
	struct type *t;
	struct member *m;
	char *name;
	unsigned long long offset;

	switch (kind) {
	case BUILTINALLOCA:
		e = exprassign(assignexpr(s), &typeulong);
		e = mkexpr(EXPRBUILTIN, mkpointertype(&typevoid, QUALNONE), e);
		e->u.builtin.kind = BUILTINALLOCA;
		break;
	case BUILTINCONSTANTP:
		e = mkconstexpr(&typeint, eval(condexpr(s))->kind == EXPRCONST);
		break;
	case BUILTINEXPECT:
		/* just a no-op for now */
		/* TODO: check that the expression and the expected value have type 'long' */
		e = assignexpr(s);
		expect(TCOMMA, "after expression");
		delexpr(assignexpr(s));
		break;
	case BUILTININFF:
		e = mkexpr(EXPRCONST, &typefloat, NULL);
		/* TODO: use INFINITY here when we can handle musl's math.h */
		e->u.constant.f = strtod("inf", NULL);
		break;
	case BUILTINNANF:
		e = assignexpr(s);
		if (!e->decayed || e->base->kind != EXPRSTRING || e->base->u.string.size > 1)
			error(&tok.loc, "__builtin_nanf currently only supports empty string literals");
		e = mkexpr(EXPRCONST, &typefloat, NULL);
		/* TODO: use NAN here when we can handle musl's math.h */
		e->u.constant.f = strtod("nan", NULL);
		break;
	case BUILTINOFFSETOF:
		t = typename(s, NULL, NULL);
		expect(TCOMMA, "after type name");
		name = expect(TIDENT, "after ','");
		if (t->kind != TYPESTRUCT && t->kind != TYPEUNION)
			error(&tok.loc, "type is not a struct/union type");
		offset = 0;
		m = typemember(t, name, &offset);
		if (!m)
			error(&tok.loc, "struct/union has no member named '%s'", name);
		designator(s, m->type, &offset);
		e = mkconstexpr(&typeulong, offset);
		free(name);
		break;
	case BUILTINTYPESCOMPATIBLEP:
		t = typename(s, NULL, NULL);
		expect(TCOMMA, "after type name");
		e = mkconstexpr(&typeint, typecompatible(t, typename(s, NULL, NULL)));
		break;
	case BUILTINUNREACHABLE:
		e = mkexpr(EXPRBUILTIN, &typevoid, NULL);
		e->u.builtin.kind = BUILTINUNREACHABLE;
		break;
	case BUILTINVAARG:
		e = mkexpr(EXPRBUILTIN, NULL, assignexpr(s));
		e->u.builtin.kind = BUILTINVAARG;
		if (!typesame(e->base->type, typeadjvalist))
			error(&tok.loc, "va_arg argument must have type va_list");
		if (typeadjvalist == targ->typevalist)
			e->base = mkunaryexpr(TBAND, e->base);
		expect(TCOMMA, "after va_list");
		e->type = typename(s, &e->qual, &toeval);
		e->toeval = toeval;
		break;
	case BUILTINVACOPY:
		e = mkexpr(EXPRASSIGN, &typevoid, NULL);
		e->u.assign.l = assignexpr(s);
		if (!typesame(e->u.assign.l->type, typeadjvalist))
			error(&tok.loc, "va_copy destination must have type va_list");
		if (typeadjvalist != targ->typevalist)
			e->u.assign.l = mkunaryexpr(TMUL, e->u.assign.l);
		expect(TCOMMA, "after target va_list");
		e->u.assign.r = assignexpr(s);
		if (!typesame(e->u.assign.r->type, typeadjvalist))
			error(&tok.loc, "va_copy source must have type va_list");
		if (typeadjvalist != targ->typevalist)
			e->u.assign.r = mkunaryexpr(TMUL, e->u.assign.r);
		break;
	case BUILTINVAEND:
		e = assignexpr(s);
		if (!typesame(e->type, typeadjvalist))
			error(&tok.loc, "va_end argument must have type va_list");
		e = mkexpr(EXPRCAST, &typevoid, e);
		break;
	case BUILTINVASTART:
		e = mkexpr(EXPRBUILTIN, &typevoid, assignexpr(s));
		e->u.builtin.kind = BUILTINVASTART;
		if (!typesame(e->base->type, typeadjvalist))
			error(&tok.loc, "va_start argument must have type va_list");
		if (typeadjvalist == targ->typevalist)
			e->base = mkunaryexpr(TBAND, e->base);
		if (consume(TCOMMA))
			delexpr(assignexpr(s));
		break;
	default:
		fatal("internal error; unknown builtin");
		return NULL;  /* unreachable */
	}
	return e;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl -0x14(%rbp), %eax
movq %rax, -0x50(%rbp)
subq $0xc, %rax
ja 0xb7ec
movq -0x50(%rbp), %rax
leaq 0xe5c1(%rip), %rcx      # 0x1979c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, %rdi
leaq 0x16bb1(%rip), %rsi     # 0x21da8
callq 0x7ff0
movq %rax, -0x20(%rbp)
leaq 0x16831(%rip), %rdi     # 0x21a38
xorl %esi, %esi
callq 0x11760
movq %rax, %rsi
movq -0x20(%rbp), %rdx
movl $0xd, %edi
callq 0x9040
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl $0x0, 0x30(%rax)
jmp 0xb804
movq -0x10(%rbp), %rdi
callq 0x8b40
movq %rax, %rdi
callq 0x7010
cmpl $0x1, (%rax)
sete %al
andb $0x1, %al
movzbl %al, %eax
movslq %eax, %rsi
leaq 0x16a47(%rip), %rdi     # 0x21ca0
callq 0xb820
movq %rax, -0x20(%rbp)
jmp 0xb804
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, -0x20(%rbp)
movl $0x6e, %edi
leaq 0xec7a(%rip), %rsi      # 0x19efa
callq 0xd8d0
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, %rdi
callq 0x7ee0
jmp 0xb804
movl $0x1, %edi
leaq 0x16c09(%rip), %rsi     # 0x21eb0
xorl %eax, %eax
movl %eax, %edx
callq 0x9040
movq %rax, -0x20(%rbp)
leaq 0xee76(%rip), %rdi      # 0x1a131
xorl %eax, %eax
movl %eax, %esi
callq 0x3080
movq -0x20(%rbp), %rax
movsd %xmm0, 0x30(%rax)
jmp 0xb804
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
testb $0x1, 0x5(%rax)
je 0xb305
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
cmpl $0x2, (%rax)
jne 0xb305
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
cmpq $0x1, 0x30(%rax)
jbe 0xb31e
leaq 0x16e9c(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0xee1e(%rip), %rsi      # 0x1a135
movb $0x0, %al
callq 0x11190
movl $0x1, %edi
leaq 0x16b86(%rip), %rsi     # 0x21eb0
xorl %eax, %eax
movl %eax, %edx
callq 0x9040
movq %rax, -0x20(%rbp)
leaq 0xee34(%rip), %rdi      # 0x1a172
xorl %eax, %eax
movl %eax, %esi
callq 0x3080
movq -0x20(%rbp), %rax
movsd %xmm0, 0x30(%rax)
jmp 0xb804
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x3960
movq %rax, -0x30(%rbp)
movl $0x6e, %edi
leaq 0xe898(%rip), %rsi      # 0x19c0d
callq 0xd8d0
movl $0x4, %edi
leaq 0xedf0(%rip), %rsi      # 0x1a176
callq 0xd8d0
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rax
cmpl $0xf, (%rax)
je 0xb3ba
movq -0x30(%rbp), %rax
cmpl $0x10, (%rax)
je 0xb3ba
leaq 0x16e00(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0xedcd(%rip), %rsi      # 0x1a180
movb $0x0, %al
callq 0x11190
movq $0x0, -0x48(%rbp)
movq -0x30(%rbp), %rdi
movq -0x40(%rbp), %rsi
leaq -0x48(%rbp), %rdx
callq 0x11f70
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0xb3fb
movq -0x40(%rbp), %rdx
leaq 0x16dbf(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0xe9ed(%rip), %rsi      # 0x19de1
movb $0x0, %al
callq 0x11190
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x48(%rbp), %rdx
callq 0xbd10
movq -0x48(%rbp), %rsi
leaq 0x1698d(%rip), %rdi     # 0x21da8
callq 0xb820
movq %rax, -0x20(%rbp)
movq -0x40(%rbp), %rdi
callq 0x3260
jmp 0xb804
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x3960
movq %rax, -0x30(%rbp)
movl $0x6e, %edi
leaq 0xe7bb(%rip), %rsi      # 0x19c0d
callq 0xd8d0
movq -0x30(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x3960
movq -0x58(%rbp), %rdi
movq %rax, %rsi
callq 0x11890
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
leaq 0x16817(%rip), %rdi     # 0x21ca0
callq 0xb820
movq %rax, -0x20(%rbp)
jmp 0xb804
movl $0xd, %edi
leaq 0x16595(%rip), %rsi     # 0x21a38
xorl %eax, %eax
movl %eax, %edx
callq 0x9040
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl $0x7, 0x30(%rax)
jmp 0xb804
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, %rdx
movl $0xd, %edi
xorl %eax, %eax
movl %eax, %esi
callq 0x9040
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl $0x8, 0x30(%rax)
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x8(%rax), %rdi
leaq 0x16cd4(%rip), %rax     # 0x221d0
movq (%rax), %rsi
callq 0x11ab0
testb $0x1, %al
jne 0xb521
leaq 0x16c99(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0xec86(%rip), %rsi      # 0x1a1a0
movb $0x0, %al
callq 0x11190
leaq 0x16ca8(%rip), %rax     # 0x221d0
movq (%rax), %rax
leaq 0x16c6e(%rip), %rcx     # 0x221a0
movq (%rcx), %rcx
cmpq 0x8(%rcx), %rax
jne 0xb558
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rsi
movl $0x4a, %edi
callq 0x9410
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x18(%rax)
movl $0x6e, %edi
leaq 0xec63(%rip), %rsi      # 0x1a1c7
callq 0xd8d0
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x10, %rsi
leaq -0x28(%rbp), %rdx
callq 0x3960
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x28(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x28(%rax)
jmp 0xb804
movl $0xb, %edi
leaq 0x16492(%rip), %rsi     # 0x21a38
xorl %eax, %eax
movl %eax, %edx
callq 0x9040
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rax
movq 0x8(%rax), %rdi
leaq 0x16bf6(%rip), %rax     # 0x221d0
movq (%rax), %rsi
callq 0x11ab0
testb $0x1, %al
jne 0xb5ff
leaq 0x16bbb(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0xebdd(%rip), %rsi      # 0x1a1d5
movb $0x0, %al
callq 0x11190
leaq 0x16bca(%rip), %rax     # 0x221d0
movq (%rax), %rax
leaq 0x16b90(%rip), %rcx     # 0x221a0
movq (%rcx), %rcx
cmpq 0x8(%rcx), %rax
je 0xb636
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rsi
movl $0x4b, %edi
callq 0x9410
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x30(%rax)
movl $0x6e, %edi
leaq 0xebbe(%rip), %rsi      # 0x1a200
callq 0xd8d0
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x20(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rdi
leaq 0x16b62(%rip), %rax     # 0x221d0
movq (%rax), %rsi
callq 0x11ab0
testb $0x1, %al
jne 0xb693
leaq 0x16b27(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0xeb89(%rip), %rsi      # 0x1a215
movb $0x0, %al
callq 0x11190
leaq 0x16b36(%rip), %rax     # 0x221d0
movq (%rax), %rax
leaq 0x16afc(%rip), %rcx     # 0x221a0
movq (%rcx), %rcx
cmpq 0x8(%rcx), %rax
je 0xb6ca
movq -0x20(%rbp), %rax
movq 0x38(%rax), %rsi
movl $0x4b, %edi
callq 0x9410
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x38(%rax)
jmp 0xb804
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x16ae5(%rip), %rax     # 0x221d0
movq (%rax), %rsi
callq 0x11ab0
testb $0x1, %al
jne 0xb710
leaq 0x16aaa(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0xeb32(%rip), %rsi      # 0x1a23b
movb $0x0, %al
callq 0x11190
movq -0x20(%rbp), %rdx
movl $0x8, %edi
leaq 0x16318(%rip), %rsi     # 0x21a38
callq 0x9040
movq %rax, -0x20(%rbp)
jmp 0xb804
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, %rdx
movl $0xd, %edi
leaq 0x162f2(%rip), %rsi     # 0x21a38
callq 0x9040
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl $0xc, 0x30(%rax)
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x8(%rax), %rdi
leaq 0x16a63(%rip), %rax     # 0x221d0
movq (%rax), %rsi
callq 0x11ab0
testb $0x1, %al
jne 0xb792
leaq 0x16a28(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0xead7(%rip), %rsi      # 0x1a262
movb $0x0, %al
callq 0x11190
leaq 0x16a37(%rip), %rax     # 0x221d0
movq (%rax), %rax
leaq 0x169fd(%rip), %rcx     # 0x221a0
movq (%rcx), %rcx
cmpq 0x8(%rcx), %rax
jne 0xb7c9
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rsi
movl $0x4a, %edi
callq 0x9410
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x18(%rax)
movl $0x6e, %edi
callq 0xd910
testb $0x1, %al
jne 0xb7d9
jmp 0xb7ea
movq -0x10(%rbp), %rdi
callq 0x9170
movq %rax, %rdi
callq 0x7ee0
jmp 0xb804
leaq 0xea98(%rip), %rdi      # 0x1a28b
movb $0x0, %al
callq 0x12650
movq $0x0, -0x8(%rbp)
jmp 0xb80c
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)