// File: besm6[P]pascal-re/dtran.cc
// Function: main
int
main (int argc, char **argv)
{
    int basereg = 0;
    bool nolabels = false, noequs = false, nooctal = false, litconst = false;

    const char * usage = "Usage: %s [-l] [-e] [-o] [-c] [-Rbase] [-d] objfile\n";
    char opt;

    while ((opt = getopt(argc, argv, "cdeloR:")) != -1) {
        switch (opt) {
        case 'l':
            // To produce a compilable assembly code,
            // not needed for decompile.
            nolabels = true;
            break;
        case 'e':
            // To produce a compilable assembly code
            // and to simplify decompilation.
            // If not used, the output will match DTRAN closely.
            noequs = true;
            break;
        case 'o':
            // If not used, the output will match DTRAN closely,
            // if used, the offsets will always be printed in decimal.
            nooctal = true;
            break;
        case 'c':
            litconst = true;
            // References to the const section printed as literals;
            // used for decompilation.
            break;
        case 'R':	/* -RN (decimal) use reg N as base */
            // Say -R8 for decompilation
            basereg = 0;
            while (*optarg >= '0' && *optarg <= '9') {
                basereg *= 10;
                basereg += *optarg - '0';
                ++optarg;
            }
            if (basereg == 0 || basereg > 017) {
                fprintf(stderr, "Bad base reg %o, need 1 <= R <= 15\n",
                        basereg);
                exit(1);
            }
            break;
        case 'd':
            // Decompilation all-in-one mode.
            noequs = true;
            nooctal = true;
            litconst = true;
            basereg = 8;
            break;
        default: /* '?' */
            fprintf(stderr, usage, argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    if (optind >= argc) {
        fprintf (stderr, usage, argv[0]);
        exit (EXIT_FAILURE);
    }
    fprintf(stderr, "Decompiling file %s\n", argv[optind]);
    Dtran dtr(argv[optind], basereg, nolabels, noequs, nooctal);
    dtr.dump_symtab();
    dtr.prtext(litconst);
    dtr.prconst(dtr.cmd_len, dtr.const_len, litconst);
    if (dtr.data_len) {
        printf(" ,DATA,\n");
        if (litconst) {
            dtr.prdata();
        } else {
            dtr.prconst(dtr.cmd_len + dtr.const_len, dtr.data_len, false);
            dtr.prsets();
        }
    }
    printf(" ,END,\n");
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x400d0, %rsp          # imm = 0x400D0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movb $0x0, -0x15(%rbp)
movb $0x0, -0x16(%rbp)
movb $0x0, -0x17(%rbp)
movb $0x0, -0x18(%rbp)
leaq 0x4c6b(%rip), %rax      # 0x82a2
movq %rax, -0x20(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x4c8e(%rip), %rdx      # 0x82d7
callq 0x3060
movb %al, -0x21(%rbp)
movsbl %al, %eax
cmpl $-0x1, %eax
je 0x37a1
movsbl -0x21(%rbp), %eax
addl $-0x52, %eax
movl %eax, %ecx
movq %rcx, -0x400b8(%rbp)
subl $0x1d, %eax
ja 0x3776
movq -0x400b8(%rbp), %rax
leaq 0x4980(%rip), %rcx      # 0x8004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x1, -0x15(%rbp)
jmp 0x379c
movb $0x1, -0x16(%rbp)
jmp 0x379c
movb $0x1, -0x17(%rbp)
jmp 0x379c
movb $0x1, -0x18(%rbp)
jmp 0x379c
movl $0x0, -0x14(%rbp)
movq 0x7909(%rip), %rax      # 0xafc8
movq (%rax), %rax
movsbl (%rax), %ecx
xorl %eax, %eax
cmpl $0x30, %ecx
movb %al, -0x400b9(%rbp)
jl 0x36eb
movq 0x78ef(%rip), %rax      # 0xafc8
movq (%rax), %rax
movsbl (%rax), %eax
cmpl $0x39, %eax
setle %al
movb %al, -0x400b9(%rbp)
movb -0x400b9(%rbp), %al
testb $0x1, %al
jne 0x36f7
jmp 0x372e
imull $0xa, -0x14(%rbp), %eax
movl %eax, -0x14(%rbp)
movq 0x78c3(%rip), %rax      # 0xafc8
movq (%rax), %rax
movsbl (%rax), %eax
subl $0x30, %eax
addl -0x14(%rbp), %eax
movl %eax, -0x14(%rbp)
movq 0x78ad(%rip), %rax      # 0xafc8
movq (%rax), %rcx
addq $0x1, %rcx
movq 0x789f(%rip), %rax      # 0xafc8
movq %rcx, (%rax)
jmp 0x36b8
cmpl $0x0, -0x14(%rbp)
je 0x373a
cmpl $0xf, -0x14(%rbp)
jle 0x375f
movq 0x7897(%rip), %rax      # 0xafd8
movq (%rax), %rdi
movl -0x14(%rbp), %edx
leaq 0x4b91(%rip), %rsi      # 0x82df
movb $0x0, %al
callq 0x32e0
movl $0x1, %edi
callq 0x3250
jmp 0x379c
movb $0x1, -0x16(%rbp)
movb $0x1, -0x17(%rbp)
movb $0x1, -0x18(%rbp)
movl $0x8, -0x14(%rbp)
jmp 0x379c
movq 0x785b(%rip), %rax      # 0xafd8
movq (%rax), %rdi
movq -0x20(%rbp), %rsi
movq -0x10(%rbp), %rax
movq (%rax), %rdx
movb $0x0, %al
callq 0x32e0
movl $0x1, %edi
callq 0x3250
jmp 0x363b
movq 0x7838(%rip), %rax      # 0xafe0
movl (%rax), %eax
cmpl -0x8(%rbp), %eax
jl 0x37d5
movq 0x7822(%rip), %rax      # 0xafd8
movq (%rax), %rdi
movq -0x20(%rbp), %rsi
movq -0x10(%rbp), %rax
movq (%rax), %rdx
movb $0x0, %al
callq 0x32e0
movl $0x1, %edi
callq 0x3250
movq 0x77fc(%rip), %rax      # 0xafd8
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x77f6(%rip), %rcx      # 0xafe0
movq %rcx, -0x400d0(%rbp)
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rdx
leaq 0x4b04(%rip), %rsi      # 0x8303
xorl %eax, %eax
callq 0x32e0
movq -0x400d0(%rbp), %rcx
movq -0x10(%rbp), %rax
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rsi
movl -0x14(%rbp), %edx
movzbl -0x17(%rbp), %r9d
movzbl -0x16(%rbp), %r8d
movzbl -0x15(%rbp), %ecx
andl $0x1, %ecx
andl $0x1, %r8d
andl $0x1, %r9d
leaq -0x400a0(%rbp), %rdi
movq %rdi, -0x400c8(%rbp)
callq 0x3950
movq -0x400c8(%rbp), %rdi
callq 0x3c30
jmp 0x3855
movzbl -0x18(%rbp), %esi
andl $0x1, %esi
leaq -0x400a0(%rbp), %rdi
callq 0x3c90
jmp 0x386a
movl -0x40088(%rbp), %esi
movl -0x40080(%rbp), %edx
movzbl -0x18(%rbp), %ecx
andl $0x1, %ecx
leaq -0x400a0(%rbp), %rdi
callq 0x3ed0
jmp 0x388b
cmpl $0x0, -0x40094(%rbp)
je 0x3910
leaq 0x4a7d(%rip), %rdi      # 0x8318
xorl %eax, %eax
callq 0x3040
jmp 0x38a4
testb $0x1, -0x18(%rbp)
je 0x38da
leaq -0x400a0(%rbp), %rdi
callq 0x4180
jmp 0x38b8
jmp 0x390e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x400a8(%rbp)
movl %eax, -0x400ac(%rbp)
leaq -0x400a0(%rbp), %rdi
callq 0x48c0
jmp 0x393f
movl -0x40094(%rbp), %edx
movl -0x40088(%rbp), %esi
movl -0x40080(%rbp), %eax
addl %eax, %esi
leaq -0x400a0(%rbp), %rdi
xorl %ecx, %ecx
callq 0x3ed0
jmp 0x38fe
leaq -0x400a0(%rbp), %rdi
callq 0x46b0
jmp 0x390c
jmp 0x390e
jmp 0x3910
leaq 0x4a0a(%rip), %rdi      # 0x8321
xorl %eax, %eax
callq 0x3040
jmp 0x3920
movl $0x0, -0x4(%rbp)
leaq -0x400a0(%rbp), %rdi
callq 0x48c0
movl -0x4(%rbp), %eax
addq $0x400d0, %rsp          # imm = 0x400D0
popq %rbp
retq
movq -0x400a8(%rbp), %rdi
callq 0x3370
nopl (%rax,%rax)