// File: /workspace/github_c_makefile_star2_O2/tstword[P]MIPSAssemblerC/src/assembler.c
// Function: instruction_cfg
struct instruction_node *instruction_cfg() {
    struct instruction_node *node = NULL;

    if(cfg_assembler->lookahead == TOK_IDENTIFIER) label_cfg();

    switch(cfg_assembler->lookahead) {
        case TOK_DIRECTIVE: {
            node = (struct instruction_node *)malloc(sizeof(struct instruction_node));

            if(node == NULL) { 
                perror("CRITICAL ERROR: Failed to allocate memory for instruction node: ");
                exit(EXIT_FAILURE);
            }

            node->mnemonic = (struct reserved_entry *)cfg_assembler->tokenizer->attrptr;
            node->offset = cfg_assembler->segment_offset[cfg_assembler->segment];
            node->segment = cfg_assembler->segment;
            node->next = NULL;

            match_cfg(TOK_DIRECTIVE);

            /* Error recovery ignore commas */
            while(cfg_assembler->lookahead == TOK_COMMA) {
                match_cfg(TOK_COMMA);
            }

            switch(cfg_assembler->lookahead) {
                case TOK_IDENTIFIER:
                case TOK_INTEGER:
                case TOK_STRING:
                    node->operand_list = operand_list_cfg();
                    break;
                default:
                    node->operand_list = NULL;
            }

            if(check_directive(node))
                destroy_instruction(node);

            end_line_cfg();

            break;
        }
        case TOK_MNEMONIC:
            node = (struct instruction_node *)malloc(sizeof(struct instruction_node));

            if(node == NULL) { 
                perror("CRITICAL ERROR: Failed to allocate memory for instruction node: ");
                exit(EXIT_FAILURE);
            }

            node->mnemonic = (struct reserved_entry *)cfg_assembler->tokenizer->attrptr;
            node->offset = cfg_assembler->segment_offset[cfg_assembler->segment];
            node->segment = cfg_assembler->segment;
            node->next = NULL;
            
            match_cfg(TOK_MNEMONIC);

            /* Error recovery ignore commas */
            while(cfg_assembler->lookahead == TOK_COMMA) {
                match_cfg(TOK_COMMA);
            }

            switch(cfg_assembler->lookahead) {
                case TOK_IDENTIFIER:
                case TOK_INTEGER:
                case TOK_REGISTER:
                    node->operand_list = operand_list_cfg();
                    break;
                default:
                    node->operand_list = NULL;
            }

            if(assemble_instruction(node))
                destroy_instruction(node);

            end_line_cfg();

            break;
        case TOK_EOL:
        case TOK_NULL:
            end_line_cfg();
            break;
        default:
            report_cfg("Unexpected %s on line %ld, col %ld", get_token_str(cfg_assembler->lookahead), cfg_assembler->lineno, cfg_assembler->colno);
    }

    return node;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq 0x7610(%rip), %r14      # 0xc5b8
movl 0x40(%r14), %edi
cmpl $0x3, %edi
jne 0x4fc1
callq 0x37ce
movq 0x75fb(%rip), %r14      # 0xc5b8
movl 0x40(%r14), %edi
testl %edi, %edi
je 0x503d
cmpl $0x7, %edi
je 0x503d
cmpl $0x8, %edi
je 0x5049
cmpl $0xc, %edi
jne 0x50a7
pushq $0x20
popq %rdi
callq 0x30f0
testq %rax, %rax
je 0x5110
movq %rax, %rbx
movq (%r14), %rax
movq 0x20(%rax), %rax
movq %rax, (%rbx)
movzbl 0x45(%r14), %eax
movl 0x48(%r14,%rax,4), %ecx
movl %ecx, 0x10(%rbx)
movb %al, 0x14(%rbx)
andq $0x0, 0x18(%rbx)
pushq $0xc
popq %rdi
callq 0x371d
movq 0x759e(%rip), %rax      # 0xc5b8
movl 0x40(%rax), %edi
cmpl $0x2, %edi
je 0x500e
leal -0x3(%rdi), %eax
cmpl $0x2, %eax
jb 0x5033
cmpl $0xa, %edi
jne 0x50d6
callq 0x3ae6
jmp 0x50d8
callq 0x377d
xorl %ebx, %ebx
jmp 0x5105
pushq $0x20
popq %rdi
callq 0x30f0
testq %rax, %rax
je 0x5110
movq %rax, %rbx
movq (%r14), %rax
movq 0x20(%rax), %rax
movq %rax, (%rbx)
movzbl 0x45(%r14), %eax
movl 0x48(%r14,%rax,4), %ecx
movl %ecx, 0x10(%rbx)
movb %al, 0x14(%rbx)
andq $0x0, 0x18(%rbx)
pushq $0x8
popq %rdi
callq 0x371d
movq 0x752d(%rip), %rax      # 0xc5b8
movl 0x40(%rax), %edi
cmpl $0x2, %edi
je 0x507f
leal -0x3(%rdi), %eax
cmpl $0x2, %eax
jb 0x50a0
cmpl $0x9, %edi
jne 0x50e6
callq 0x3ae6
jmp 0x50e8
callq 0x6666
movq 0x7505(%rip), %rcx      # 0xc5b8
movq 0x98(%rcx), %rdx
movq 0xa0(%rcx), %rcx
leaq 0x22dc(%rip), %rdi      # 0x73a4
xorl %ebx, %ebx
movq %rax, %rsi
xorl %eax, %eax
callq 0x328c
jmp 0x5105
xorl %eax, %eax
movq %rax, 0x8(%rbx)
movq %rbx, %rdi
callq 0x4c83
jmp 0x50f4
xorl %eax, %eax
movq %rax, 0x8(%rbx)
movq %rbx, %rdi
callq 0x4bcd
testl %eax, %eax
je 0x5100
movq %rbx, %rdi
callq 0x3d45
callq 0x377d
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x2516(%rip), %rdi      # 0x762d
callq 0x3130
pushq $0x1
popq %rdi
callq 0x3150