// File: /workspace/github_c_makefile_star2_O3/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 0x712f(%rip), %r14      # 0xc5b8
movl 0x40(%r14), %edi
cmpl $0x3, %edi
jne 0x54a2
callq 0x3bd6
movq 0x711a(%rip), %r14      # 0xc5b8
movl 0x40(%r14), %edi
cmpl $0x7, %edi
jg 0x54c0
testl %edi, %edi
je 0x54b4
cmpl $0x7, %edi
jne 0x5540
callq 0x3b83
xorl %ebx, %ebx
jmp 0x5608
cmpl $0x8, %edi
je 0x5572
cmpl $0xc, %edi
jne 0x5540
movl $0x20, %edi
callq 0x30f0
testq %rax, %rax
je 0x5613
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)
movq $0x0, 0x18(%rbx)
movl $0xc, %edi
callq 0x3b21
movq 0x70a1(%rip), %rax      # 0xc5b8
movl 0x40(%rax), %edi
cmpl $0x2, %edi
je 0x550b
cmpl $0xa, %edi
ja 0x55d9
movl $0x418, %eax            # imm = 0x418
btl %edi, %eax
jae 0x55d9
callq 0x3f2e
jmp 0x55db
callq 0x6d36
movq 0x706c(%rip), %rcx      # 0xc5b8
movq 0x98(%rcx), %rdx
movq 0xa0(%rcx), %rcx
leaq 0x1e43(%rip), %rdi      # 0x73a4
xorl %ebx, %ebx
movq %rax, %rsi
xorl %eax, %eax
callq 0x365c
jmp 0x5608
movl $0x20, %edi
callq 0x30f0
testq %rax, %rax
je 0x5618
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)
movq $0x0, 0x18(%rbx)
movl $0x8, %edi
callq 0x3b21
movq 0x6ffd(%rip), %rax      # 0xc5b8
movl 0x40(%rax), %edi
cmpl $0x2, %edi
je 0x55af
cmpl $0x9, %edi
ja 0x55e9
movl $0x218, %eax            # imm = 0x218
btl %edi, %eax
jae 0x55e9
callq 0x3f2e
jmp 0x55eb
xorl %eax, %eax
movq %rax, 0x8(%rbx)
movq %rbx, %rdi
callq 0x509d
jmp 0x55f7
xorl %eax, %eax
movq %rax, 0x8(%rbx)
movq %rbx, %rdi
callq 0x500b
testl %eax, %eax
je 0x5603
movq %rbx, %rdi
callq 0x4187
callq 0x3b83
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
callq 0x3350
callq 0x333b