// File: /workspace/github_cpp_makefile_star2_O2/fondoger[P]C0-Compiler/src/grammar.cpp
// Function: pCaseItem(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, DataType const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
static void pCaseItem(const std::string &switched_val, 
        const DataType &switched_dtype,
        const std::string &end_label)
{
    // TODO: default clause must be behind of case clause, 
    // which is prescribed by C0 grammar rules.
    // TODO: values in cases can't be equal
    // TODO: might sort case item's and apply binary search
    // to improve switch-case's performance.
    std::string cased_val;
    DataType cased_dtype;
    std::string case_label = genLabel();

    test3(Symset({CASESY, DEFAULTSY}));
    if (g_sym == CASESY) {
        readSymbol();
        // cased-value must be int or char literal, can't be 
        // const identifier
        test3(Symset({CHARVALUE, MINUS, PLUS, INTVALUE}));
        if (g_sym == CHARVALUE) {
            std::stringstream ss;
            ss << "\'" << g_char << "\'";
            cased_val = ss.str();
            cased_dtype = DT_CHAR;
            readSymbol();
        } else { // g_sym == INTVALUE
            pSignedInteger();
            cased_val = std::to_string(g_num);
            cased_dtype = DT_INT;
        }
        if (switched_dtype != cased_dtype) {
            error(ERR_SWITCH_TYPE_NOT_MATCH);
            std::stringstream ss;
            ss << "$witched=" << switched_val << "(" << dtype2str[switched_dtype]
               << ") $cased=" << cased_val << "(" << dtype2str[cased_dtype]
               << ")" << std::endl;
            error(ss.str());
            return;
        }
        test3(Symset({COLON}));
        readSymbol();
        case_label = genLabel();
        // generate if...goto... without cache
        // TODO: optimize switch, we don't have to load
        // switched_val every time when compare 
        genMidCode(COMPARE, switched_val, tokens[EQL], cased_val);
        genMidCode(BNZ, case_label, NONE, NONE);
        // generate labels and statements body in cache stack
        startCachingMidCode();
        genMidCode(LABEL, case_label, NONE, NONE); 
        pStatement();
        genMidCode(GOTO, end_label, NONE, NONE);
        // stop cache
        pauseCachingMidCode();

    } else {
        // default:
        readSymbol();
        test3(Symset({COLON}));
        readSymbol();
        // this label is not necessary, but it improves
        // readability of generated mid code and final 
        // mips code.
        case_label = genLabel();
        genMidCode(LABEL, case_label, NONE, NONE);
        // no cache for default clause
        pStatement();
        genMidCode(GOTO, end_label, NONE, NONE);
    }

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x278, %rsp            # imm = 0x278
movq %rdx, -0x30(%rbp)
movq %rsi, %r15
movq %rdi, %r14
leaq -0xc0(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq -0xb0(%rbp), %rdi
callq 0x106de
movabsq $0xb0000000a, %r12      # imm = 0xB0000000A
leaq -0x298(%rbp), %rsi
movq %r12, (%rsi)
leaq -0x90(%rbp), %rdi
pushq $0x2
popq %rdx
callq 0xef20
movabsq $0x2600000022, %rbx     # imm = 0x2600000022
leaq -0x50(%rbp), %rsi
movq %rbx, (%rsi)
leaq -0x88(%rbp), %rdi
pushq $0x2
popq %rdx
callq 0xef20
movq -0x90(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x9f5f
leaq -0x50(%rbp), %rsi
movq %r12, (%rsi)
leaq -0x298(%rbp), %rdi
pushq $0x2
popq %rdx
callq 0xef20
leaq 0x15c3d(%rip), %r13     # 0x24610
movl (%r13), %eax
movq -0x298(%rbp), %rcx
btq %rax, %rcx
jae 0xed4c
cmpl $0xa, %eax
jne 0xeaee
callq 0x13808
movaps 0x7983(%rip), %xmm0     # 0x16380
leaq -0x298(%rbp), %rsi
movups %xmm0, (%rsi)
leaq -0x80(%rbp), %rdi
pushq $0x4
popq %rdx
callq 0xef20
leaq -0x50(%rbp), %rsi
movq %rbx, (%rsi)
leaq -0x78(%rbp), %rdi
pushq $0x2
popq %rdx
callq 0xef20
movq -0x80(%rbp), %rdi
movq -0x78(%rbp), %rsi
callq 0x9f5f
leaq -0x298(%rbp), %rsi
movaps 0x793f(%rip), %xmm0     # 0x16380
movups %xmm0, (%rsi)
leaq -0x50(%rbp), %rdi
pushq $0x4
popq %rdx
callq 0xef20
movl (%r13), %eax
movq -0x50(%rbp), %rcx
btq %rax, %rcx
jae 0xed4c
cmpl $0x10, %eax
jne 0xebd6
leaq -0x298(%rbp), %rdi
callq 0x31f0
leaq -0x288(%rbp), %rdi
leaq 0x8189(%rip), %rsi      # 0x16c0e
callq 0x3280
leaq 0x15ba7(%rip), %rcx     # 0x24638
movsbl (%rcx), %esi
movq %rax, %rdi
callq 0x32f0
leaq 0x816b(%rip), %rsi      # 0x16c0e
movq %rax, %rdi
callq 0x3280
leaq -0x280(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x33d0
leaq -0xd0(%rbp), %rdi
leaq -0x50(%rbp), %r12
movq %r12, %rsi
callq 0x3310
movq %r12, %rdi
callq 0x3498
callq 0x13808
leaq -0x298(%rbp), %rdi
callq 0x34a0
pushq $0x2
jmp 0xec10
callq 0x13808
leaq -0x50(%rbp), %rsi
movl $0x25, (%rsi)
leaq -0x60(%rbp), %rdi
pushq $0x1
popq %rdx
callq 0xef20
leaq -0x298(%rbp), %rsi
movq %rbx, (%rsi)
leaq -0x58(%rbp), %rdi
pushq $0x2
popq %rdx
callq 0xef20
movq -0x60(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x9f5f
leaq -0x50(%rbp), %rsi
movl $0x25, (%rsi)
leaq -0x298(%rbp), %rdi
pushq $0x1
popq %rdx
callq 0xef20
movq -0x298(%rbp), %rax
movl (%r13), %ecx
btq %rcx, %rax
jae 0xed4c
callq 0x13808
leaq -0x298(%rbp), %rdi
callq 0x106de
leaq -0xb0(%rbp), %r14
leaq -0x298(%rbp), %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x3310
movq %r15, %rdi
callq 0x3498
movl $0x13, (%r15)
leaq 0x113c6(%rip), %rcx     # 0x1ff60
leaq -0x298(%rbp), %rdi
movq %r14, %rsi
movq %rcx, %rdx
callq 0x100d0
callq 0xbdb8
leaq -0x298(%rbp), %rdi
movl $0x14, (%rdi)
leaq 0x1139b(%rip), %rcx     # 0x1ff60
movq -0x30(%rbp), %rsi
movq %rcx, %rdx
callq 0x100d0
jmp 0xed51
callq 0xe508
leaq 0x15a5a(%rip), %rax     # 0x2463c
movl (%rax), %esi
leaq -0x298(%rbp), %rdi
callq 0xef70
leaq -0xd0(%rbp), %rdi
leaq -0x298(%rbp), %r12
movq %r12, %rsi
callq 0x3310
movq %r12, %rdi
callq 0x3498
pushq $0x1
popq %r12
cmpl %r12d, (%r15)
jne 0xed7b
leaq -0x50(%rbp), %rsi
movl $0x25, (%rsi)
leaq -0x70(%rbp), %rdi
pushq $0x1
popq %rdx
callq 0xef20
leaq -0x298(%rbp), %rsi
movq %rbx, (%rsi)
leaq -0x68(%rbp), %rdi
pushq $0x2
popq %rdx
callq 0xef20
movq -0x70(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x9f5f
leaq -0x50(%rbp), %rsi
movl $0x25, (%rsi)
leaq -0x298(%rbp), %rdi
pushq $0x1
popq %rdx
callq 0xef20
movq -0x298(%rbp), %rax
movl (%r13), %ecx
btq %rcx, %rax
jae 0xed4c
callq 0x13808
leaq -0x298(%rbp), %rdi
callq 0x106de
leaq -0xb0(%rbp), %rdi
leaq -0x298(%rbp), %r15
movq %r15, %rsi
callq 0x3310
movq %r15, %rdi
callq 0x3498
movl $0x11, (%r15)
leaq 0x10741(%rip), %rdx     # 0x1f400
leaq -0x298(%rbp), %rdi
leaq -0xd0(%rbp), %rcx
movq %r14, %rsi
callq 0x100d0
leaq -0x298(%rbp), %rdi
movl $0x16, (%rdi)
leaq 0x11277(%rip), %rcx     # 0x1ff60
leaq -0xb0(%rbp), %rsi
movq %rcx, %rdx
callq 0x100d0
callq 0x1059a
leaq -0x298(%rbp), %rdi
movl $0x13, (%rdi)
leaq 0x1124f(%rip), %rcx     # 0x1ff60
leaq -0xb0(%rbp), %rsi
movq %rcx, %rdx
callq 0x100d0
callq 0xbdb8
leaq -0x298(%rbp), %rdi
movl $0x14, (%rdi)
leaq 0x11227(%rip), %rcx     # 0x1ff60
movq -0x30(%rbp), %rsi
movq %rcx, %rdx
callq 0x100d0
callq 0x105a6
jmp 0xed51
callq 0x13808
leaq -0xb0(%rbp), %rdi
callq 0x3498
leaq -0xd0(%rbp), %rdi
callq 0x3498
addq $0x278, %rsp            # imm = 0x278
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x7941(%rip), %rsi      # 0x166c3
leaq -0x110(%rbp), %rdi
leaq -0x298(%rbp), %rdx
callq 0x30f0
leaq -0x110(%rbp), %rdi
callq 0xa247
leaq -0x110(%rbp), %rdi
callq 0x3498
leaq -0x298(%rbp), %rdi
callq 0x31f0
leaq -0x288(%rbp), %rdi
leaq 0x792c(%rip), %rsi      # 0x166f3
callq 0x3280
movq %rax, %rdi
movq %r14, %rsi
callq 0x3250
leaq 0x791f(%rip), %rsi      # 0x166fd
movq %rax, %rdi
callq 0x3280
movl (%r15), %esi
shlq $0x5, %rsi
leaq 0x10d4c(%rip), %rbx     # 0x1fb40
addq %rbx, %rsi
movq %rax, %rdi
callq 0x3250
leaq 0x78f9(%rip), %rsi      # 0x166ff
movq %rax, %rdi
callq 0x3280
leaq -0xd0(%rbp), %rsi
movq %rax, %rdi
callq 0x3250
leaq 0x78d9(%rip), %rsi      # 0x166fd
movq %rax, %rdi
callq 0x3280
shll $0x5, %r12d
addq %r12, %rbx
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3250
leaq 0x835b(%rip), %rsi      # 0x171a0
movq %rax, %rdi
callq 0x3280
movq %rax, %rdi
callq 0x3130
leaq -0x280(%rbp), %rsi
leaq -0xf0(%rbp), %rdi
callq 0x33d0
leaq -0xf0(%rbp), %rdi
callq 0xa247
leaq -0xf0(%rbp), %rdi
callq 0x3498
leaq -0x298(%rbp), %rdi
callq 0x34a0
jmp 0xed51
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
movq %rax, %rbx
leaq -0xf0(%rbp), %rdi
callq 0x3498
jmp 0xeeed
jmp 0xeefd
jmp 0xeefd
movq %rax, %rbx
leaq -0x110(%rbp), %rdi
callq 0x3498
jmp 0xef00
jmp 0xeefd
jmp 0xeefd
jmp 0xeeea
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeeea
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
jmp 0xeefd
movq %rax, %rbx
jmp 0xef0c
movq %rax, %rbx
leaq -0x298(%rbp), %rdi
callq 0x34a0
jmp 0xef00
jmp 0xeefd
movq %rax, %rbx
leaq -0xb0(%rbp), %rdi
callq 0x3498
leaq -0xd0(%rbp), %rdi
callq 0x3498
movq %rbx, %rdi
callq 0x3430