// File: /workspace/github_cpp_makefile_star2_O2/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 0xd048
movq 0x55bcf(%rip), %rax     # 0x63aa0
movq (%rax), %rax
cmpq 0x55b25(%rip), %rax     # 0x63a00
movq %rax, 0x10(%rsp)
je 0xdeec
movl 0x10(%rax), %eax
decl %eax
cmpl $0x1, %eax
ja 0xdf06
leaq 0xf0(%rsp), %rdi
pushq $0x2
popq %rsi
callq 0xaa9a
addq $-0x8, 0xae4bc(%rip)    # 0xbc3c0
jmp 0xdf0e
pushq $0x19
popq %rdi
callq 0x4f2c
movabsq $0x1ffffffffff, %rbx    # imm = 0x1FFFFFFFFFF
callq 0x5107
leaq 0x30(%rsp), %rdi
andq $0x0, (%rdi)
leaq 0x20(%rsp), %rax
andq $0x0, (%rax)
callq 0x5148
pushq $0x2a
popq %rdi
callq 0x7429
movb $0x1, 0x7(%rsp)
pushq $-0x1
popq %rax
movq %rax, 0x18(%rsp)
xorl %r12d, %r12d
movq $0x0, 0x8(%rsp)
xorl %r15d, %r15d
xorl %r13d, %r13d
movl 0x558bb(%rip), %eax     # 0x6381c
cmpl $0xf, %eax
je 0xdffb
cmpl $0x27, %eax
je 0xdffb
callq 0x51a1
movq $0x1, 0x55955(%rip) # 0x638d8
cmpl $0x31, 0x55892(%rip)    # 0x6381c
jne 0xe016
testb $0x1, 0x8(%rsp)
je 0xdf9f
pushq $0x49
popq %rdi
callq 0x4f2c
leaq 0x718(%rsp), %rdi
callq 0x6316
movb $0x1, %al
movq %rax, 0x8(%rsp)
movq 0x558ce(%rip), %rax     # 0x63888
movq %rax, 0x18(%rsp)
pushq $0x12
popq %rdi
callq 0x7429
leaq 0x98(%rsp), %rdi
callq 0xe7dc
addq $-0x8, 0xae44c(%rip)    # 0xbc428
cmpq $0x1, 0x558f4(%rip)     # 0x638d8
sete %al
andb %al, 0x7(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x5148
movl 0x55821(%rip), %eax     # 0x6381c
cmpl $0x27, %eax
je 0xe0fc
leaq 0x2c8(%rsp), %rdi
callq 0x6316
jmp 0xdf5b
leaq 0x48(%rsp), %rdi
leaq 0x40(%rsp), %rsi
pushq $0x1
popq %rdx
callq 0x71f0
movq 0x48(%rsp), %rsi
testq %rsi, %rsi
je 0xe0dd
testq %r15, %r15
je 0xe061
leaq 0x50(%rsp), %rdi
movq %r15, %rdx
callq 0x74d4
addq $-0x8, 0xae358(%rip)    # 0xbc3a8
cmpb $0x0, 0x50(%rsp)
jne 0xe064
pushq $0x7
popq %rdi
callq 0x4f2c
jmp 0xe064
movq %rsi, %r15
pushq $0x18
popq %rdi
callq 0x390b
movq %rax, %rbp
movq 0x40(%rsp), %rax
movq %rax, 0x8(%rbp)
movq 0x55809(%rip), %rcx     # 0x63888
movq %rcx, 0x10(%rbp)
movq %rax, %rcx
shlq $0x17, %rcx
movq %r13, %r14
testq %r14, %r14
je 0xe0ba
movq 0x8(%r14), %rdx
movq %rdx, %rsi
xorq %rax, %rsi
testq %rbx, %rsi
je 0xe0b2
shlq $0x17, %rdx
cmpq %rdx, %rcx
jl 0xe0ba
movq %r14, %r12
movq (%r14), %r14
jmp 0xe08d
pushq $0x49
popq %rdi
callq 0x4f2c
cmpq %r13, %r14
je 0xe0c9
movq %r14, (%rbp)
movq %rbp, (%r12)
jmp 0xe0d0
movq %r13, (%rbp)
movq %rbp, %r13
leaq 0x5a8(%rsp), %rdi
callq 0x6316
cmpl $0xe, 0x55738(%rip)     # 0x6381c
jne 0xdfbf
leaq 0x438(%rsp), %rdi
callq 0x6316
jmp 0xe016
leaq 0x158(%rsp), %rdi
callq 0x6316
leaq 0x50(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
movq 0x10(%rsp), %r12
movq %r12, %rdx
callq 0x74d4
addq $-0x8, 0xae27f(%rip)    # 0xbc3a8
cmpb $0x0, (%r14)
je 0xe1dc
callq 0x51a1
movq 0x558a9(%rip), %rdx     # 0x639e8
leaq 0x50(%rsp), %r14
movq %r14, %rdi
movq %r12, %rsi
callq 0x74d4
movb (%r14), %bpl
addq $-0x8, 0xae24e(%rip)    # 0xbc3a8
testq %r13, %r13
je 0xe4a3
movq 0x8(%r13), %rax
leaq 0x50(%rsp), %rcx
movq %rax, (%rcx)
movq %rax, 0x38(%rsp)
movq %rax, 0x28(%rsp)
movq %r13, %r12
movq 0x10(%rsp), %rcx
testq %r12, %r12
je 0xe243
movq 0x50(%rsp), %r14
movq 0x8(%r12), %rax
xorq %r14, %rax
testq %rbx, %rax
jne 0xe1e9
cmpl $0x1, 0x10(%rcx)
jne 0xe1e9
testb %bpl, %bpl
je 0xe1c6
movq %r14, %rsi
shlq $0x17, %rsi
sarq $0x17, %rsi
incq %rsi
leaq 0x50(%rsp), %rdi
callq 0x381c
movq 0x10(%rsp), %rcx
jmp 0xe1d6
leaq 0x1(%r14), %rax
movq %rax, 0x5585f(%rip)     # 0x63a30
movq %rax, 0x50(%rsp)
movq (%r12), %r12
jmp 0xe181
pushq $0x58
popq %rdi
callq 0x4f2c
jmp 0xe4a3
movq 0x30(%rsp), %rsi
xorl %edi, %edi
callq 0x56f1
movl 0x10(%r15), %eax
cmpl $0x1, %eax
je 0xe378
cmpl $0x2, %eax
jne 0xe396
movq %r15, %rdi
callq 0x12d9c
movq 0x28(%rax), %rax
movq %rax, %rbx
negq %rbx
cmovsq %rax, %rbx
movq %r15, %rdi
callq 0x12d9c
movq 0x30(%rax), %rcx
movq %rcx, %rax
negq %rax
cmovsq %rcx, %rax
cmpq %rax, %rbx
cmovaq %rbx, %rax
jmp 0xe384
testb $0x1, 0x8(%rsp)
movq 0x18(%rsp), %rbx
jne 0xe260
movq 0x55632(%rip), %rbx     # 0x63888
leaq 0x20(%rsp), %rdi
callq 0x5148
movq 0x30(%rsp), %rsi
xorl %edi, %edi
callq 0x56f1
movq 0x38(%rsp), %r12
movq %r12, 0x557b8(%rip)     # 0x63a30
addq 0x5a251(%rip), %rbx     # 0x684d0
leaq 0x557aa(%rip), %r15     # 0x63a30
negq %rbx
shlq $0x17, %r14
sarq $0x17, %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x56f1
movq %r12, 0x5578d(%rip)     # 0x63a30
movq %r15, %rdi
movq %r12, %rsi
callq 0x381c
movl $0x2000e, %edi          # imm = 0x2000E
callq 0x4fcb
movq 0x555c9(%rip), %rax     # 0x63888
movq 0x5576a(%rip), %rcx     # 0x63a30
shlq $0x17, %rcx
sarq $0x17, %rcx
negq %rcx
leaq (%rax,%rcx), %rsi
incq %rsi
movq %r15, %rdi
callq 0x381c
movq 0x55749(%rip), %rsi     # 0x63a30
shlq $0x17, %rsi
sarq $0x17, %rsi
cmpq $0x3fff, %rsi           # imm = 0x3FFF
jg 0xe341
addq $-0x4000, %rsi          # imm = 0xC000
leaq 0x5572a(%rip), %rbx     # 0x63a30
movq %rbx, %rdi
callq 0x381c
movq 0x5571b(%rip), %rdi     # 0x63a30
andl $0x7fff, %edi           # imm = 0x7FFF
orq $0x840000, %rdi         # imm = 0x840000
callq 0x546d
movq %rbx, %rdi
movq %rax, %rsi
callq 0x381c
movq 0x556f7(%rip), %rsi     # 0x63a30
shlq $0x17, %rsi
sarq $0x17, %rsi
movb 0x7(%rsp), %bl
addq $0xec0000, %rsi         # imm = 0xEC0000
movq %rsi, %rdi
callq 0x4fcb
testq %r13, %r13
je 0xe48d
callq 0x51a1
movq 0x10(%r13), %rdi
addq 0x5a16b(%rip), %rdi     # 0x684d8
callq 0x4fcb
movq (%r13), %r13
jmp 0xe354
movq %r15, %rdi
callq 0x12dc6
movq 0x20(%rax), %rax
cmpq $0x7d00, %rax           # imm = 0x7D00
jge 0xe396
movb $0x1, %bpl
movl $0x2000e, %edi          # imm = 0x2000E
jmp 0xe39d
movl $0xf00001, %edi         # imm = 0xF00001
xorl %ebp, %ebp
callq 0x4fcb
leaq 0x28(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x381c
movq (%rbx), %r14
leaq 0x55675(%rip), %rbx     # 0x63a30
movl $0xee0000, %r15d        # imm = 0xEE0000
testq %r13, %r13
je 0xe471
testb %bpl, %bpl
je 0xe437
shlq $0x17, %r14
sarq $0x17, %r14
movq 0x8(%r13), %rax
shlq $0x17, %rax
sarq $0x17, %rax
subq %rax, %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x381c
movq 0x55638(%rip), %rsi     # 0x63a30
movq %rbx, %rdi
callq 0x381c
movq 0x55629(%rip), %rdi     # 0x63a30
shlq $0x17, %rdi
sarq $0x17, %rdi
callq 0x569a
leaq 0xea8000(%rax), %rdi
callq 0x4fcb
movq 0x10(%r13), %rdi
addq %r15, %rdi
callq 0x4fcb
movq 0x8(%r13), %r14
movq %r14, 0x28(%rsp)
jmp 0xe468
movl $0xf08001, %edi         # imm = 0xF08001
callq 0x4fcb
movq 0x8(%r13), %rax
movq %rax, 0x555e4(%rip)     # 0x63a30
callq 0x554f
leaq 0x80a000(%rax), %rdi
movq 0x10(%r13), %rsi
addq 0x5a065(%rip), %rsi     # 0x684c8
callq 0x50e3
movq (%r13), %r13
jmp 0xe3c1
testb $0x1, 0x8(%rsp)
movb 0x7(%rsp), %bl
je 0xe48d
movq 0x18(%rsp), %rdi
addq 0x5a050(%rip), %rdi     # 0x684d8
callq 0x4fcb
movq 0x20(%rsp), %rsi
xorl %edi, %edi
callq 0x56f1
testb $0x1, %bl
jne 0xe4a3
callq 0x5107
addq $0x888, %rsp            # imm = 0x888
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq