// File: vsklad[P]cgen/./bal/variables/variablesio.cpp
// Function: bal::operator<<(std::ostream&, bal::VariablesArray const&)
std::ostream& operator << (std::ostream& stream, const VariablesArray& array) {
        const variableid_t size = array.size();
        const variableid_t element_size = array.element_size();
        const variableid_t elements_size = size / element_size;
        
        assert(elements_size * element_size == size);
        
        const literalid_t* literalid = array.data();
        bool bracket_1_open = false;
        
        size_t i = 0;
        while (i < elements_size) {
            if (i > 0) {
                stream << ", ";
            };
            
            // check and process the possible sequence of elements
            size_t elements_sequence_size = 1;
            int elements_sequence_step = 0;
            get_variables_range_sequence_(literalid, size - (i * element_size), element_size,
                                                    elements_sequence_size, elements_sequence_step);
            
            if (i == 0 && !bracket_1_open && size > element_size * elements_sequence_size) {
                stream << "{";
                bracket_1_open = true;
            };

            bool bracket_2_open = false;
            
            size_t j = 0;
            while(j < element_size) {
                size_t k;
                
                // output constant as much as possible, limit to 64 bit, align to 4 bits
                // look ahead bit by bit and compress
                uint64_t constant = 0;
                k = 0;
                while ((k < 64) && (j + k) < element_size) {
                    if (literal_t__is_constant(*(literalid + k))) {
                        constant = (constant << 1) | (literal_t__is_constant_1(*(literalid + k)) ? 1 : 0);
                        k++;
                        continue;
                    };
                    break;
                };
                if (k > 0) {
                    // constants that have number of bits mod 4 != 0, require brackets
                    // because they are split into bin and hex
                    if (j == 0 && ((k < element_size) || (k > 3 && k % 4 != 0)) && !bracket_2_open) {
                        stream << "{";
                        bracket_2_open = true;
                    } else if (j > 0) {
                        stream << ", ";
                    };
                    
                    // output the most significant bits to align to 4 from the lower end of the element
                    // if less than 4 bits total, output everything here
                    const size_t k_prefix = (k <= 3) ? k : ((element_size - j) & 0x3);
                    if (k_prefix > 0 && k > 0) {
                        uint64_t prefix_constant = constant >> (k > k_prefix ? k - k_prefix : 0);
                        stream << "0b";
                        stream << ((k_prefix > 2 && k > 2) ? (prefix_constant & 0b100) ? "1" : "0" : "");
                        stream << ((k_prefix > 1 && k > 1) ? (prefix_constant & 0b010) ? "1" : "0" : "");
                        stream <<                           ((prefix_constant & 0b001) ? "1" : "0");
                        // zero out b_prefix most significant bits
                        constant &= 0xFFFFFFFFFFFFFFFFull >> (64 - k + k_prefix);
                    };
                    
                    if (k > k_prefix) {
                        const size_t k_suffix = (k - k_prefix) & 0x3;
                        if (k - k_prefix > k_suffix) {
                            // output the main part of the constant aligned to 4 bits
                            if (k_prefix > 0) {
                                stream << ", "; // separate from the prefix
                            };
                            stream << "0x" << std::setfill('0') << std::setw((int)((k - k_prefix) >> 2));
                            stream << std::hex << (constant >> k_suffix);
                        };
                        
                        if (k_suffix > 0) {
                            // output the remaining least significant bits
                            if (k > k_suffix) {
                                stream << ", "; // separate from the hex constant
                            };
                            stream << "0b";
                            stream << (k_suffix > 2 ? (constant & 0b100) ? "1" : "0" : "");
                            stream << (k_suffix > 1 ? (constant & 0b010) ? "1" : "0" : "");
                            stream <<                ((constant & 0b001) ? "1" : "0");
                        };
                    };
                    
                    // skip the processed literals
                    literalid += k;
                    j += k;
                };
                
                // output variables as much as possible; compress sequential
                int sequence_step = 0;
                get_variables_sequence_(literalid, element_size - j, k, sequence_step);
                
                // elements_sequence_size == 1 && k > 1 means the sequence is within element
                // therefore must be bracketed in order to avoid confusion
                if (i == 0 && j == 0 && !bracket_1_open && elements_sequence_size == 1 && k > 1) {
                    stream << "{";
                    bracket_1_open = true;
                };
                
                if (k > 0) {
                    // k < element_size means there are more elements to output
                    // k > 1 sequence within element must always be bracketed
                    if (!bracket_2_open && j == 0 && (k < element_size || k > 1)) {
                        stream << "{";
                        bracket_2_open = true;
                    } else if (j > 0) {
                        stream << ", ";
                    };
                    stream << literal_t(*literalid);
                    write_sequence_parameters_(stream, k, sequence_step);
                    // skip the processed literals
                    literalid += k;
                    j += k;
                };
            };
            
            if (bracket_2_open) {
                stream << "}";
            };
            
            write_sequence_parameters_(stream, elements_sequence_size, elements_sequence_step);
            
            // skip processed elements
            i += elements_sequence_size;
            literalid += (elements_sequence_size - 1) * element_size;
        };
        
        if (bracket_1_open) {
            stream << "}";
        };
        return stream;
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x102f0
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2e1a0
movl %eax, -0x18(%rbp)
movl -0x14(%rbp), %eax
xorl %edx, %edx
divl -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
imull -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
jne 0x59014
jmp 0x59033
leaq 0xf52e(%rip), %rdi      # 0x68549
leaq 0xf54c(%rip), %rsi      # 0x6856e
movl $0x81, %edx
leaq 0xf560(%rip), %rcx      # 0x6858e
callq 0xd1c0
movq -0x10(%rbp), %rdi
callq 0x2e180
movq %rax, -0x28(%rbp)
movb $0x0, -0x29(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movl -0x1c(%rbp), %ecx
cmpq %rcx, %rax
jae 0x597a1
cmpq $0x0, -0x38(%rbp)
jbe 0x59073
movq -0x8(%rbp), %rdi
leaq 0x9354(%rip), %rsi      # 0x623c2
callq 0xd320
movq $0x1, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movq -0x28(%rbp), %rdi
movl -0x14(%rbp), %eax
movl %eax, %esi
movq -0x38(%rbp), %rax
movl -0x18(%rbp), %ecx
imulq %rcx, %rax
subq %rax, %rsi
movl -0x18(%rbp), %eax
movl %eax, %edx
leaq -0x40(%rbp), %rcx
leaq -0x44(%rbp), %r8
callq 0x59860
cmpq $0x0, -0x38(%rbp)
jne 0x590dc
testb $0x1, -0x29(%rbp)
jne 0x590dc
movl -0x14(%rbp), %eax
movl -0x18(%rbp), %ecx
imulq -0x40(%rbp), %rcx
cmpq %rcx, %rax
jbe 0x590dc
movq -0x8(%rbp), %rdi
leaq 0xb40d(%rip), %rsi      # 0x644e0
callq 0xd320
movb $0x1, -0x29(%rbp)
movb $0x0, -0x45(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movl -0x18(%rbp), %ecx
cmpq %rcx, %rax
jae 0x5974f
movq $0x0, -0x60(%rbp)
movq $0x0, -0x58(%rbp)
xorl %eax, %eax
cmpq $0x40, -0x58(%rbp)
movb %al, -0x89(%rbp)
jae 0x5912e
movq -0x50(%rbp), %rax
addq -0x58(%rbp), %rax
movl -0x18(%rbp), %ecx
cmpq %rcx, %rax
setb %al
movb %al, -0x89(%rbp)
movb -0x89(%rbp), %al
testb $0x1, %al
jne 0x5913a
jmp 0x59181
movq -0x28(%rbp), %rax
movq -0x58(%rbp), %rcx
cmpl $0x1, (%rax,%rcx,4)
ja 0x5917f
movq -0x60(%rbp), %rax
shlq %rax
movq -0x28(%rbp), %rcx
movq -0x58(%rbp), %rdx
movl (%rcx,%rdx,4), %esi
xorl %ecx, %ecx
movl $0x1, %edx
cmpl $0x1, %esi
cmovel %edx, %ecx
movslq %ecx, %rcx
orq %rcx, %rax
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x59108
jmp 0x59181
cmpq $0x0, -0x58(%rbp)
jbe 0x59634
cmpq $0x0, -0x50(%rbp)
jne 0x591d0
movq -0x58(%rbp), %rax
movl -0x18(%rbp), %ecx
cmpq %rcx, %rax
jb 0x591b4
cmpq $0x3, -0x58(%rbp)
jbe 0x591d0
movq -0x58(%rbp), %rax
andq $0x3, %rax
cmpq $0x0, %rax
je 0x591d0
testb $0x1, -0x45(%rbp)
jne 0x591d0
movq -0x8(%rbp), %rdi
leaq 0xb31b(%rip), %rsi      # 0x644e0
callq 0xd320
movb $0x1, -0x45(%rbp)
jmp 0x591e9
cmpq $0x0, -0x50(%rbp)
jbe 0x591e7
movq -0x8(%rbp), %rdi
leaq 0x91e0(%rip), %rsi      # 0x623c2
callq 0xd320
jmp 0x591e9
cmpq $0x3, -0x58(%rbp)
ja 0x591fd
movq -0x58(%rbp), %rax
movq %rax, -0x98(%rbp)
jmp 0x5920f
movl -0x18(%rbp), %eax
subq -0x50(%rbp), %rax
andq $0x3, %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0x68(%rbp)
cmpq $0x0, -0x68(%rbp)
jbe 0x593e5
cmpq $0x0, -0x58(%rbp)
jbe 0x593e5
movq -0x60(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x68(%rbp), %rax
jbe 0x59256
movq -0x58(%rbp), %rax
subq -0x68(%rbp), %rax
movq %rax, -0xa8(%rbp)
jmp 0x59261
xorl %eax, %eax
movq %rax, -0xa8(%rbp)
jmp 0x59261
movq -0xa0(%rbp), %rax
movq -0xa8(%rbp), %rcx
shrq %cl, %rax
movq %rax, -0x70(%rbp)
movq -0x8(%rbp), %rdi
leaq 0xf353(%rip), %rsi      # 0x685d4
callq 0xd320
movq -0x8(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpq $0x2, -0x68(%rbp)
jbe 0x592dd
cmpq $0x2, -0x58(%rbp)
jbe 0x592dd
movq -0x70(%rbp), %rax
andq $0x4, %rax
cmpq $0x0, %rax
je 0x592bd
leaq 0x2080(%rip), %rax      # 0x5b334
movq %rax, -0xb8(%rbp)
jmp 0x592cd
leaq 0x422a(%rip), %rax      # 0x5d4ee
movq %rax, -0xb8(%rbp)
jmp 0x592cd
movq -0xb8(%rbp), %rax
movq %rax, -0xc0(%rbp)
jmp 0x592ed
leaq 0xf0d8(%rip), %rax      # 0x683bc
movq %rax, -0xc0(%rbp)
jmp 0x592ed
movq -0xb0(%rbp), %rdi
movq -0xc0(%rbp), %rsi
callq 0xd320
movq -0x8(%rbp), %rax
movq %rax, -0xc8(%rbp)
cmpq $0x1, -0x68(%rbp)
jbe 0x59357
cmpq $0x1, -0x58(%rbp)
jbe 0x59357
movq -0x70(%rbp), %rax
andq $0x2, %rax
cmpq $0x0, %rax
je 0x59337
leaq 0x2006(%rip), %rax      # 0x5b334
movq %rax, -0xd0(%rbp)
jmp 0x59347
leaq 0x41b0(%rip), %rax      # 0x5d4ee
movq %rax, -0xd0(%rbp)
jmp 0x59347
movq -0xd0(%rbp), %rax
movq %rax, -0xd8(%rbp)
jmp 0x59367
leaq 0xf05e(%rip), %rax      # 0x683bc
movq %rax, -0xd8(%rbp)
jmp 0x59367
movq -0xc8(%rbp), %rdi
movq -0xd8(%rbp), %rsi
callq 0xd320
movq -0x8(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x70(%rbp), %rax
andq $0x1, %rax
cmpq $0x0, %rax
je 0x593a3
leaq 0x1f9a(%rip), %rax      # 0x5b334
movq %rax, -0xe8(%rbp)
jmp 0x593b3
leaq 0x4144(%rip), %rax      # 0x5d4ee
movq %rax, -0xe8(%rbp)
jmp 0x593b3
movq -0xe0(%rbp), %rdi
movq -0xe8(%rbp), %rsi
callq 0xd320
movl $0x40, %ecx
subq -0x58(%rbp), %rcx
addq -0x68(%rbp), %rcx
movq $-0x1, %rax
shrq %cl, %rax
andq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x68(%rbp), %rax
jbe 0x59618
movq -0x58(%rbp), %rax
subq -0x68(%rbp), %rax
andq $0x3, %rax
movq %rax, -0x78(%rbp)
movq -0x58(%rbp), %rax
subq -0x68(%rbp), %rax
cmpq -0x78(%rbp), %rax
jbe 0x594af
cmpq $0x0, -0x68(%rbp)
jbe 0x5942c
movq -0x8(%rbp), %rdi
leaq 0x8f9b(%rip), %rsi      # 0x623c2
callq 0xd320
movq -0x8(%rbp), %rdi
leaq 0xf1a0(%rip), %rsi      # 0x685d7
callq 0xd320
movq %rax, -0xf8(%rbp)
movl $0x30, %edi
callq 0x1ad60
movq -0xf8(%rbp), %rdi
movb %al, -0x79(%rbp)
movzbl -0x79(%rbp), %esi
callq 0xd4e0
movq %rax, -0xf0(%rbp)
movq -0x58(%rbp), %rax
subq -0x68(%rbp), %rax
shrq $0x2, %rax
movl %eax, %edi
callq 0x1ad80
movq -0xf0(%rbp), %rdi
movl %eax, -0x80(%rbp)
movl -0x80(%rbp), %esi
callq 0xd390
movq -0x8(%rbp), %rdi
leaq 0x5a9(%rip), %rsi       # 0x59a40
callq 0xd0f0
movq %rax, %rdi
movq -0x60(%rbp), %rsi
movq -0x78(%rbp), %rcx
shrq %cl, %rsi
callq 0xd0a0
cmpq $0x0, -0x78(%rbp)
jbe 0x59616
movq -0x58(%rbp), %rax
cmpq -0x78(%rbp), %rax
jbe 0x594d4
movq -0x8(%rbp), %rdi
leaq 0x8ef3(%rip), %rsi      # 0x623c2
callq 0xd320
movq -0x8(%rbp), %rdi
leaq 0xf0f5(%rip), %rsi      # 0x685d4
callq 0xd320
movq -0x8(%rbp), %rax
movq %rax, -0x100(%rbp)
cmpq $0x2, -0x78(%rbp)
jbe 0x59534
movq -0x60(%rbp), %rax
andq $0x4, %rax
cmpq $0x0, %rax
je 0x59514
leaq 0x1e29(%rip), %rax      # 0x5b334
movq %rax, -0x108(%rbp)
jmp 0x59524
leaq 0x3fd3(%rip), %rax      # 0x5d4ee
movq %rax, -0x108(%rbp)
jmp 0x59524
movq -0x108(%rbp), %rax
movq %rax, -0x110(%rbp)
jmp 0x59544
leaq 0xee81(%rip), %rax      # 0x683bc
movq %rax, -0x110(%rbp)
jmp 0x59544
movq -0x100(%rbp), %rdi
movq -0x110(%rbp), %rsi
callq 0xd320
movq -0x8(%rbp), %rax
movq %rax, -0x118(%rbp)
cmpq $0x1, -0x78(%rbp)
jbe 0x595a7
movq -0x60(%rbp), %rax
andq $0x2, %rax
cmpq $0x0, %rax
je 0x59587
leaq 0x1db6(%rip), %rax      # 0x5b334
movq %rax, -0x120(%rbp)
jmp 0x59597
leaq 0x3f60(%rip), %rax      # 0x5d4ee
movq %rax, -0x120(%rbp)
jmp 0x59597
movq -0x120(%rbp), %rax
movq %rax, -0x128(%rbp)
jmp 0x595b7
leaq 0xee0e(%rip), %rax      # 0x683bc
movq %rax, -0x128(%rbp)
jmp 0x595b7
movq -0x118(%rbp), %rdi
movq -0x128(%rbp), %rsi
callq 0xd320
movq -0x8(%rbp), %rax
movq %rax, -0x130(%rbp)
movq -0x60(%rbp), %rax
andq $0x1, %rax
cmpq $0x0, %rax
je 0x595f3
leaq 0x1d4a(%rip), %rax      # 0x5b334
movq %rax, -0x138(%rbp)
jmp 0x59603
leaq 0x3ef4(%rip), %rax      # 0x5d4ee
movq %rax, -0x138(%rbp)
jmp 0x59603
movq -0x130(%rbp), %rdi
movq -0x138(%rbp), %rsi
callq 0xd320
jmp 0x59618
movq -0x58(%rbp), %rax
shlq $0x2, %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x58(%rbp), %rax
addq -0x50(%rbp), %rax
movq %rax, -0x50(%rbp)
movl $0x0, -0x84(%rbp)
movq -0x28(%rbp), %rdi
movl -0x18(%rbp), %eax
movl %eax, %esi
subq -0x50(%rbp), %rsi
leaq -0x58(%rbp), %rdx
leaq -0x84(%rbp), %rcx
callq 0x59a70
cmpq $0x0, -0x38(%rbp)
jne 0x59691
cmpq $0x0, -0x50(%rbp)
jne 0x59691
testb $0x1, -0x29(%rbp)
jne 0x59691
cmpq $0x1, -0x40(%rbp)
jne 0x59691
cmpq $0x1, -0x58(%rbp)
jbe 0x59691
movq -0x8(%rbp), %rdi
leaq 0xae58(%rip), %rsi      # 0x644e0
callq 0xd320
movb $0x1, -0x29(%rbp)
cmpq $0x0, -0x58(%rbp)
jbe 0x5974a
testb $0x1, -0x45(%rbp)
jne 0x596d2
cmpq $0x0, -0x50(%rbp)
jne 0x596d2
movq -0x58(%rbp), %rax
movl -0x18(%rbp), %ecx
cmpq %rcx, %rax
jb 0x596bc
cmpq $0x1, -0x58(%rbp)
jbe 0x596d2
movq -0x8(%rbp), %rdi
leaq 0xae19(%rip), %rsi      # 0x644e0
callq 0xd320
movb $0x1, -0x45(%rbp)
jmp 0x596eb
cmpq $0x0, -0x50(%rbp)
jbe 0x596e9
movq -0x8(%rbp), %rdi
leaq 0x8cde(%rip), %rsi      # 0x623c2
callq 0xd320
jmp 0x596eb
movq -0x8(%rbp), %rax
movq %rax, -0x140(%rbp)
movq -0x28(%rbp), %rax
movl (%rax), %esi
leaq -0x88(%rbp), %rdi
callq 0x12e30
movq -0x140(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x12d50
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
movl -0x84(%rbp), %edx
callq 0x58f50
movq -0x58(%rbp), %rax
shlq $0x2, %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x58(%rbp), %rax
addq -0x50(%rbp), %rax
movq %rax, -0x50(%rbp)
jmp 0x590e8
testb $0x1, -0x45(%rbp)
je 0x59765
movq -0x8(%rbp), %rdi
leaq 0xad82(%rip), %rsi      # 0x644e2
callq 0xd320
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
movl -0x44(%rbp), %edx
callq 0x58f50
movq -0x40(%rbp), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x40(%rbp), %rax
subq $0x1, %rax
movl -0x18(%rbp), %ecx
imulq %rcx, %rax
shlq $0x2, %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0x5904c
testb $0x1, -0x29(%rbp)
je 0x597b7
movq -0x8(%rbp), %rdi
leaq 0xad30(%rip), %rsi      # 0x644e2
callq 0xd320
movq -0x8(%rbp), %rax
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
nopw %cs:(%rax,%rax)