// File: /workspace/github_c_makefile_star2_O0/chgzm[P]minic/generator.c
// Function: process_global_declaration
static void process_global_declaration(const DeclarationNode* node) {
    // create type
    Type* type = NULL;
    for (int i = 0; i < node->decl_specifier_nodes->size; ++i) {
        const DeclSpecifierNode* decl_specifier_node = node->decl_specifier_nodes->elements[i];
        const TypeSpecifierNode* type_specifier_node = decl_specifier_node->type_specifier_node;
        if (type_specifier_node == NULL) {
            continue;
        }

        type = process_type_specifier_in_global(type_specifier_node);
        break;
    }

    for (int j = 0; j < node->init_declarator_nodes->size; ++j) {
        GlobalVar* gv       = malloc(sizeof(GlobalVar));
        gv->type            = type;
        gv->type->ptr_count = 0;

        const InitDeclaratorNode* init_declarator_node = node->init_declarator_nodes->elements[j];
        const DeclaratorNode* declarator_node  = init_declarator_node->declarator_node;

        const PointerNode* pointer_node = declarator_node->pointer_node;
        if (pointer_node != NULL) {
            gv->type->ptr_count = pointer_node->count;
            gv->type->size      = 8;
        } else {
            gv->type->size = gv->type->type_size;
        }

        const DirectDeclaratorNode* direct_declarator_node = declarator_node->direct_declarator_node;
        const ConditionalExprNode*  conditional_expr_node  = direct_declarator_node->conditional_expr_node;
        if (conditional_expr_node == NULL) {
            gv->type->array_size = 0;
        } else {
            gv->type->array_size = get_array_size_from_constant_expr(conditional_expr_node);
        }

        const DirectDeclaratorNode* ident_node = get_identifier_direct_declarator(direct_declarator_node);
        if (init_declarator_node->initializer_node != NULL) {
            printf(".global %s\n", ident_node->identifier);
        } else {
            printf(".comm %s,8,8\n", ident_node->identifier);
        }

        gv->name = strdup(ident_node->identifier);
        vector_push_back(globalvar_list, gv);

        if (init_declarator_node->initializer_node != NULL) {
            const InitializerNode* initializer_node = init_declarator_node->initializer_node;

            if (initializer_node->assign_expr_node != NULL) {
                if (is_int_constant(initializer_node->assign_expr_node)) {
                    const int int_constant1 = get_int_constant(initializer_node->assign_expr_node);
                    printf(".data\n");
                    printf("%s:\n", gv->name);
                    printf("  .quad %d\n", int_constant1); 
                    printf(".text\n");
                } 
                else {
                    const char* label1 = get_string_label();
                    printf(".data\n");
                    printf("%s:\n", label1);
                    printf("  .string \"%s\"\n", get_character_constant(initializer_node->assign_expr_node));
                    printf("%s:\n", gv->name);
                    printf("  .quad %s\n", label1); 
                    printf(".text\n");
                }
            } 
            else {
                InitializerListNode* initializer_list_node = initializer_node->initializer_list_node;
                const InitializerNode* first = initializer_list_node->initializer_nodes->elements[0];
                if (is_int_constant(first->assign_expr_node)) {
                    printf(".data\n");
                    printf("%s:\n", gv->name);

                    for (int k = 0; k < initializer_list_node->initializer_nodes->size; ++k) {
                        const InitializerNode* init1 = initializer_list_node->initializer_nodes->elements[k];
                        const int int_constant2 = get_int_constant(init1->assign_expr_node);
                        printf("  .quad %d\n", int_constant2); 
                    }
                    printf(".text\n");
                } else {
                    Vector* label_list = create_vector();
                    printf(".data\n");
                    for (int l = 0; l < initializer_list_node->initializer_nodes->size; ++l) {
                        const InitializerNode* init2 = initializer_list_node->initializer_nodes->elements[l];
                        char* label2 = get_string_label();
                        printf("%s:\n", label2);
                        printf("  .string \"%s\"\n", get_character_constant(init2->assign_expr_node));

                        vector_push_back(label_list, label2);
                   }

                   printf("%s:\n", gv->name);
                   for (int m = 0; m < label_list->size; ++m) {
                       char* label3 = label_list->elements[m];
                       printf("  .quad %s\n", label3);
                   }
                   printf(".text\n");
                }
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x8(%rbp)
movq $0x0, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movl -0x14(%rbp), %eax
movq -0x8(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x8(%rcx), %eax
jge 0x2c91
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movslq -0x14(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x2c77
jmp 0x2c86
movq -0x28(%rbp), %rdi
callq 0x32a0
movq %rax, -0x10(%rbp)
jmp 0x2c91
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x2c3e
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
cmpl 0x8(%rcx), %eax
jge 0x3143
movl $0x18, %edi
callq 0x10f0
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
movq (%rax), %rax
movl $0x0, 0x10(%rax)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0x2d27
movq -0x50(%rbp), %rax
movl (%rax), %ecx
movq -0x38(%rbp), %rax
movq (%rax), %rax
movl %ecx, 0x10(%rax)
movq -0x38(%rbp), %rax
movq (%rax), %rax
movl $0x8, 0x8(%rax)
jmp 0x2d3b
movq -0x38(%rbp), %rax
movq (%rax), %rax
movl 0x4(%rax), %ecx
movq -0x38(%rbp), %rax
movq (%rax), %rax
movl %ecx, 0x8(%rax)
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
jne 0x2d6a
movq -0x38(%rbp), %rax
movq (%rax), %rax
movl $0x0, 0xc(%rax)
jmp 0x2d7f
movq -0x60(%rbp), %rdi
callq 0x3660
movl %eax, %ecx
movq -0x38(%rbp), %rax
movq (%rax), %rax
movl %ecx, 0xc(%rax)
movq -0x58(%rbp), %rdi
callq 0x36b0
movq %rax, -0x68(%rbp)
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x2dae
movq -0x68(%rbp), %rax
movq (%rax), %rsi
leaq 0xc827(%rip), %rdi      # 0xf5cc
movb $0x0, %al
callq 0x1090
jmp 0x2dc3
movq -0x68(%rbp), %rax
movq (%rax), %rsi
leaq 0xc81c(%rip), %rdi      # 0xf5d8
movb $0x0, %al
callq 0x1090
movq -0x68(%rbp), %rax
movq (%rax), %rdi
callq 0x1170
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
movq 0x12367(%rip), %rdi     # 0x15148
movq -0x38(%rbp), %rsi
callq 0xe610
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x3133
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
cmpq $0x0, (%rax)
je 0x2efa
movq -0x70(%rbp), %rax
movq (%rax), %rdi
callq 0x36e0
testb $0x1, %al
jne 0x2e25
jmp 0x2e79
movq -0x70(%rbp), %rax
movq (%rax), %rdi
callq 0x3730
movl %eax, -0x74(%rbp)
leaq 0xc7ab(%rip), %rdi      # 0xf5e6
movb $0x0, %al
callq 0x1090
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0xc79c(%rip), %rdi      # 0xf5ed
movb $0x0, %al
callq 0x1090
movl -0x74(%rbp), %esi
leaq 0xc790(%rip), %rdi      # 0xf5f2
movb $0x0, %al
callq 0x1090
leaq 0xc78e(%rip), %rdi      # 0xf5fe
movb $0x0, %al
callq 0x1090
jmp 0x2ef5
callq 0x37d0
movq %rax, -0x80(%rbp)
leaq 0xc75d(%rip), %rdi      # 0xf5e6
movb $0x0, %al
callq 0x1090
movq -0x80(%rbp), %rsi
leaq 0xc752(%rip), %rdi      # 0xf5ed
movb $0x0, %al
callq 0x1090
movq -0x70(%rbp), %rax
movq (%rax), %rdi
callq 0x3780
movq %rax, %rsi
leaq 0xc74d(%rip), %rdi      # 0xf605
movb $0x0, %al
callq 0x1090
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0xc71f(%rip), %rdi      # 0xf5ed
movb $0x0, %al
callq 0x1090
movq -0x80(%rbp), %rsi
leaq 0xc735(%rip), %rdi      # 0xf615
movb $0x0, %al
callq 0x1090
leaq 0xc710(%rip), %rdi      # 0xf5fe
movb $0x0, %al
callq 0x1090
jmp 0x3131
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq (%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq (%rax), %rdi
callq 0x36e0
testb $0x1, %al
jne 0x2f38
jmp 0x2fe7
leaq 0xc6a7(%rip), %rdi      # 0xf5e6
movb $0x0, %al
callq 0x1090
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0xc698(%rip), %rdi      # 0xf5ed
movb $0x0, %al
callq 0x1090
movl $0x0, -0x94(%rbp)
movl -0x94(%rbp), %eax
movq -0x88(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x8(%rcx), %eax
jge 0x2fd4
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movslq -0x94(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
movq (%rax), %rdi
callq 0x3730
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %esi
leaq 0xc636(%rip), %rdi      # 0xf5f2
movb $0x0, %al
callq 0x1090
movl -0x94(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
jmp 0x2f66
leaq 0xc623(%rip), %rdi      # 0xf5fe
movb $0x0, %al
callq 0x1090
jmp 0x312f
movb $0x0, %al
callq 0xe5c0
movq %rax, -0xb0(%rbp)
leaq 0xc5ea(%rip), %rdi      # 0xf5e6
movb $0x0, %al
callq 0x1090
movl $0x0, -0xb4(%rbp)
movl -0xb4(%rbp), %eax
movq -0x88(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x8(%rcx), %eax
jge 0x30ad
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movslq -0xb4(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0xc0(%rbp)
callq 0x37d0
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rsi
leaq 0xc58e(%rip), %rdi      # 0xf5ed
movb $0x0, %al
callq 0x1090
movq -0xc0(%rbp), %rax
movq (%rax), %rdi
callq 0x3780
movq %rax, %rsi
leaq 0xc586(%rip), %rdi      # 0xf605
movb $0x0, %al
callq 0x1090
movq -0xb0(%rbp), %rdi
movq -0xc8(%rbp), %rsi
callq 0xe610
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x300d
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0xc531(%rip), %rdi      # 0xf5ed
movb $0x0, %al
callq 0x1090
movl $0x0, -0xcc(%rbp)
movl -0xcc(%rbp), %eax
movq -0xb0(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jge 0x3121
movq -0xb0(%rbp), %rax
movq (%rax), %rax
movslq -0xcc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rsi
leaq 0xc50c(%rip), %rdi      # 0xf615
movb $0x0, %al
callq 0x1090
movl -0xcc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xcc(%rbp)
jmp 0x30cd
leaq 0xc4d6(%rip), %rdi      # 0xf5fe
movb $0x0, %al
callq 0x1090
jmp 0x3131
jmp 0x3133
jmp 0x3135
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x2c98
addq $0xe0, %rsp
popq %rbp
retq
nopl (%rax)