// File: /workspace/github_cpp_makefile_star2_O3/Gammelkebab[P]GameOfLife/src/world/block.cpp
// Function: Block::Block(World*, int)
Block::Block(World *world, int block_num) : world(world), block_num(block_num)
{
    x = block_num % world->cols;
    y = block_num / world->cols;

    first_row = y == 0;
    first_col = x == 0;
    last_row = y == world->rows - 1;
    last_col = x == world->cols - 1;

    /* Calculate the pixels assigned to this block
     * - Takes care of 8 bit allignment
     * - Takes care of additional pixels from remainder of splitting
     */
    width = world->width / world->cols;
    width -= width % 8;

    /*
     * The remainder after assigning full 8 bit blocks
     * This value is always < world->cols * 8
     * distribute all full 8 bit blocks of the remainder to the first blocks, 
     * then the remaining bits to the last block
     */
    int remainder_x = world->width % (world->cols * 8);
    if (x < remainder_x / 8)
    {
        width += 8;
    }
    if (last_col)
    {
        width += remainder_x % 8;
    }

    // the same for the height
    height = world->height / world->rows;
    height -= height % 8;
    int remainder_y = world->height % (world->rows * 8);
    if (y < remainder_y / 8)
    {
        height += 8;
    }
    if (last_row)
    {
        height += remainder_y % 8;
    }

    // calculate the position of the first (upper left) pixel assigned to this block
    // takes care of additional pixels from remainder of splitting
    starting_x = world->width / world->cols;
    starting_x -= starting_x % 8;
    starting_x *= x;
    starting_x += min(remainder_x / 8, x) * 8; // add all horizontal remainder pixels before this block
    starting_y = world->height / world->rows;
    starting_y -= starting_y % 8;
    starting_y *= y;
    starting_y += min(remainder_y / 8, y) * 8; // add all vertical remainder pixels before this block

    // Create the write buffer grid, containing compressed information about the block
    // 8 Pixels are compressed into one byte
    width_byte = width / 8 + (width % 8 == 0 ? 0 : 1);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
movl %edx, %eax
movq %rsi, (%rdi)
movl %edx, 0x8(%rdi)
movl 0x10(%rsi), %ebx
cltd
idivl %ebx
movl %eax, %ecx
movl %edx, %r9d
movl %edx, 0xc(%rdi)
movl %eax, 0x10(%rdi)
testl %eax, %eax
sete 0x28(%rdi)
testl %edx, %edx
sete 0x29(%rdi)
movl 0xc(%rsi), %r14d
leal -0x1(%r14), %r10d
cmpl %r10d, %eax
sete 0x2a(%rdi)
leal -0x1(%rbx), %ebp
cmpl %ebp, %edx
sete 0x2b(%rdi)
movl (%rsi), %r8d
movl %r8d, %eax
cltd
idivl %ebx
leal 0x7(%rax), %r11d
testl %eax, %eax
cmovnsl %eax, %r11d
andl $-0x8, %r11d
shll $0x3, %ebx
movl %r8d, %eax
cltd
idivl %ebx
movl %edx, %r8d
leal 0x7(%r8), %ebx
testl %edx, %edx
cmovnsl %edx, %ebx
movl %ebx, %eax
andl $-0x8, %eax
subl %eax, %r8d
sarl $0x3, %ebx
leal 0x8(%r11), %eax
cmpl %ebx, %r9d
cmovgel %r11d, %eax
addl %eax, %r8d
cmpl %ebp, %r9d
cmovnel %eax, %r8d
movl %r8d, 0x1c(%rdi)
movl 0x4(%rsi), %esi
movl %esi, %eax
cltd
idivl %r14d
leal 0x7(%rax), %r15d
testl %eax, %eax
cmovnsl %eax, %r15d
andl $-0x8, %r15d
shll $0x3, %r14d
movl %esi, %eax
cltd
idivl %r14d
leal 0x7(%rdx), %eax
testl %edx, %edx
cmovnsl %edx, %eax
movl %eax, %esi
andl $-0x8, %esi
subl %esi, %edx
sarl $0x3, %eax
leal 0x8(%r15), %esi
cmpl %eax, %ecx
cmovgel %r15d, %esi
addl %esi, %edx
cmpl %r10d, %ecx
cmovnel %esi, %edx
movl %edx, 0x20(%rdi)
imull %r9d, %r11d
cmpl %r9d, %ebx
cmovgel %r9d, %ebx
leal (%r11,%rbx,8), %edx
movl %edx, 0x14(%rdi)
imull %ecx, %r15d
cmpl %ecx, %eax
cmovgel %ecx, %eax
leal (%r15,%rax,8), %eax
movl %eax, 0x18(%rdi)
leal 0x7(%r8), %eax
testl %r8d, %r8d
cmovnsl %r8d, %eax
sarl $0x3, %eax
andl $0x7, %r8d
cmpl $0x1, %r8d
sbbl $-0x1, %eax
movl %eax, 0x24(%rdi)
popq %rbx
popq %r14
popq %r15
popq %rbp
retq