// File: /workspace/github_cpp_makefile_star2_O3/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 0x3ef0
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 0x3fea
btl $0x13, %r14d
jb 0x3f8e
cmpl $-0x1, %edx
je 0x4056
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 0x405d
addl %r14d, %edx
movq 0x40060(%rbx), %rsi
movq 0x40068(%rbx), %rdi
subq %rsi, %rdi
sarq $0x5, %rdi
cmpq %rdx, %rdi
jbe 0x4067
movq %rdx, %r14
shlq $0x5, %r14
cmpq $0x0, 0x8(%rsi,%r14)
jne 0x3fe0
testb %cl, %cl
je 0x3fa0
movq %rsp, %rdi
movq %rbx, %rsi
callq 0x454a
jmp 0x3fb1
btl $0x13, %r14d
jae 0x3fe0
movl %r14d, %eax
andl $0x7800, %eax           # imm = 0x7800
addl $0xffffc000, %eax       # imm = 0xFFFFC000
cmpl $0x37ff, %eax           # imm = 0x37FF
ja 0x3fe0
andl $0x3fff, %r14d          # imm = 0x3FFF
movq 0x40060(%rbx), %rax
movq 0x40068(%rbx), %rcx
subq %rax, %rcx
sarq $0x5, %rcx
cmpq %r14, %rcx
jbe 0x3fe0
movl %r14d, %ecx
shll $0x5, %ecx
cmpq $0x0, 0x8(%rax,%rcx)
jne 0x3fe0
cmpl $0x1000, %r14d          # imm = 0x1000
leaq 0x157a(%rip), %rax      # 0x54d2
leaq 0x157a(%rip), %rsi      # 0x54d9
cmovbq %rax, %rsi
movq %rsp, %r15
movq %r15, %rdi
movl %r14d, %edx
xorl %eax, %eax
callq 0x254c
shll $0x5, %r14d
addq 0x40060(%rbx), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x2190
movq (%r15), %rdi
jmp 0x3fc9
cmpl $-0x1, %edx
je 0x3f99
cmpl %r14d, 0x3c(%rbx)
je 0x3fe0
movl %eax, %edi
callq 0x23a3
leaq 0x152b(%rip), %rsi      # 0x54d2
movq %rsp, %rdi
xorl %eax, %eax
callq 0x254c
addq 0x40060(%rbx), %r14
movq %rsp, %rbx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2190
movq (%rbx), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x3fe0
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x2140
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
movl %r14d, %ecx
notl %ecx
testl $0x7800, %ecx           # imm = 0x7800
jne 0x4023
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 0x4071
andl $0x7fff, %ecx           # imm = 0x7FFF
jmp 0x402c
movl %r14d, %ecx
andl $0x3fff, %ecx           # imm = 0x3FFF
movl %ecx, 0x38(%rbx)
movl %r14d, 0x3c(%rbx)
movq 0x3f9e(%rip), %rdx      # 0x7fd8
movq (%rdx), %rdi
leaq 0x151d(%rip), %rsi      # 0x5561
movl %eax, %edx
xorl %eax, %eax
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
jmp 0x21d0
movl %eax, %edi
callq 0x2410
movl %eax, %edi
movl %r14d, %esi
callq 0x23eb
movl %eax, %edi
movl %r14d, %esi
callq 0x23c6
movl %eax, %edi
callq 0x2433