// File: /workspace/github_c_makefile_star2_O1/michaelforney[P]cproc/qbe.c
// Function: emitdata
void
emitdata(struct decl *d, struct init *init)
{
	struct init *cur;
	struct type *t;
	unsigned long long offset = 0, start, end, bits = 0;
	size_t i;
	int align;

	align = d->u.obj.align;
	for (cur = init; cur; cur = cur->next)
		cur->expr = eval(cur->expr);
	if (d->u.obj.storage == SDTHREAD)
		fputs("thread ", stdout);
	if (d->linkage == LINKEXTERN)
		fputs("export ", stdout);
	fputs("data ", stdout);
	emitname(d->value);
	printf(" = align %d { ", align);

	while (init) {
		cur = init;
		while ((init = init->next) && init->start * 8 + init->bits.before < cur->end * 8 - cur->bits.after) {
			/*
			XXX: Currently, if multiple union members are
			initialized, these assertions may not hold.
			(https://todo.sr.ht/~mcf/cproc/38)
			*/
			assert(cur->expr->kind == EXPRSTRING);
			assert(init->expr->kind == EXPRCONST);
			i = (init->start - cur->start) / cur->expr->type->base->size;
			switch (cur->expr->type->base->size) {
			case 1: ((unsigned char *)cur->expr->u.string.data)[i]  = init->expr->u.constant.u; break;
			case 2: ((uint_least16_t *)cur->expr->u.string.data)[i] = init->expr->u.constant.u; break;
			case 4: ((uint_least32_t *)cur->expr->u.string.data)[i] = init->expr->u.constant.u; break;
			}
		}
		start = cur->start + cur->bits.before / 8;
		end = cur->end - (cur->bits.after + 7) / 8;
		if (offset < start && bits) {
			printf("b %u, ", (unsigned)bits);  /* unfinished byte from previous bit-field */
			++offset;
			bits = 0;
		}
		if (offset < start)
			printf("z %llu, ", start - offset);
		if (cur->bits.before || cur->bits.after) {
			/* little-endian target specific */
			assert(cur->expr->type->prop & PROPINT);
			assert(cur->expr->kind == EXPRCONST);
			bits |= cur->expr->u.constant.u << cur->bits.before % 8;
			for (offset = start; offset < end; ++offset, bits >>= 8)
				printf("b %u, ", (unsigned)bits & 0xff);
			/*
			clear the upper `after` bits in the last byte,
			or all bits when `after` is 0 (we ended on a
			byte boundary).
			*/
			bits &= 0x7f >> (cur->bits.after + 7) % 8;
		} else {
			t = cur->expr->type;
			if (t->kind == TYPEARRAY)
				t = t->base;
			printf("%c ", qbetype(t).data);
			dataitem(cur->expr, cur->end - cur->start);
			fputs(", ", stdout);
		}
		offset = end;
	}
	if (bits) {
		printf("b %u, ", (unsigned)bits);
		++offset;
	}
	assert(offset <= d->type->size);
	if (offset < d->type->size)
		printf("z %llu ", d->type->size - offset);
	puts("}");
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r15
movl 0x40(%rdi), %ebp
testq %rsi, %rsi
je 0x11009
movq %rbx, %r14
movq 0x10(%r14), %rdi
callq 0x61cc
movq %rax, 0x10(%r14)
movq 0x20(%r14), %r14
testq %r14, %r14
jne 0x10ff3
cmpl $0x1, 0x44(%r15)
jne 0x11026
movq 0x9fa9(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x4a28(%rip), %rdi      # 0x15a49
callq 0x30f0
cmpl $0x2, 0xc(%r15)
jne 0x11043
movq 0x9f8c(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x4a13(%rip), %rdi      # 0x15a51
callq 0x30f0
movq 0x9f76(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x4a05(%rip), %rdi      # 0x15a59
callq 0x30f0
movq %r15, (%rsp)
movq 0x20(%r15), %rdi
callq 0x10ec1
leaq 0x49f2(%rip), %rdi      # 0x15a5f
movl %ebp, %esi
xorl %eax, %eax
callq 0x30b0
testq %rbx, %rbx
je 0x11280
xorl %r12d, %r12d
xorl %r8d, %r8d
movq 0x20(%rbx), %r14
testq %r14, %r14
je 0x11120
movq (%r14), %rax
movswq 0x18(%r14), %rcx
leaq (%rcx,%rax,8), %rcx
movq 0x8(%rbx), %rdx
shlq $0x3, %rdx
movswq 0x1a(%rbx), %rsi
subq %rsi, %rdx
cmpq %rdx, %rcx
jae 0x11120
movq 0x10(%rbx), %rcx
cmpl $0x2, (%rcx)
jne 0x112dd
movq 0x10(%r14), %rsi
cmpl $0x1, (%rsi)
jne 0x112fc
subq (%rbx), %rax
movq 0x8(%rcx), %rdx
movq 0x20(%rdx), %rdx
movq 0x10(%rdx), %rdi
xorl %edx, %edx
divq %rdi
cmpq $0x4, %rdi
je 0x1110d
cmpq $0x2, %rdi
je 0x110ff
cmpq $0x1, %rdi
jne 0x11117
movb 0x30(%rsi), %dl
movq 0x38(%rcx), %rcx
movb %dl, (%rcx,%rax)
jmp 0x11117
movzwl 0x30(%rsi), %edx
movq 0x38(%rcx), %rcx
movw %dx, (%rcx,%rax,2)
jmp 0x11117
movl 0x30(%rsi), %edx
movq 0x38(%rcx), %rcx
movl %edx, (%rcx,%rax,4)
movq 0x20(%r14), %r14
jmp 0x11089
movl 0x18(%rbx), %eax
leal 0x7(%rax), %ecx
testw %ax, %ax
cmovnsl %eax, %ecx
movswl %cx, %eax
shrl $0x3, %eax
movswq %ax, %r13
addq (%rbx), %r13
movq 0x8(%rbx), %rbp
movswl 0x1a(%rbx), %r15d
leal 0x7(%r15), %eax
addl $0xe, %r15d
testl %eax, %eax
cmovnsl %eax, %r15d
cmpq %r13, %r12
jae 0x11171
testq %r8, %r8
je 0x11171
leaq 0x4975(%rip), %rdi      # 0x15ad6
movl %r8d, %esi
xorl %eax, %eax
callq 0x30b0
incq %r12
xorl %r8d, %r8d
movq %r13, %rsi
subq %r12, %rsi
jbe 0x1118d
leaq 0x495d(%rip), %rdi      # 0x15add
xorl %eax, %eax
movq %r8, %r12
callq 0x30b0
movq %r12, %r8
sarl $0x3, %r15d
movslq %r15d, %rax
subq %rax, %rbp
movswl 0x18(%rbx), %ecx
testl %ecx, %ecx
jne 0x111a6
cmpw $0x0, 0x1a(%rbx)
je 0x11223
movq 0x10(%rbx), %rax
movq 0x8(%rax), %rdx
testb $0x2, 0x4(%rdx)
leaq 0x491d(%rip), %r15      # 0x15ad6
je 0x1131b
cmpl $0x1, (%rax)
jne 0x1133a
movq 0x30(%rax), %r12
leal 0x7(%rcx), %eax
testl %ecx, %ecx
cmovnsl %ecx, %eax
andl $0xf8, %eax
subl %eax, %ecx
shlq %cl, %r12
orq %r8, %r12
cmpq %rbp, %r13
jae 0x111fd
movzbl %r12b, %esi
movq %r15, %rdi
xorl %eax, %eax
callq 0x30b0
incq %r13
shrq $0x8, %r12
jmp 0x111e1
movb 0x1a(%rbx), %cl
decb %cl
andb $0x7, %cl
movl $0x7f, %eax
shrl %cl, %eax
andl %eax, %r12d
movq %r12, %r8
movq %r14, %rbx
movq %rbp, %r12
testq %r14, %r14
jne 0x11085
jmp 0x11285
movq 0x10(%rbx), %rax
movq 0x8(%rax), %rdi
cmpl $0xd, (%rdi)
jne 0x11239
movq %r8, %r15
movq 0x20(%rdi), %rdi
jmp 0x1123c
movq %r8, %r15
callq 0x102ec
shrl $0x8, %eax
movsbl %al, %esi
leaq 0x48d5(%rip), %rdi      # 0x15b23
xorl %eax, %eax
callq 0x30b0
movq 0x8(%rbx), %rsi
movq 0x10(%rbx), %rdi
subq (%rbx), %rsi
callq 0x11378
movq 0x9d54(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x4864(%rip), %rdi      # 0x15ada
callq 0x30f0
movq %r15, %r8
jmp 0x11212
xorl %ebp, %ebp
xorl %r8d, %r8d
testq %r8, %r8
je 0x1129e
leaq 0x4845(%rip), %rdi      # 0x15ad6
movl %r8d, %esi
xorl %eax, %eax
callq 0x30b0
incq %rbp
movq (%rsp), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rsi
subq %rbp, %rsi
jb 0x11359
jbe 0x112c3
leaq 0x4883(%rip), %rdi      # 0x15b3f
xorl %eax, %eax
callq 0x30b0
leaq 0x3fe4(%rip), %rdi      # 0x152ae
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3050
leaq 0x478a(%rip), %rdi      # 0x15a6e
leaq 0x4569(%rip), %rsi      # 0x15854
leaq 0x479a(%rip), %rcx      # 0x15a8c
movl $0x58b, %edx            # imm = 0x58B
callq 0x30e0
leaq 0x47b5(%rip), %rdi      # 0x15ab8
leaq 0x454a(%rip), %rsi      # 0x15854
leaq 0x477b(%rip), %rcx      # 0x15a8c
movl $0x58c, %edx            # imm = 0x58C
callq 0x30e0
leaq 0x47c4(%rip), %rdi      # 0x15ae6
leaq 0x452b(%rip), %rsi      # 0x15854
leaq 0x475c(%rip), %rcx      # 0x15a8c
movl $0x59f, %edx            # imm = 0x59F
callq 0x30e0
leaq 0x47c5(%rip), %rdi      # 0x15b06
leaq 0x450c(%rip), %rsi      # 0x15854
leaq 0x473d(%rip), %rcx      # 0x15a8c
movl $0x5a0, %edx            # imm = 0x5A0
callq 0x30e0
leaq 0x47c7(%rip), %rdi      # 0x15b27
leaq 0x44ed(%rip), %rsi      # 0x15854
leaq 0x471e(%rip), %rcx      # 0x15a8c
movl $0x5b8, %edx            # imm = 0x5B8
callq 0x30e0