// File: /workspace/github_cpp_makefile_star2_O3/Gammelkebab[P]GameOfLife/src/world/world.cpp
// Function: World::World(int, int, int, int, double)
World::World(int width, int height, int proc_amt, int total_rounds, double worker_share) : width(width), height(height), total_rounds(total_rounds)
{
    width_byte = width / 8 + (width % 8 == 0 ? 0 : 1);

    // Never have noone or everyone at work
    int worker_amt_tmp = btw(proc_amt * worker_share, 1, proc_amt - 1);

    // Distributes rows and columns proportionally to the overall pixel aspect ratio
    float rows_tmp = sqrt(worker_amt_tmp * ((float)height / width));
    rows = floor(rows_tmp);
    cols = floor(worker_amt_tmp / rows_tmp);

    // Try to create one more row or column (Might be possible due to flooring)
    int r1 = (rows + 1) * cols;
    int c1 = rows * (cols + 1);
    if (r1 <= proc_amt && c1 <= proc_amt)
    {
        if (r1 > c1)
        {
            rows++;
        }
        else
        {
            cols++;
        }
    }
    else if (r1 <= proc_amt)
    {
        rows++;
    }
    else if (c1 <= proc_amt)
    {
        cols++;
    }

    block_amt = rows * cols;
    worker_amt = block_amt; // There is one worker for every block
    writer_amt = proc_amt - worker_amt;

    // TODO
    // This enables scattering the writers amongst cores,
    // as long as the processor-core-distribution is known
    writer_nums = new int[writer_amt];
    for (int w = 0; w < writer_amt; w++)
    {
        writer_nums[w] = w + worker_amt; // Put writers behind workers
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movl %ecx, %ebx
movq %rdi, %r14
movl %esi, (%rdi)
leal 0x7(%rsi), %eax
testl %esi, %esi
cmovnsl %esi, %eax
movl %edx, 0x4(%rdi)
cvtsi2ss %esi, %xmm1
sarl $0x3, %eax
movl %esi, %ecx
andl $0x7, %ecx
cmpl $0x1, %ecx
sbbl $-0x1, %eax
cvtsi2sd %ebx, %xmm2
movl %r8d, 0x28(%rdi)
mulsd %xmm0, %xmm2
cvttsd2si %xmm2, %ecx
leal -0x1(%rbx), %esi
cmpl %esi, %ecx
cmovll %ecx, %esi
cmpl $0x2, %esi
movl $0x1, %ecx
cmovgel %esi, %ecx
movl %eax, 0x8(%rdi)
xorps %xmm2, %xmm2
cvtsi2ss %ecx, %xmm2
xorps %xmm0, %xmm0
cvtsi2ss %edx, %xmm0
divss %xmm1, %xmm0
movss %xmm2, 0x4(%rsp)
mulss %xmm2, %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jb 0x3ab4
sqrtss %xmm0, %xmm0
jmp 0x3ab9
callq 0x2240
movss %xmm0, (%rsp)
callq 0x2080
cvttss2si %xmm0, %r12d
movl %r12d, 0xc(%r14)
movss 0x4(%rsp), %xmm0
divss (%rsp), %xmm0
callq 0x2080
cvttss2si %xmm0, %eax
movl %eax, 0x10(%r14)
leal 0x1(%r12), %edx
movl %edx, %r15d
imull %eax, %r15d
leal 0x1(%rax), %esi
movl %esi, %ecx
imull %r12d, %ecx
cmpl %ebx, %r15d
jg 0x3b09
cmpl %ebx, %ecx
jg 0x3b09
cmpl %ecx, %r15d
jg 0x3b1b
jmp 0x3b21
cmpl %ebx, %r15d
jle 0x3b1b
cmpl %ebx, %ecx
jle 0x3b21
imull %r12d, %eax
movl %eax, %r15d
jmp 0x3b28
movl %edx, 0xc(%r14)
jmp 0x3b28
movl %esi, 0x10(%r14)
movl %ecx, %r15d
movl %r15d, 0x14(%r14)
movl %r15d, 0x18(%r14)
subl %r15d, %ebx
movl %ebx, 0x1c(%r14)
movslq %ebx, %r12
leaq (,%r12,4), %rax
testl %r12d, %r12d
movq $-0x1, %rdi
cmovnsq %rax, %rdi
callq 0x2030
movq %rax, 0x20(%r14)
testl %r12d, %r12d
jle 0x3c03
movl %ebx, %ecx
incl %ebx
decq %rcx
movq %rcx, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
andl $-0x2, %ebx
negq %rbx
movdqa 0x69f(%rip), %xmm1      # 0x4220
movl $0x1, %ecx
movdqa 0x6a2(%rip), %xmm2      # 0x4230
pxor %xmm2, %xmm0
pcmpeqd %xmm3, %xmm3
movdqa 0x6a2(%rip), %xmm4      # 0x4240
movdqa %xmm1, %xmm5
pxor %xmm2, %xmm5
movdqa %xmm5, %xmm6
pcmpgtd %xmm0, %xmm6
pcmpeqd %xmm0, %xmm5
pshufd $0xf5, %xmm5, %xmm7     # xmm7 = xmm5[1,1,3,3]
pand %xmm6, %xmm7
pshufd $0xf5, %xmm6, %xmm5     # xmm5 = xmm6[1,1,3,3]
por %xmm7, %xmm5
movd %xmm5, %edx
notl %edx
testb $0x1, %dl
je 0x3bd4
movl %r15d, -0x4(%rax,%rcx,4)
pxor %xmm3, %xmm5
pextrw $0x4, %xmm5, %edx
testb $0x1, %dl
je 0x3be9
leal 0x1(%r15), %edx
movl %edx, (%rax,%rcx,4)
paddq %xmm4, %xmm1
leaq (%rbx,%rcx), %rdx
addq $0x2, %rdx
addq $0x2, %rcx
addl $0x2, %r15d
cmpq $0x1, %rdx
jne 0x3b9e
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
nop