// File: /workspace/github_c_makefile_star2_O3/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, %r12
movq %rdi, %r14
movl 0x40(%rdi), %ebp
testq %rsi, %rsi
je 0x11025
movq %r12, %rbx
movq 0x10(%rbx), %rdi
callq 0x603c
movq %rax, 0x10(%rbx)
movq 0x20(%rbx), %rbx
testq %rbx, %rbx
jne 0x1100f
cmpl $0x1, 0x44(%r14)
jne 0x11042
movq 0x9f8d(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x4aac(%rip), %rdi      # 0x15ae9
callq 0x30f0
cmpl $0x2, 0xc(%r14)
jne 0x1105f
movq 0x9f70(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x4a97(%rip), %rdi      # 0x15af1
callq 0x30f0
movq 0x9f5a(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x4a89(%rip), %rdi      # 0x15af9
callq 0x30f0
movq 0x20(%r14), %rdi
callq 0x10edd
leaq 0x4a7a(%rip), %rdi      # 0x15aff
movl %ebp, %esi
xorl %eax, %eax
callq 0x30b0
testq %r12, %r12
je 0x112f9
movq %r14, (%rsp)
xorl %ebx, %ebx
xorl %r8d, %r8d
movq 0x20(%r12), %r14
testq %r14, %r14
je 0x11140
movq (%r14), %rax
movswq 0x18(%r14), %rcx
leaq (%rcx,%rax,8), %rcx
movq 0x8(%r12), %rdx
shlq $0x3, %rdx
movswq 0x1a(%r12), %rsi
subq %rsi, %rdx
cmpq %rdx, %rcx
jae 0x11143
movq 0x10(%r12), %rcx
cmpl $0x2, (%rcx)
jne 0x11330
movq 0x10(%r14), %rsi
cmpl $0x1, (%rsi)
jne 0x1134f
subq (%r12), %rax
movq 0x8(%rcx), %rdx
movq 0x20(%rdx), %rdx
movq 0x10(%rdx), %rdi
xorl %edx, %edx
divq %rdi
cmpq $0x4, %rdi
je 0x1112d
cmpq $0x2, %rdi
je 0x1111f
cmpq $0x1, %rdi
jne 0x11137
movb 0x30(%rsi), %dl
movq 0x38(%rcx), %rcx
movb %dl, (%rcx,%rax)
jmp 0x11137
movzwl 0x30(%rsi), %edx
movq 0x38(%rcx), %rcx
movw %dx, (%rcx,%rax,2)
jmp 0x11137
movl 0x30(%rsi), %edx
movq 0x38(%rcx), %rcx
movl %edx, (%rcx,%rax,4)
movq 0x20(%r14), %r14
jmp 0x110a5
xorl %r14d, %r14d
movl 0x18(%r12), %eax
leal 0x7(%rax), %ecx
testw %ax, %ax
cmovnsl %eax, %ecx
movswl %cx, %eax
shrl $0x3, %eax
movswq %ax, %r13
addq (%r12), %r13
movq 0x8(%r12), %rbp
movswl 0x1a(%r12), %r15d
leal 0x7(%r15), %eax
addl $0xe, %r15d
testl %eax, %eax
cmovnsl %eax, %r15d
cmpq %r13, %rbx
jae 0x11199
testq %r8, %r8
je 0x11199
leaq 0x49ed(%rip), %rdi      # 0x15b76
movl %r8d, %esi
xorl %eax, %eax
callq 0x30b0
incq %rbx
xorl %r8d, %r8d
movq %r13, %rsi
subq %rbx, %rsi
jbe 0x111b5
leaq 0x49d5(%rip), %rdi      # 0x15b7d
xorl %eax, %eax
movq %r8, %rbx
callq 0x30b0
movq %rbx, %r8
sarl $0x3, %r15d
movslq %r15d, %rax
subq %rax, %rbp
movzwl 0x18(%r12), %ecx
testw %cx, %cx
jne 0x111d3
cmpw $0x0, 0x1a(%r12)
je 0x11252
movq 0x10(%r12), %rax
movq 0x8(%rax), %rdx
testb $0x2, 0x4(%rdx)
leaq 0x498f(%rip), %r15      # 0x15b76
je 0x1138d
cmpl $0x1, (%rax)
jne 0x1136e
movq 0x30(%rax), %rbx
leal 0x7(%rcx), %eax
testw %cx, %cx
cmovnsl %ecx, %eax
andl $0xf8, %eax
subl %eax, %ecx
shlq %cl, %rbx
orq %r8, %rbx
cmpq %rbp, %r13
jae 0x1122b
movzbl %bl, %esi
movq %r15, %rdi
xorl %eax, %eax
callq 0x30b0
incq %r13
shrq $0x8, %rbx
jmp 0x11210
movb 0x1a(%r12), %cl
decb %cl
andb $0x7, %cl
movl $0x7f, %eax
shrl %cl, %eax
andl %eax, %ebx
movq %rbx, %r8
movq %r14, %r12
movq %rbp, %rbx
testq %r14, %r14
jne 0x110a0
jmp 0x112b0
movq 0x10(%r12), %rax
movq 0x8(%rax), %rdi
cmpl $0xd, (%rdi)
jne 0x11269
movq %r8, %rbx
movq 0x20(%rdi), %rdi
jmp 0x1126c
movq %r8, %rbx
callq 0x102e0
shrl $0x8, %eax
movsbl %al, %esi
leaq 0x4945(%rip), %rdi      # 0x15bc3
xorl %eax, %eax
callq 0x30b0
movq 0x8(%r12), %rsi
movq 0x10(%r12), %rdi
subq (%r12), %rsi
callq 0x113ac
movq 0x9d21(%rip), %rax      # 0x1afc0
movq (%rax), %rsi
leaq 0x48d1(%rip), %rdi      # 0x15b7a
callq 0x30f0
jmp 0x1123e
testq %r8, %r8
je 0x112c9
leaq 0x48ba(%rip), %rdi      # 0x15b76
movl %r8d, %esi
xorl %eax, %eax
callq 0x30b0
incq %rbp
movq (%rsp), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rsi
cmpq %rsi, %rbp
jbe 0x11303
leaq 0x48e6(%rip), %rdi      # 0x15bc7
leaq 0x460c(%rip), %rsi      # 0x158f4
leaq 0x483d(%rip), %rcx      # 0x15b2c
movl $0x5b8, %edx            # imm = 0x5B8
callq 0x30e0
movq 0x10(%r14), %rax
movq 0x10(%rax), %rsi
xorl %ebp, %ebp
subq %rbp, %rsi
jbe 0x11316
leaq 0x48d0(%rip), %rdi      # 0x15bdf
xorl %eax, %eax
callq 0x30b0
leaq 0x4029(%rip), %rdi      # 0x15346
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3050
leaq 0x47d7(%rip), %rdi      # 0x15b0e
leaq 0x45b6(%rip), %rsi      # 0x158f4
leaq 0x47e7(%rip), %rcx      # 0x15b2c
movl $0x58b, %edx            # imm = 0x58B
callq 0x30e0
leaq 0x4802(%rip), %rdi      # 0x15b58
leaq 0x4597(%rip), %rsi      # 0x158f4
leaq 0x47c8(%rip), %rcx      # 0x15b2c
movl $0x58c, %edx            # imm = 0x58C
callq 0x30e0
leaq 0x4831(%rip), %rdi      # 0x15ba6
leaq 0x4578(%rip), %rsi      # 0x158f4
leaq 0x47a9(%rip), %rcx      # 0x15b2c
movl $0x5a0, %edx            # imm = 0x5A0
callq 0x30e0
leaq 0x47f2(%rip), %rdi      # 0x15b86
leaq 0x4559(%rip), %rsi      # 0x158f4
leaq 0x478a(%rip), %rcx      # 0x15b2c
movl $0x59f, %edx            # imm = 0x59F
callq 0x30e0