// File: /workspace/github_c_makefile_star2_O0/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 %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq $0x0, -0x8(%rbp)
movq 0x8ce1(%rip), %rax      # 0xf5a8
cmpl $0x3, 0x40(%rax)
jne 0x68d2
callq 0x3a50
movq 0x8ccf(%rip), %rax      # 0xf5a8
movl 0x40(%rax), %eax
movq %rax, -0x10(%rbp)
subq $0xc, %rax
ja 0x6afc
movq -0x10(%rbp), %rax
leaq 0x3b33(%rip), %rcx      # 0xa428
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x20, %edi
callq 0x30e0
movq %rax, -0x8(%rbp)
cmpq $0x0, -0x8(%rbp)
jne 0x6929
leaq 0x3ef3(%rip), %rdi      # 0xa80d
callq 0x3120
movl $0x1, %edi
callq 0x3140
movq 0x8c78(%rip), %rax      # 0xf5a8
movq (%rax), %rax
movq 0x20(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
movq 0x8c63(%rip), %rax      # 0xf5a8
movq 0x8c5c(%rip), %rcx      # 0xf5a8
movzbl 0x45(%rcx), %ecx
movl 0x48(%rax,%rcx,4), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x10(%rax)
movq 0x8c46(%rip), %rax      # 0xf5a8
movb 0x45(%rax), %cl
movq -0x8(%rbp), %rax
movb %cl, 0x14(%rax)
movq -0x8(%rbp), %rax
movq $0x0, 0x18(%rax)
movl $0xc, %edi
callq 0x3900
movq 0x8c1f(%rip), %rax      # 0xf5a8
cmpl $0x2, 0x40(%rax)
jne 0x699b
movl $0x2, %edi
callq 0x3900
jmp 0x6982
movq 0x8c06(%rip), %rax      # 0xf5a8
movl 0x40(%rax), %eax
movl %eax, -0x14(%rbp)
addl $-0x3, %eax
subl $0x2, %eax
jb 0x69bc
jmp 0x69b2
movl -0x14(%rbp), %eax
subl $0xa, %eax
jne 0x69ce
jmp 0x69bc
callq 0x3fb0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x69da
movq -0x8(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x8(%rbp), %rdi
callq 0x6450
cmpl $0x0, %eax
je 0x69f1
movq -0x8(%rbp), %rdi
callq 0x44d0
callq 0x39c0
jmp 0x6b38
movl $0x20, %edi
callq 0x30e0
movq %rax, -0x8(%rbp)
cmpq $0x0, -0x8(%rbp)
jne 0x6a26
leaq 0x3df6(%rip), %rdi      # 0xa80d
callq 0x3120
movl $0x1, %edi
callq 0x3140
movq 0x8b7b(%rip), %rax      # 0xf5a8
movq (%rax), %rax
movq 0x20(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
movq 0x8b66(%rip), %rax      # 0xf5a8
movq 0x8b5f(%rip), %rcx      # 0xf5a8
movzbl 0x45(%rcx), %ecx
movl 0x48(%rax,%rcx,4), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x10(%rax)
movq 0x8b49(%rip), %rax      # 0xf5a8
movb 0x45(%rax), %cl
movq -0x8(%rbp), %rax
movb %cl, 0x14(%rax)
movq -0x8(%rbp), %rax
movq $0x0, 0x18(%rax)
movl $0x8, %edi
callq 0x3900
movq 0x8b22(%rip), %rax      # 0xf5a8
cmpl $0x2, 0x40(%rax)
jne 0x6a98
movl $0x2, %edi
callq 0x3900
jmp 0x6a7f
movq 0x8b09(%rip), %rax      # 0xf5a8
movl 0x40(%rax), %eax
movl %eax, -0x18(%rbp)
addl $-0x3, %eax
subl $0x2, %eax
jb 0x6ab9
jmp 0x6aaf
movl -0x18(%rbp), %eax
subl $0x9, %eax
jne 0x6acb
jmp 0x6ab9
callq 0x3fb0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x6ad7
movq -0x8(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x8(%rbp), %rdi
callq 0x6330
cmpl $0x0, %eax
je 0x6aee
movq -0x8(%rbp), %rdi
callq 0x44d0
callq 0x39c0
jmp 0x6b38
callq 0x39c0
jmp 0x6b38
movq 0x8aa5(%rip), %rax      # 0xf5a8
movl 0x40(%rax), %edi
callq 0x9200
movq %rax, %rsi
movq 0x8a93(%rip), %rax      # 0xf5a8
movq 0x98(%rax), %rdx
movq 0x8a85(%rip), %rax      # 0xf5a8
movq 0xa0(%rax), %rcx
leaq 0x3a53(%rip), %rdi      # 0xa584
movb $0x0, %al
callq 0x3280
movq -0x8(%rbp), %rax
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)