// File: /workspace/github_c_makefile_star2_O2/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
subq $0x18, %rsp
movq %rsi, %r12
movq %rdi, %r14
movl 0x40(%rdi), %ebp
movq %rsi, %rbx
testq %rbx, %rbx
je 0xf9dc
movq 0x10(%rbx), %rdi
callq 0x5d00
movq %rax, 0x10(%rbx)
movq 0x20(%rbx), %rbx
jmp 0xf9c4
cmpl $0x1, 0x44(%r14)
jne 0xf9f9
movq 0xb5d6(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x50b9(%rip), %rdi      # 0x14aad
callq 0x30f0
cmpl $0x2, 0xc(%r14)
jne 0xfa16
movq 0xb5b9(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x50a4(%rip), %rdi      # 0x14ab5
callq 0x30f0
movq 0xb5a3(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x5096(%rip), %rdi      # 0x14abd
callq 0x30f0
movq %r14, 0x10(%rsp)
movq 0x20(%r14), %rdi
callq 0xf896
leaq 0x5082(%rip), %rdi      # 0x14ac3
movl %ebp, %esi
xorl %eax, %eax
callq 0x30b0
leaq 0x50e9(%rip), %r15      # 0x14b3a
xorl %r8d, %r8d
xorl %ebp, %ebp
testq %r12, %r12
je 0xfc69
movq %r12, %r14
movq 0x20(%r14), %r14
movq 0x8(%r12), %rbx
movswq 0x1a(%r12), %rcx
testq %r14, %r14
je 0xfb07
movq (%r14), %rax
movswq 0x18(%r14), %rdx
leaq (%rdx,%rax,8), %rdx
leaq (,%rbx,8), %rsi
subq %rcx, %rsi
cmpq %rsi, %rdx
jae 0xfb07
movq 0x10(%r12), %rcx
cmpl $0x2, (%rcx)
jne 0xfce1
movq 0x10(%r14), %rsi
cmpl $0x1, (%rsi)
jne 0xfcc2
subq (%r12), %rax
movq 0x8(%rcx), %rdx
movq 0x20(%rdx), %rdx
movq 0x10(%rdx), %rdi
xorl %edx, %edx
divq %rdi
cmpq $0x4, %rdi
je 0xfaf8
cmpq $0x2, %rdi
je 0xfae7
cmpq $0x1, %rdi
jne 0xfa62
movb 0x30(%rsi), %dl
movq 0x38(%rcx), %rcx
movb %dl, (%rcx,%rax)
jmp 0xfa62
movzwl 0x30(%rsi), %edx
movq 0x38(%rcx), %rcx
movw %dx, (%rcx,%rax,2)
jmp 0xfa62
movl 0x30(%rsi), %edx
movq 0x38(%rcx), %rcx
movl %edx, (%rcx,%rax,4)
jmp 0xfa62
movzwl 0x18(%r12), %eax
cwtd
movw $0x8, %si
idivw %si
movswq %ax, %r13
addq (%r12), %r13
addl $0x7, %ecx
movl %ecx, %eax
cltd
pushq $0x8
popq %rcx
idivl %ecx
cmpq %r13, %rbp
jae 0xfb54
testq %r8, %r8
je 0xfb54
movq %r15, %rdi
movl %r8d, %esi
movq %rbp, 0x8(%rsp)
movl %eax, %ebp
xorl %eax, %eax
callq 0x30b0
movl %ebp, %eax
movq 0x8(%rsp), %rbp
incq %rbp
xorl %r8d, %r8d
movq %r13, %rsi
subq %rbp, %rsi
jbe 0xfb78
leaq 0x4fde(%rip), %rdi      # 0x14b41
movl %eax, 0x8(%rsp)
xorl %eax, %eax
movq %r8, %rbp
callq 0x30b0
movl 0x8(%rsp), %eax
movq %rbp, %r8
cltq
subq %rax, %rbx
movzwl 0x18(%r12), %eax
testw %ax, %ax
je 0xfb8f
movq 0x10(%r12), %rcx
jmp 0xfb9d
cmpw $0x0, 0x1a(%r12)
movq 0x10(%r12), %rcx
je 0xfc04
movq 0x8(%rcx), %rdx
testb $0x2, 0x4(%rdx)
je 0xfd00
cmpl $0x1, (%rcx)
jne 0xfd1f
cwtd
movq 0x30(%rcx), %rbp
movw $0x8, %cx
idivw %cx
movl %edx, %ecx
shlq %cl, %rbp
orq %r8, %rbp
cmpq %rbx, %r13
jae 0xfbe5
movzbl %bpl, %esi
movq %r15, %rdi
xorl %eax, %eax
callq 0x30b0
incq %r13
shrq $0x8, %rbp
jmp 0xfbc9
movb 0x1a(%r12), %cl
decb %cl
andb $0x7, %cl
pushq $0x7f
popq %rax
shrl %cl, %eax
andl %eax, %ebp
movq %rbp, %r8
movq %rbx, %rbp
movq %r14, %r12
jmp 0xfa56
movq 0x8(%rcx), %rdi
cmpl $0xd, (%rdi)
jne 0xfc16
movq %r8, %r13
movq 0x20(%rdi), %rdi
jmp 0xfc19
movq %r8, %r13
callq 0xee06
shrl $0x8, %eax
movsbl %al, %esi
leaq 0x4f5c(%rip), %rdi      # 0x14b87
xorl %eax, %eax
callq 0x30b0
movq 0x8(%r12), %rsi
movq 0x10(%r12), %rdi
subq (%r12), %rsi
callq 0xfd5d
movq 0xb374(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x4ee8(%rip), %rdi      # 0x14b3e
callq 0x30f0
movq %rbx, %rbp
movq %r14, %r12
movq %r13, %r8
jmp 0xfa56
testq %r8, %r8
je 0xfc82
leaq 0x4ec5(%rip), %rdi      # 0x14b3a
movl %r8d, %esi
xorl %eax, %eax
callq 0x30b0
incq %rbp
movq 0x10(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rsi
subq %rbp, %rsi
jb 0xfd3e
jbe 0xfca8
leaq 0x4f02(%rip), %rdi      # 0x14ba3
xorl %eax, %eax
callq 0x30b0
leaq 0x465f(%rip), %rdi      # 0x1430e
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3050
leaq 0x4e53(%rip), %rdi      # 0x14b1c
leaq 0x4be8(%rip), %rsi      # 0x148b8
leaq 0x4e19(%rip), %rcx      # 0x14af0
movl $0x58c, %edx            # imm = 0x58C
callq 0x30e0
leaq 0x4dea(%rip), %rdi      # 0x14ad2
leaq 0x4bc9(%rip), %rsi      # 0x148b8
leaq 0x4dfa(%rip), %rcx      # 0x14af0
movl $0x58b, %edx            # imm = 0x58B
callq 0x30e0
leaq 0x4e43(%rip), %rdi      # 0x14b4a
leaq 0x4baa(%rip), %rsi      # 0x148b8
leaq 0x4ddb(%rip), %rcx      # 0x14af0
movl $0x59f, %edx            # imm = 0x59F
callq 0x30e0
leaq 0x4e44(%rip), %rdi      # 0x14b6a
leaq 0x4b8b(%rip), %rsi      # 0x148b8
leaq 0x4dbc(%rip), %rcx      # 0x14af0
movl $0x5a0, %edx            # imm = 0x5A0
callq 0x30e0
leaq 0x4e46(%rip), %rdi      # 0x14b8b
leaq 0x4b6c(%rip), %rsi      # 0x148b8
leaq 0x4d9d(%rip), %rcx      # 0x14af0
movl $0x5b8, %edx            # imm = 0x5B8
callq 0x30e0