// File: /workspace/github_cpp_makefile_star2_O3/besm6[P]pascal-re/pascompl.cc
// Function: caseStatement()
void caseStatement()
{
    typedef struct CaseClause : public BESM6Obj {
        CaseClause * next;
        Word value;
        int64_t offset;
    } * CaseClausePtr;

    CaseClausePtr allClauses, curClause, clause, old = NULL;
    bool isIntCase;
    bool otherSeen;
    int64_t otherOffset = -1;
    bool itemsEnded, goodMode;
    TypesPtr firstType, itemtype, exprtype;
    Word itemvalue;
    int64_t itemSpan;
    Word expected;
    int64_t startLine, l4var17z, endOfStmt;
    Word minValue, maxValue;

    startLine = lineCnt;
    expression();
    exprtype = curExpr->typ;
    otherSeen = false;
    if (exprtype == AlfaType or
        (exprtype->k == kindScalar || exprtype->k == kindRange))
        (void) formOperator(LOAD);
    else
        error(25); /* errExprNotOfADiscreteType */
    disableNorm();
    l4var17z = 0;
    endOfStmt = 0;
    allClauses = NULL;
    formJump(l4var17z);
    checkSymAndRead(OFSY);
    firstType = NULL;
    goodMode = true;
    do {
        if (not (SY == SEMICOLON || SY == ENDSY)) {
            padToLeft();
            arithMode = 1;
            if (SY == OTHERSY) {
                if (otherSeen)
                    error(73); /* errCaseLabelsIdentical */
                inSymbol();
                otherSeen = true;
                otherOffset = moduleOffset;
            } else do {
                    parseLiteral(itemtype, itemvalue, true);
                    if (itemtype != NULL) {
                        if (firstType == NULL) {
                            firstType = itemtype;
                        } else {
                            if (not typeCheck(itemtype, firstType))
                                error(errConstOfOtherTypeNeeded);
                        } /* 15700 */
                        clause = new CaseClause;
                        clause->value = itemvalue;
                        clause->offset = moduleOffset;
                        curClause = allClauses;
                        while (curClause != NULL) {
                            if (itemvalue == curClause->value) {
                                error(73); /* errCaseLabelsIdentical */
                                break;
                            } else if (itemvalue.i < curClause->value.i) {
                                break;
                            } else {
                                old = curClause;
                                curClause = curClause->next;
                            }
                        } /* 15723 */
                        if (curClause == allClauses) {
                            clause->next = allClauses;
                            allClauses = clause;
                        } else {
                            clause->next = curClause;
                            old->next = clause;
                        }
                        inSymbol();
                    } /* 15735 */
                  itemsEnded = (SY != COMMA);
                  if (not itemsEnded)
                      inSymbol();
                } while (!itemsEnded);
            checkSymAndRead(COLON);
            Statement();
            goodMode = goodMode and (arithMode == 1);
            formJump(endOfStmt);
        } /* 15762 */
        itemsEnded = (SY == ENDSY);
        if (not itemsEnded)
            inSymbol();
    } while (!itemsEnded);
    if (SY != ENDSY) {
        requiredSymErr(ENDSY);
        stmtName = "CASE  ";
        reportStmtType(startLine);
    } else
        inSymbol();
    if (not typeCheck(firstType, exprtype)) {
        error(88); /* errDifferentTypesOfLabelsAndExpr */;
        return;
    }
    padToLeft();
    isIntCase = typeCheck(exprtype, IntegerType);
    if (allClauses != NULL) {
        expected = allClauses->value;
        minValue = expected;
        curClause = allClauses;
        while (curClause != NULL) {
            if (expected == curClause->value and
                exprtype->k == kindScalar) {
                maxValue = expected;
                if (isIntCase) {
                    expected.i = expected.i + 1; // Integers with exponent
                } else {
                    curVal = expected;
                    curVal.ii = curVal.ii + 1; // Integers without exponent
                    expected = curVal;
                }
                curClause = curClause->next;
            } else {
                itemSpan = 34000;
                P0715(0, l4var17z);
                if (firstType->k == kindRange) {
                    itemSpan = std::max(std::abs(firstType->cast<RangeT>().left),
                                        std::abs(firstType->cast<RangeT>().right));
                } else {
                    if (firstType->k == kindScalar)
                        itemSpan = firstType->cast<ScalarT>().numen;
                }
                itemsEnded = (itemSpan < 32000);
                if (itemsEnded) {
                    form1Insn(KATI+14);
                } else {
                    form1Insn(KATX+SP+1);
                }
                minValue.i = (minValue.i - minValue.i); /* WTF? */
                while (allClauses != NULL) {
                    if (itemsEnded) {
                        curVal.i = (minValue.i - allClauses->value.i);
                        curVal.i = curVal.ii;
                        form1Insn(getValueOrAllocSymtab(curVal.i) +
                                  (KUTM+I14));
                        form1Insn(KVZM+I14 + allClauses->offset);
                        minValue = allClauses->value;
                    } else {
                        form1Insn(KXTA+SP+1);
                        curVal = allClauses->value;
                        form2Insn(KAEX + I8 + getFCSToffset(),
                                  InsnTemp[UZA] + allClauses->offset);
                    }
                    allClauses = allClauses->next;
                }
                if (otherSeen)
                    form1Insn(InsnTemp[UJ] + otherOffset);
                goto L16211;
            } /* if 16141 */
        } /* while 16142 */
        if (not otherSeen) {
            otherOffset = moduleOffset;
            formJump(endOfStmt);
        }
        P0715(0, l4var17z);
        curVal = minValue;
        P0715(-(InsnTemp[U1A]+otherOffset), maxValue.i);
        curVal = minValue;
        curVal.i = curVal.ii;
        form1Insn(KATI+14);
        curVal.i = ((moduleOffset + (1)) - curVal.i);
        if (curVal.i < 040000) {
            curVal.i = (curVal.i - 040000);
            curVal.i = allocSymtab(041000000 | (curVal.ii & 077777));
        }
        form1Insn(KUJ+I14 + curVal.i);
        while (allClauses != NULL) {
            padToLeft();
            form1Insn(InsnTemp[UJ] + allClauses->offset);
            allClauses = allClauses->next;
        }
L16211:
        P0715(0, endOfStmt);
        if (not goodMode)
            disableNorm();
        /* 16217 */
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x888, %rsp            # imm = 0x888
callq 0xee5e
movq 0x54bcc(%rip), %rax     # 0x64aa0
movq (%rax), %rax
cmpq 0x54b22(%rip), %rax     # 0x64a00
movq %rax, 0x8(%rsp)
je 0xfeef
movl 0x10(%rax), %eax
decl %eax
cmpl $0x1, %eax
ja 0xff0b
leaq 0xf0(%rsp), %rdi
movl $0x2, %esi
callq 0xc308
addq $-0x8, 0xad4b7(%rip)    # 0xbd3c0
jmp 0xff15
movl $0x19, %edi
callq 0x58ff
cmpq $0x1, 0x549bb(%rip)     # 0x648d8
je 0xff36
movq 0x14362(%rip), %rdi     # 0x24288
callq 0x59a2
movq $0x1, 0x549a2(%rip) # 0x648d8
movabsq $0x1ffffffffff, %rbp    # imm = 0x1FFFFFFFFFF
xorl %r14d, %r14d
leaq 0x30(%rsp), %rdi
movq %r14, (%rdi)
leaq 0x20(%rsp), %rax
movq %r14, (%rax)
callq 0x5b33
movl $0x2a, %edi
callq 0x83e7
movb $0x1, 0x7(%rsp)
movq $-0x1, 0x18(%rsp)
movq $0x0, 0x10(%rsp)
xorl %r15d, %r15d
xorl %r12d, %r12d
movl 0x54897(%rip), %eax     # 0x6481c
cmpl $0xf, %eax
je 0x10040
cmpl $0x27, %eax
je 0x10040
cmpb $0x0, 0x549d6(%rip)     # 0x64974
jne 0xffb2
movq 0x59501(%rip), %rdi     # 0x694a8
callq 0x59a2
movl 0x5486a(%rip), %eax     # 0x6481c
movq $0x0, 0x5499b(%rip) # 0x64958
movq $0x1, 0x54910(%rip) # 0x648d8
cmpl $0x31, %eax
jne 0x1005b
testb $0x1, 0x10(%rsp)
je 0xffe2
movl $0x49, %edi
callq 0x58ff
leaq 0x718(%rsp), %rdi
callq 0x6f40
movb $0x1, %al
movq %rax, 0x10(%rsp)
movq 0x5488b(%rip), %rax     # 0x64888
movq %rax, 0x18(%rsp)
movl $0x12, %edi
callq 0x83e7
leaq 0x98(%rsp), %rdi
callq 0x108ce
addq $-0x8, 0xad407(%rip)    # 0xbd428
cmpq $0x1, 0x548af(%rip)     # 0x648d8
sete %al
andb %al, 0x7(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x5b33
movl 0x547dc(%rip), %eax     # 0x6481c
cmpl $0x27, %eax
je 0x10155
leaq 0x2c8(%rsp), %rdi
callq 0x6f40
jmp 0xff7f
leaq 0x48(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movl $0x1, %edx
callq 0x8157
movq 0x48(%rsp), %rsi
testq %rsi, %rsi
je 0x10136
testq %r15, %r15
je 0x100aa
leaq 0x50(%rsp), %rdi
movq %r15, %rdx
callq 0x84c6
addq $-0x8, 0xad311(%rip)    # 0xbd3a8
cmpb $0x0, 0x50(%rsp)
jne 0x100ad
movl $0x7, %edi
callq 0x58ff
jmp 0x100ad
movq %rsi, %r15
movl $0x18, %edi
callq 0x3d77
movq %rax, %r13
movq 0x40(%rsp), %rax
movq %rax, 0x8(%r13)
movq 0x547be(%rip), %rcx     # 0x64888
movq %rcx, 0x10(%r13)
testq %r12, %r12
je 0x10106
movq %rax, %rcx
shlq $0x17, %rcx
movq %r12, %rdx
movq %rdx, %rbx
movq 0x8(%rdx), %rdx
movq %rdx, %rsi
xorq %rax, %rsi
testq %rbp, %rsi
je 0x1010a
shlq $0x17, %rdx
cmpq %rdx, %rcx
jl 0x10114
movq (%rbx), %rdx
movq %rbx, %r14
testq %rdx, %rdx
jne 0x100dd
movq %rbx, %r14
xorl %ebx, %ebx
jmp 0x10114
movl $0x49, %edi
callq 0x58ff
cmpq %r12, %rbx
je 0x10122
movq %rbx, (%r13)
movq %r13, (%r14)
jmp 0x10129
movq %r12, (%r13)
movq %r13, %r12
leaq 0x5a8(%rsp), %rdi
callq 0x6f40
cmpl $0xe, 0x546df(%rip)     # 0x6481c
jne 0x10002
leaq 0x438(%rsp), %rdi
callq 0x6f40
jmp 0x1005b
leaq 0x158(%rsp), %rdi
callq 0x6f40
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
movq 0x8(%rsp), %rdx
callq 0x84c6
addq $-0x8, 0xad229(%rip)    # 0xbd3a8
cmpb $0x0, (%rbx)
je 0x1039a
cmpb $0x0, 0x547e5(%rip)     # 0x64974
jne 0x1019d
movq 0x59310(%rip), %rdi     # 0x694a8
callq 0x59a2
movq $0x0, 0x547b0(%rip) # 0x64958
movq 0x54839(%rip), %rdx     # 0x649e8
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
callq 0x84c6
movb (%rbx), %bl
addq $-0x8, 0xad1dd(%rip)    # 0xbd3a8
testq %r12, %r12
je 0x1052d
movq 0x8(%r12), %rax
leaq 0x50(%rsp), %rcx
movq %rax, (%rcx)
movq %rax, 0x38(%rsp)
movq %rax, 0x28(%rsp)
movq %r12, %r13
movq 0x8(%rsp), %rcx
movq 0x50(%rsp), %r14
movq 0x8(%r13), %rax
xorq %r14, %rax
testq %rbp, %rax
jne 0x103a9
cmpl $0x1, 0x10(%rcx)
jne 0x103a9
testb %bl, %bl
je 0x10235
movq %r14, %rsi
shlq $0x17, %rsi
sarq $0x17, %rsi
incq %rsi
leaq 0x50(%rsp), %rdi
callq 0x3c48
movq 0x8(%rsp), %rcx
jmp 0x10245
leaq 0x1(%r14), %rax
movq %rax, 0x547f0(%rip)     # 0x64a30
movq %rax, 0x50(%rsp)
movq (%r13), %r13
testq %r13, %r13
jne 0x101f3
testb $0x1, 0x10(%rsp)
movq 0x18(%rsp), %rbx
jne 0x1026b
movq 0x54627(%rip), %rbx     # 0x64888
leaq 0x20(%rsp), %rdi
callq 0x5b33
movq 0x30(%rsp), %rsi
xorl %edi, %edi
callq 0x61d5
movq 0x38(%rsp), %r13
movq %r13, 0x547ad(%rip)     # 0x64a30
addq 0x59246(%rip), %rbx     # 0x694d0
leaq 0x5479f(%rip), %r15     # 0x64a30
negq %rbx
shlq $0x17, %r14
sarq $0x17, %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x61d5
movq %r13, 0x54782(%rip)     # 0x64a30
movq %r15, %rdi
movq %r13, %rsi
callq 0x3c48
movl $0x2000e, %edi          # imm = 0x2000E
callq 0x59a2
movq 0x545be(%rip), %rax     # 0x64888
movq 0x5475f(%rip), %rcx     # 0x64a30
shlq $0x17, %rcx
sarq $0x17, %rcx
negq %rcx
leaq (%rax,%rcx), %rsi
incq %rsi
movq %r15, %rdi
callq 0x3c48
movq 0x5473e(%rip), %rsi     # 0x64a30
shlq $0x17, %rsi
sarq $0x17, %rsi
cmpq $0x3fff, %rsi           # imm = 0x3FFF
jg 0x1034c
addq $-0x4000, %rsi          # imm = 0xC000
leaq 0x5471f(%rip), %rbx     # 0x64a30
movq %rbx, %rdi
callq 0x3c48
movq 0x54710(%rip), %rdi     # 0x64a30
andl $0x7fff, %edi           # imm = 0x7FFF
orq $0x840000, %rdi         # imm = 0x840000
callq 0x5ed0
movq %rbx, %rdi
movq %rax, %rsi
callq 0x3c48
movq 0x546ec(%rip), %rsi     # 0x64a30
shlq $0x17, %rsi
sarq $0x17, %rsi
addq $0xec0000, %rsi         # imm = 0xEC0000
movq %rsi, %rdi
callq 0x59a2
cmpb $0x0, 0x54612(%rip)     # 0x64974
jne 0x10370
movq 0x5913d(%rip), %rdi     # 0x694a8
callq 0x59a2
movq $0x0, 0x545dd(%rip) # 0x64958
movq 0x10(%r12), %rdi
addq 0x59151(%rip), %rdi     # 0x694d8
callq 0x59a2
movq (%r12), %r12
testq %r12, %r12
jne 0x1035b
jmp 0x104f9
movl $0x58, %edi
callq 0x58ff
jmp 0x1052d
movq 0x30(%rsp), %rsi
xorl %edi, %edi
callq 0x61d5
movl 0x10(%r15), %eax
cmpl $0x1, %eax
je 0x103e8
cmpl $0x2, %eax
jne 0x103fe
movq 0x28(%r15), %rax
movq 0x30(%r15), %rcx
movq %rax, %rdx
negq %rdx
cmovsq %rax, %rdx
movq %rcx, %rax
negq %rax
cmovsq %rcx, %rax
cmpq %rax, %rdx
cmovaq %rdx, %rax
jmp 0x103ec
movq 0x20(%r15), %rax
cmpq $0x7d00, %rax           # imm = 0x7D00
jge 0x103fe
movb $0x1, %bpl
movl $0x2000e, %edi          # imm = 0x2000E
jmp 0x10405
movl $0xf00001, %edi         # imm = 0xF00001
xorl %ebp, %ebp
callq 0x59a2
leaq 0x28(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x3c48
movq (%rbx), %r14
leaq 0x5460d(%rip), %rbx     # 0x64a30
movl $0xee0000, %r13d        # imm = 0xEE0000
testb %bpl, %bpl
je 0x10499
shlq $0x17, %r14
sarq $0x17, %r14
movq 0x8(%r12), %rax
shlq $0x17, %rax
sarq $0x17, %rax
subq %rax, %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3c48
movq 0x545d8(%rip), %rsi     # 0x64a30
movq %rbx, %rdi
callq 0x3c48
movq 0x545c9(%rip), %rdi     # 0x64a30
shlq $0x17, %rdi
sarq $0x17, %rdi
callq 0x617e
leaq 0xea8000(%rax), %rdi
callq 0x59a2
movq 0x10(%r12), %rdi
addq %r13, %rdi
callq 0x59a2
movq 0x8(%r12), %r14
movq %r14, 0x28(%rsp)
jmp 0x104d4
movl $0xf08001, %edi         # imm = 0xF08001
callq 0x59a2
movq 0x8(%r12), %rax
movq %rax, 0x54581(%rip)     # 0x64a30
callq 0x5ff3
leaq 0x80a000(%rax), %rdi
movq 0x10(%r12), %r15
addq 0x59001(%rip), %r15     # 0x694c8
callq 0x59a2
movq %r15, %rdi
callq 0x59a2
movq (%r12), %r12
testq %r12, %r12
jne 0x10429
testb $0x1, 0x10(%rsp)
je 0x104f9
movq 0x18(%rsp), %rdi
addq 0x58fe4(%rip), %rdi     # 0x694d8
callq 0x59a2
movq 0x20(%rsp), %rsi
xorl %edi, %edi
callq 0x61d5
testb $0x1, 0x7(%rsp)
jne 0x1052d
cmpq $0x1, 0x543c4(%rip)     # 0x648d8
je 0x1052d
movq 0x13d6b(%rip), %rdi     # 0x24288
callq 0x59a2
movq $0x1, 0x543ab(%rip) # 0x648d8
addq $0x888, %rsp            # imm = 0x888
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq