// File: /workspace/github_cpp_makefile_star2_O3/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 $0x288, %rsp            # imm = 0x288
movq %rdx, %r13
movq %rsi, -0x58(%rbp)
movq %rdi, %r14
leaq -0x68(%rbp), %r12
movq %r12, -0x10(%r12)
movq $0x0, -0x8(%r12)
movb $0x0, (%r12)
leaq -0xe0(%rbp), %rdi
callq 0x15c85
movabsq $0xb0000000a, %rbx      # imm = 0xB0000000A
leaq -0x2a8(%rbp), %rsi
movq %rbx, (%rsi)
leaq -0xc0(%rbp), %rdi
movl $0x2, %edx
callq 0x13dee
movabsq $0x2600000022, %r15     # imm = 0x2600000022
leaq -0x48(%rbp), %rsi
movq %r15, (%rsi)
leaq -0xb8(%rbp), %rdi
movl $0x2, %edx
callq 0x13dee
movq -0xc0(%rbp), %rdi
movq -0xb8(%rbp), %rsi
callq 0xd8a2
leaq -0x48(%rbp), %rsi
movq %rbx, (%rsi)
leaq -0x2a8(%rbp), %rdi
movl $0x2, %edx
callq 0x13dee
leaq 0x15fbb(%rip), %rbx     # 0x29630
movl (%rbx), %eax
movq -0x2a8(%rbp), %rcx
btq %rax, %rcx
jae 0x13b0f
cmpl $0xa, %eax
jne 0x137d6
callq 0x19d18
movaps 0x8c83(%rip), %xmm0     # 0x1c320
leaq -0x2a8(%rbp), %rsi
movups %xmm0, (%rsi)
leaq -0xb0(%rbp), %rdi
movl $0x4, %edx
callq 0x13dee
leaq -0x48(%rbp), %rsi
movq %r15, (%rsi)
leaq -0xa8(%rbp), %rdi
movl $0x2, %edx
callq 0x13dee
movq -0xb0(%rbp), %rdi
movq -0xa8(%rbp), %rsi
callq 0xd8a2
leaq -0x2a8(%rbp), %rsi
movaps 0x8c2f(%rip), %xmm0     # 0x1c320
movups %xmm0, (%rsi)
leaq -0x48(%rbp), %rdi
movl $0x4, %edx
callq 0x13dee
movl (%rbx), %eax
movq -0x48(%rbp), %rcx
btq %rax, %rcx
jae 0x13b0f
cmpl $0x10, %eax
movq %r14, -0x50(%rbp)
jne 0x138d9
leaq -0x2a8(%rbp), %rdi
callq 0x31f0
leaq -0x298(%rbp), %rbx
leaq 0x9505(%rip), %rsi      # 0x1cc3e
movl $0x1, %edx
movq %rbx, %rdi
callq 0x3340
leaq 0x15f0b(%rip), %rax     # 0x29658
movb (%rax), %al
leaq -0x48(%rbp), %rsi
movb %al, (%rsi)
movl $0x1, %edx
movq %rbx, %rdi
callq 0x3340
leaq 0x94d5(%rip), %rsi      # 0x1cc3e
movl $0x1, %edx
movq %rax, %rdi
callq 0x3340
leaq -0x290(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x3420
leaq -0x78(%rbp), %rdi
leaq -0x48(%rbp), %rbx
movq %rbx, %rsi
callq 0x3370
movq (%rbx), %rdi
leaq -0x38(%rbp), %rax
cmpq %rax, %rdi
je 0x137a7
callq 0x32a0
callq 0x19d18
movq 0xf7ed(%rip), %rsi      # 0x22fa0
leaq -0x2a8(%rbp), %rdi
callq 0x3210
leaq -0x228(%rbp), %rdi
callq 0x30e0
movl $0x2, %r14d
jmp 0x139af
callq 0x19d18
leaq -0x48(%rbp), %rsi
movl $0x25, (%rsi)
leaq -0x90(%rbp), %rdi
movl $0x1, %edx
callq 0x13dee
leaq -0x2a8(%rbp), %rsi
movq %r15, (%rsi)
leaq -0x88(%rbp), %rdi
movl $0x2, %edx
callq 0x13dee
movq -0x90(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0xd8a2
leaq -0x48(%rbp), %rsi
movl $0x25, (%rsi)
leaq -0x2a8(%rbp), %rdi
movl $0x1, %edx
callq 0x13dee
movq -0x2a8(%rbp), %rax
movl (%rbx), %ecx
btq %rcx, %rax
jae 0x13b0f
callq 0x19d18
leaq -0x2a8(%rbp), %rdi
callq 0x15c85
leaq -0xe0(%rbp), %rdi
leaq -0x2a8(%rbp), %rbx
movq %rbx, %rsi
callq 0x3370
movq (%rbx), %rdi
leaq -0x298(%rbp), %rax
cmpq %rax, %rdi
je 0x1388d
callq 0x32a0
leaq -0x2a8(%rbp), %rdi
movl $0x13, (%rdi)
leaq 0x116df(%rip), %rcx     # 0x24f80
leaq -0xe0(%rbp), %rsi
movq %rcx, %rdx
callq 0x150ec
callq 0xfe0c
leaq -0x2a8(%rbp), %rdi
movl $0x14, (%rdi)
leaq 0x116b7(%rip), %rcx     # 0x24f80
movq %r13, %rsi
movq %rcx, %rdx
callq 0x150ec
jmp 0x13b14
callq 0x1300e
movq %r13, -0x80(%rbp)
leaq 0x15d73(%rip), %rax     # 0x2965c
movl (%rax), %r12d
movl %r12d, %r13d
negl %r13d
cmovsl %r12d, %r13d
movl $0x1, %ebx
cmpl $0xa, %r13d
jb 0x13946
movl $0x4, %ebx
movl $0xd1b71759, %eax       # imm = 0xD1B71759
movl %r13d, %ecx
cmpl $0x63, %ecx
jbe 0x1393f
cmpl $0x3e7, %ecx            # imm = 0x3E7
jbe 0x13944
cmpl $0x2710, %ecx           # imm = 0x2710
jb 0x13946
movl %ecx, %edx
imulq %rax, %rdx
shrq $0x2d, %rdx
addl $0x4, %ebx
cmpl $0x1869f, %ecx          # imm = 0x1869F
movl %edx, %ecx
ja 0x1390e
addl $-0x3, %ebx
jmp 0x13946
addl $-0x2, %ebx
jmp 0x13946
decl %ebx
shrl $0x1f, %r12d
leal (%rbx,%r12), %esi
leaq -0x298(%rbp), %rax
movq %rax, -0x10(%rax)
leaq -0x2a8(%rbp), %rdi
movl $0x2d, %edx
callq 0x3350
leaq -0x2a8(%rbp), %r14
addq (%r14), %r12
movq %r12, %rdi
movl %ebx, %esi
movl %r13d, %edx
callq 0x13e46
leaq -0x78(%rbp), %rdi
movq %r14, %rsi
callq 0x3370
movq (%r14), %rdi
leaq -0x298(%rbp), %rax
cmpq %rax, %rdi
je 0x139a1
callq 0x32a0
movl $0x1, %r14d
leaq -0x68(%rbp), %r12
movq -0x80(%rbp), %r13
leaq 0x15c7a(%rip), %rbx     # 0x29630
movq -0x58(%rbp), %rax
cmpl %r14d, (%rax)
jne 0x13b49
leaq -0x48(%rbp), %rsi
movl $0x25, (%rsi)
leaq -0xa0(%rbp), %rdi
movl $0x1, %edx
callq 0x13dee
leaq -0x2a8(%rbp), %rsi
movq %r15, (%rsi)
leaq -0x98(%rbp), %rdi
movl $0x2, %edx
callq 0x13dee
movq -0x50(%rbp), %r14
movq -0xa0(%rbp), %rdi
movq -0x98(%rbp), %rsi
callq 0xd8a2
leaq -0x48(%rbp), %rsi
movl $0x25, (%rsi)
leaq -0x2a8(%rbp), %rdi
movl $0x1, %edx
callq 0x13dee
movq -0x2a8(%rbp), %rax
movl (%rbx), %ecx
btq %rcx, %rax
jae 0x13b0f
callq 0x19d18
leaq -0x2a8(%rbp), %rdi
callq 0x15c85
leaq -0xe0(%rbp), %rdi
leaq -0x2a8(%rbp), %rbx
movq %rbx, %rsi
callq 0x3370
movq (%rbx), %rdi
leaq -0x298(%rbp), %rax
cmpq %rax, %rdi
je 0x13a79
callq 0x32a0
leaq -0x2a8(%rbp), %rdi
movl $0x11, (%rdi)
leaq 0x10993(%rip), %rdx     # 0x24420
leaq -0x78(%rbp), %rcx
movq %r14, %rsi
callq 0x150ec
leaq -0x2a8(%rbp), %rdi
movl $0x16, (%rdi)
leaq 0x114d3(%rip), %rcx     # 0x24f80
leaq -0xe0(%rbp), %rsi
movq %rcx, %rdx
callq 0x150ec
callq 0x15af0
leaq -0x2a8(%rbp), %rdi
movl $0x13, (%rdi)
leaq 0x114ab(%rip), %rcx     # 0x24f80
leaq -0xe0(%rbp), %rsi
movq %rcx, %rdx
callq 0x150ec
callq 0xfe0c
leaq -0x2a8(%rbp), %rdi
movl $0x14, (%rdi)
leaq 0x11483(%rip), %rcx     # 0x24f80
movq %r13, %rsi
movq %rcx, %rdx
callq 0x150ec
callq 0x15afc
jmp 0x13b14
callq 0x19d18
leaq -0xd0(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x13b29
callq 0x32a0
movq -0x78(%rbp), %rdi
cmpq %r12, %rdi
je 0x13b37
callq 0x32a0
addq $0x288, %rsp            # imm = 0x288
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq -0xf0(%rbp), %r15
movq %r15, -0x10(%r15)
leaq -0x2a8(%rbp), %rsi
movq $0x2f, (%rsi)
leaq -0x100(%rbp), %rdi
xorl %edx, %edx
callq 0x3490
leaq -0x100(%rbp), %rdi
movq %rax, (%rdi)
movq -0x2a8(%rbp), %rcx
movq %rcx, 0x10(%rdi)
movups 0x8afb(%rip), %xmm0     # 0x1c687
movups %xmm0, 0x1f(%rax)
movups 0x8ae1(%rip), %xmm0     # 0x1c678
movups %xmm0, 0x10(%rax)
movups 0x8ac6(%rip), %xmm0     # 0x1c668
movups %xmm0, (%rax)
movq %rcx, 0x8(%rdi)
movb $0x0, (%rax,%rcx)
callq 0xdccb
movq -0x100(%rbp), %rdi
cmpq %r15, %rdi
je 0x13bc3
callq 0x32a0
leaq -0x2a8(%rbp), %rdi
callq 0x31f0
leaq -0x298(%rbp), %rbx
leaq 0x8abb(%rip), %rsi      # 0x1c698
movl $0x9, %edx
movq %rbx, %rdi
callq 0x3340
movq -0x50(%rbp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %rbx, %rdi
callq 0x3340
movq %rax, %rbx
leaq 0x8a9b(%rip), %rsi      # 0x1c6a2
movl $0x1, %edx
movq %rax, %rdi
callq 0x3340
movq -0x58(%rbp), %rax
movl (%rax), %eax
shlq $0x5, %rax
leaq 0x10f3b(%rip), %r15     # 0x24b60
movq (%rax,%r15), %rsi
movq 0x8(%rax,%r15), %rdx
movq %rbx, %rdi
callq 0x3340
movq %rax, %rbx
leaq 0x8a64(%rip), %rsi      # 0x1c6a4
movl $0x9, %edx
movq %rax, %rdi
callq 0x3340
movq -0x78(%rbp), %rsi
movq -0x70(%rbp), %rdx
movq %rbx, %rdi
callq 0x3340
movq %rax, %rbx
leaq 0x8a3b(%rip), %rsi      # 0x1c6a2
movl $0x1, %edx
movq %rax, %rdi
callq 0x3340
shll $0x5, %r14d
movq (%r14,%r15), %rsi
movq 0x8(%r14,%r15), %rdx
movq %rbx, %rdi
callq 0x3340
movq %rax, %rbx
leaq 0x9542(%rip), %rsi      # 0x1d1d5
movl $0x1, %edx
movq %rax, %rdi
callq 0x3340
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x32b0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x31d0
leaq -0x290(%rbp), %rsi
leaq -0x120(%rbp), %rdi
callq 0x3420
leaq -0x120(%rbp), %rdi
callq 0xdccb
leaq -0x110(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x13cfb
callq 0x32a0
movq 0xf29e(%rip), %rsi      # 0x22fa0
leaq -0x2a8(%rbp), %rdi
callq 0x3210
leaq -0x228(%rbp), %rdi
callq 0x30e0
jmp 0x13b14
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
movq %rax, %rbx
leaq -0x110(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x13d98
callq 0x32a0
jmp 0x13d98
jmp 0x13dbb
jmp 0x13dbb
movq %rax, %rbx
movq -0x100(%rbp), %rdi
cmpq %r15, %rdi
je 0x13dbe
callq 0x32a0
jmp 0x13dbe
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13d95
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13d95
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
jmp 0x13dbb
movq %rax, %rbx
jmp 0x13dd3
movq %rax, %rbx
movq 0xf201(%rip), %rsi      # 0x22fa0
leaq -0x2a8(%rbp), %rdi
callq 0x3210
leaq -0x228(%rbp), %rdi
callq 0x30e0
jmp 0x13dbe
jmp 0x13dbb
movq %rax, %rbx
leaq -0xd0(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x13dd3
callq 0x32a0
movq -0x78(%rbp), %rdi
leaq -0x68(%rbp), %rax
cmpq %rax, %rdi
je 0x13de5
callq 0x32a0
movq %rbx, %rdi
callq 0x3480
nop