// File: /workspace/github_cpp_makefile_star2_O2/besm6[P]pascal-re/dtran.cc
// Function: Dtran::mklabels(unsigned int, unsigned int, bool)
void
mklabels(uint32 memaddr, uint32 opcode, bool litconst) {
    int arg1 = (opcode & 07777) + (opcode & 0x040000 ? 070000 : 0);
    int arg2 = opcode & 077777;
    int struc = opcode & 02000000;
    uint reg = opcode >> 20;
    if (basereg && basereg == reg) {
        if (baseaddr == ~0u &&
            (opcode & 03740000) == 02440000) {
            // Setting base reg by a relative address or a symbol
            if ((opcode & 074000) == 074000) {
                uint sympos = opcode & 03777;
                if (memory[table_off + sympos] >> 15 != 0410) {
                    fprintf(stderr, "@%05o Base register set to non-relative address\n", memaddr);
                    exit(1);
                }
                baseaddr = memory[table_off + sympos] & 077777;
            } else {
                baseaddr = opcode & 037777;
            }
            baseop = opcode;
            fprintf(stderr, "@%05o Base register set to %05o\n", memaddr, baseaddr);
        } else if (struc) {
            // Must be the same opcode as used originally.
            if (baseaddr == ~0u || baseop != opcode) {
                fprintf(stderr,
                        "@%05o Base register used in a long-address insn\n", memaddr);
                exit(1);
            }
        } else if (baseaddr == ~0u) {
            fprintf(stderr,
                    "@%05o Base register used but not yet set\n", memaddr);
            exit(1);
        } else if (arg1 >= 04000) {
            fprintf(stderr,
                    "@%05o Base register used with a symbol (%04o)\n", memaddr, arg1);
            exit(1);
        } else {
            uint off = baseaddr + arg1;
            if (off >= labels.size()) {
                fprintf(stderr, "@%05o Base offset %05o too large\n", memaddr, arg1);
                exit(1);
            }
            if (labels[off].empty())
                labels[off] = litconst ? get_literal(off) : strprintf("*%04oB", off);
        }
    } else if (struc && arg2 >= 074000) {
        // nothing
    } else if (struc && arg2 >= 040000 &&
               (arg2 & 037777) < labels.size()) {
        uint off = arg2 & 037777;
        if (labels[off].empty())
            labels[off] = off < 010000 ?
                                strprintf("*%04oB", off) :
                                strprintf("*%05o", off);
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x20, %rsp
movl %edx, %r14d
movl %esi, %eax
movq %rdi, %rbx
movl 0x34(%rdi), %edx
testl %edx, %edx
sete %sil
movl %r14d, %edi
shrl $0x14, %edi
cmpl %edi, %edx
setne %dl
orb %sil, %dl
jne 0x3b3c
movl 0x38(%rbx), %edx
movl %edx, %esi
notl %esi
movl %r14d, %edi
andl $0xfc000, %edi          # imm = 0xFC000
xorl $0xa4000, %edi          # imm = 0xA4000
orl %esi, %edi
je 0x3c33
btl $0x13, %r14d
jb 0x3bda
cmpl $-0x1, %edx
je 0x3ca2
movl %r14d, %esi
andl $0xfff, %esi            # imm = 0xFFF
shll $0xd, %r14d
sarl $0x1f, %r14d
andl $0x7000, %r14d          # imm = 0x7000
orl %esi, %r14d
cmpl $0x800, %r14d           # imm = 0x800
jae 0x3cb5
addl %r14d, %edx
movq 0x40060(%rbx), %rsi
movq 0x40068(%rbx), %rdi
subq %rsi, %rdi
sarq $0x5, %rdi
cmpq %rdx, %rdi
jbe 0x3cc8
movq %rdx, %r14
shlq $0x5, %r14
cmpq $0x0, 0x8(%rsi,%r14)
jne 0x3c29
testb %cl, %cl
je 0x3bfb
movq %rsp, %rdi
movq %rbx, %rsi
callq 0x4194
jmp 0x3c0c
btl $0x13, %r14d
jae 0x3c29
movl %r14d, %eax
andl $0x7800, %eax           # imm = 0x7800
addl $0xffffc000, %eax       # imm = 0xFFFFC000
cmpl $0x37ff, %eax           # imm = 0x37FF
ja 0x3c29
andl $0x3fff, %r14d          # imm = 0x3FFF
movq 0x40060(%rbx), %rax
movq 0x40068(%rbx), %rcx
subq %rax, %rcx
sarq $0x5, %rcx
cmpq %r14, %rcx
jbe 0x3c29
movl %r14d, %ecx
shll $0x5, %ecx
cmpq $0x0, 0x8(%rax,%rcx)
jne 0x3c29
cmpl $0x1000, %r14d          # imm = 0x1000
leaq 0x192e(%rip), %rax      # 0x54d2
leaq 0x192e(%rip), %rsi      # 0x54d9
cmovbq %rax, %rsi
movq %rsp, %r15
movq %r15, %rdi
movl %r14d, %edx
xorl %eax, %eax
callq 0x23cc
shll $0x5, %r14d
addq 0x40060(%rbx), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x21a0
movq %r15, %rdi
jmp 0x3c24
cmpl $-0x1, %edx
je 0x3be5
cmpl %r14d, 0x3c(%rbx)
je 0x3c29
movq 0x43ec(%rip), %rcx      # 0x7fd8
movq (%rcx), %rdi
leaq 0x198c(%rip), %rsi      # 0x5582
jmp 0x3cf8
leaq 0x18d0(%rip), %rsi      # 0x54d2
movq %rsp, %rdi
xorl %eax, %eax
callq 0x23cc
addq 0x40060(%rbx), %r14
movq %rsp, %rbx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x21a0
movq %rbx, %rdi
callq 0x20b0
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
movl %r14d, %ecx
notl %ecx
testw $0x7800, %cx            # imm = 0x7800
jne 0x3c6f
movl %r14d, %ecx
andl $0x7ff, %ecx            # imm = 0x7FF
addl 0x24(%rbx), %ecx
movq 0x48(%rbx,%rcx,8), %rcx
movq %rcx, %rdx
andq $-0x8000, %rdx          # imm = 0x8000
cmpq $0x840000, %rdx         # imm = 0x840000
jne 0x3ce7
andl $0x7fff, %ecx           # imm = 0x7FFF
jmp 0x3c78
movl %r14d, %ecx
andl $0x3fff, %ecx           # imm = 0x3FFF
movl %ecx, 0x38(%rbx)
movl %r14d, 0x3c(%rbx)
movq 0x4352(%rip), %rdx      # 0x7fd8
movq (%rdx), %rdi
leaq 0x18d1(%rip), %rsi      # 0x5561
movl %eax, %edx
xorl %eax, %eax
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
jmp 0x2200
movq 0x432f(%rip), %rcx      # 0x7fd8
movq (%rcx), %rdi
leaq 0x1900(%rip), %rsi      # 0x55b3
jmp 0x3cf8
movq 0x431c(%rip), %rcx      # 0x7fd8
movq (%rcx), %rdi
leaq 0x1917(%rip), %rsi      # 0x55dd
jmp 0x3cd9
movq 0x4309(%rip), %rcx      # 0x7fd8
movq (%rcx), %rdi
leaq 0x1933(%rip), %rsi      # 0x560c
movl %eax, %edx
movl %r14d, %ecx
xorl %eax, %eax
callq 0x2200
jmp 0x3d01
movq 0x42ea(%rip), %rcx      # 0x7fd8
movq (%rcx), %rdi
leaq 0x1838(%rip), %rsi      # 0x5530
movl %eax, %edx
xorl %eax, %eax
callq 0x2200
pushq $0x1
popq %rdi
callq 0x2190
nop