// File: /workspace/github_cpp_makefile_star2_O3/saumya-prakash[P]AssemblerEmulator/Assembler.cpp
// Function: Assembler::encode_first(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned int const&, unsigned int const&, unsigned int const&)
unsigned Assembler::encode_first(const string& s, const unsigned& opcode, const unsigned& line_no, const unsigned& pc)
{
    istringstream iss(s);

    string t;
    iss>>t;     // 'dump' mnemonic

    string less, more;

    iss>>less;
    if(less.empty())    // no operand - generate too few operands error
    {
        errors.insert({line_no, Error(9)});
        return 0xffffffff;
    }

    t = less;

    iss>>more;
    if(!more.empty())   // more than 1 operand - generate too many operands error
    {
        errors.insert({line_no, Error(6)});
        return 0xffffffff;
    }

    if(valid_number(t)==true)   // a numeric operand - applicable to all mnemonics of one-operand type
    {
        int a = str_to_int(t);

        a = a<<8;
        a = a + opcode;
                                // HOPE CONVERSION DOESN'T POSE ANY PROBLEMS
        unsigned tmp = a;

        return tmp;
    }

    else        // either a label or an invalid operand
    {
        struct label tmp(t, 0);
        if(tmp.name.empty())    // not a label -> so, an invalid operand
        {
            errors.insert({line_no, Error(4)});
            return 0xffffffff;
        }

                        // a label name is there
                        // first check if it is in the symbol table
        map<string, struct label>::iterator st = symtab.find(t);

        if(st==symtab.end())    // label not in symbol table - generate unknown label name error
        {
            errors.insert({line_no, Error(2)});
            return 0xffffffff;
        }

        ++(st->second.use_cnt);

        int offset;     // all one-operand mnemonics can have label as operand as well
        unsigned b;

        switch(opcode)
        {
            case 13:    // call
            case 15:    // brz
            case 16:    // brlz
            case 17:    // br
                    offset = calculate_offset(pc, st->second.addr);

                    b = offset;
                    b = b<<8;
                    b = b + opcode;

                    return b;
                    break;

            default:        // others directly take the address as operand
                        b = st->second.addr;
                        b = b<<8;
                        b = b + opcode;
                        return b;
                        break;
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x288, %rsp            # imm = 0x288
movq %r8, %r12
movq %rcx, %r14
movq %rdx, %r15
movq %rdi, %rbx
leaq 0x108(%rsp), %r13
movq %r13, %rdi
movl $0x8, %edx
callq 0x22d0
leaq 0x60(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x50(%rsp), %rsi
movq %r13, %rdi
callq 0x2230
leaq 0xd8(%rsp), %r13
movq %r13, -0x10(%r13)
xorl %eax, %eax
movq %rax, -0x8(%r13)
movb %al, (%r13)
leaq 0xf8(%rsp), %rbp
movq %rbp, -0x10(%rbp)
movq %rax, -0x8(%rbp)
movb %al, (%rbp)
leaq 0x108(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x2230
cmpq $0x0, 0xd0(%rsp)
je 0x67fb
leaq 0x50(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x20f0
leaq 0x108(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x2230
cmpq $0x0, 0xf0(%rsp)
je 0x6867
leaq 0x30(%rsp), %rsi
movl $0x6, (%rsi)
leaq 0x7a56(%rip), %rdi      # 0xe1f0
callq 0x82f6
leaq 0x18(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0x8(%rsp), %rdi
callq 0x3298
addq $0xc8, %rbx
movl (%r14), %eax
leaq 0x88(%rsp), %r14
movl %eax, -0x18(%r14)
movq %r14, -0x10(%r14)
movq 0x8(%rsp), %rax
cmpq %r15, %rax
je 0x6895
movq %rax, 0x78(%rsp)
movq 0x18(%rsp), %rax
movq %rax, 0x88(%rsp)
jmp 0x689d
leaq 0x30(%rsp), %rsi
movl $0x9, (%rsi)
leaq 0x79e3(%rip), %rdi      # 0xe1f0
callq 0x82f6
leaq 0x18(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0x8(%rsp), %rdi
callq 0x3298
addq $0xc8, %rbx
movl (%r14), %eax
leaq 0x88(%rsp), %r14
movl %eax, -0x18(%r14)
movq %r14, -0x10(%r14)
movq 0x8(%rsp), %rax
cmpq %r15, %rax
je 0x68c8
movq %rax, 0x78(%rsp)
movq 0x18(%rsp), %rax
movq %rax, 0x88(%rsp)
jmp 0x68d0
leaq 0x50(%rsp), %rsi
callq 0x35e0
testb %al, %al
je 0x69ba
leaq 0x50(%rsp), %rsi
callq 0x368e
movl %eax, %ebx
shll $0x8, %ebx
addl (%r15), %ebx
leaq 0x60(%rsp), %r14
jmp 0x6934
movups (%r15), %xmm0
movups %xmm0, (%r14)
movq 0x10(%rsp), %rax
leaq 0x70(%rsp), %rsi
movq %rax, 0x10(%rsi)
movq %r15, 0x8(%rsp)
movq $0x0, 0x10(%rsp)
movb $0x0, 0x18(%rsp)
movq %rbx, %rdi
callq 0x8a12
jmp 0x68f9
movups (%r15), %xmm0
movups %xmm0, (%r14)
movq 0x10(%rsp), %rax
leaq 0x70(%rsp), %rsi
movq %rax, 0x10(%rsi)
movq %r15, 0x8(%rsp)
movq $0x0, 0x10(%rsp)
movb $0x0, 0x18(%rsp)
movq %rbx, %rdi
callq 0x8a12
movq 0x78(%rsp), %rdi
cmpq %r14, %rdi
je 0x6913
movq 0x88(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x8(%rsp), %rdi
cmpq %r15, %rdi
leaq 0x60(%rsp), %r14
je 0x692f
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21c0
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq 0xe8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x6951
movq 0xf8(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0xc8(%rsp), %rdi
cmpq %r13, %rdi
je 0x696e
movq 0xd8(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x50(%rsp), %rdi
cmpq %r14, %rdi
je 0x6985
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x7644(%rip), %rsi      # 0xdfd0
leaq 0x108(%rsp), %rdi
callq 0x2270
leaq 0x180(%rsp), %rdi
callq 0x20b0
movl %ebx, %eax
addq $0x288, %rsp            # imm = 0x288
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xb8(%rsp), %rax
movq %rax, -0x10(%rax)
movq 0x50(%rsp), %rsi
movq 0x58(%rsp), %rdx
addq %rsi, %rdx
leaq 0xa8(%rsp), %rdi
callq 0x3298
leaq 0x70(%rsp), %rdi
leaq 0xa8(%rsp), %rdx
movq %rdi, %rsi
callq 0x8274
movq $0x0, 0x90(%rsp)
movl $0x0, 0x98(%rsp)
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x6a31
movq 0xb8(%rsp), %rsi
incq %rsi
callq 0x21c0
cmpq $0x0, 0x78(%rsp)
je 0x6a88
leaq 0x50(%rsp), %rsi
movq %rbx, %rdi
callq 0x8ee2
leaq 0x8(%rbx), %rcx
cmpq %rcx, %rax
je 0x6af1
incl 0x64(%rax)
movl (%r15), %ecx
cmpl $0x11, %ecx
ja 0x6c20
movl $0x3a000, %edx          # imm = 0x3A000
btl %ecx, %edx
jae 0x6c20
movl (%r12), %ebx
notl %ebx
addl 0x60(%rax), %ebx
shll $0x8, %ebx
addl %ecx, %ebx
leaq 0x60(%rsp), %r14
jmp 0x6bf6
leaq 0xa4(%rsp), %rsi
movl $0x4, (%rsi)
leaq 0x7753(%rip), %rdi      # 0xe1f0
callq 0x82f6
leaq 0x40(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0x30(%rsp), %rdi
callq 0x3298
addq $0xc8, %rbx
movl (%r14), %eax
leaq 0x20(%rsp), %r14
movl %eax, -0x18(%r14)
movq %r14, -0x10(%r14)
movq 0x30(%rsp), %rax
cmpq %r15, %rax
je 0x6b5a
movq %rax, 0x10(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x20(%rsp)
jmp 0x6b62
leaq 0xa4(%rsp), %rsi
movl $0x2, (%rsi)
leaq 0x76ea(%rip), %rdi      # 0xe1f0
callq 0x82f6
leaq 0x40(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0x30(%rsp), %rdi
callq 0x3298
addq $0xc8, %rbx
movl (%r14), %eax
leaq 0x20(%rsp), %r14
movl %eax, -0x18(%r14)
movq %r14, -0x10(%r14)
movq 0x30(%rsp), %rax
cmpq %r15, %rax
je 0x6b8d
movq %rax, 0x10(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x20(%rsp)
jmp 0x6b95
movups (%r15), %xmm0
movups %xmm0, (%r14)
movq 0x38(%rsp), %rax
leaq 0x8(%rsp), %rsi
movq %rax, 0x10(%rsi)
movq %r15, 0x30(%rsp)
movq $0x0, 0x38(%rsp)
movb $0x0, 0x40(%rsp)
movq %rbx, %rdi
callq 0x8a12
jmp 0x6bbe
movups (%r15), %xmm0
movups %xmm0, (%r14)
movq 0x38(%rsp), %rax
leaq 0x8(%rsp), %rsi
movq %rax, 0x10(%rsi)
movq %r15, 0x30(%rsp)
movq $0x0, 0x38(%rsp)
movb $0x0, 0x40(%rsp)
movq %rbx, %rdi
callq 0x8a12
movq 0x10(%rsp), %rdi
cmpq %r14, %rdi
je 0x6bd5
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x30(%rsp), %rdi
cmpq %r15, %rdi
leaq 0x60(%rsp), %r14
je 0x6bf1
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x21c0
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
leaq 0x80(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x6934
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x21c0
jmp 0x6934
movl 0x60(%rax), %ebx
jmp 0x6a79
jmp 0x6c2a
movq %rax, %rbx
movq 0x10(%rsp), %rdi
cmpq %r14, %rdi
je 0x6c44
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x30(%rsp), %rdi
cmpq %r15, %rdi
je 0x6c64
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x21c0
jmp 0x6c64
jmp 0x6c61
jmp 0x6c61
movq %rax, %rbx
leaq 0x80(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x6ce9
movq 0x80(%rsp), %rsi
jmp 0x6cd3
movq %rax, %rbx
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x6ce9
movq 0xb8(%rsp), %rsi
jmp 0x6cd3
jmp 0x6ce6
jmp 0x6ce6
jmp 0x6ca7
movq %rax, %rbx
movq 0x78(%rsp), %rdi
cmpq %r14, %rdi
je 0x6cc4
movq 0x88(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x8(%rsp), %rdi
cmpq %r15, %rdi
je 0x6ce9
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21c0
jmp 0x6ce9
jmp 0x6ce6
jmp 0x6ce6
movq %rax, %rbx
jmp 0x6d23
movq %rax, %rbx
movq 0xe8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x6d06
movq 0xf8(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0xc8(%rsp), %rdi
cmpq %r13, %rdi
je 0x6d23
movq 0xd8(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x50(%rsp), %rdi
leaq 0x60(%rsp), %rax
cmpq %rax, %rdi
je 0x6d3f
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x21c0
movq 0x728a(%rip), %rsi      # 0xdfd0
leaq 0x108(%rsp), %rdi
callq 0x2270
leaq 0x180(%rsp), %rdi
callq 0x20b0
movq %rbx, %rdi
callq 0x22e0