// File: /workspace/github_c_makefile_star2_O0/wjmelements[P]evm/evm.c
// Function: main
int main(int argc, char *const argv[]) {
    selfPath = argv[0];
    int option;
    char *contents = NULL;
    while ((option = getopt (argc, argv, "cdgjlo:suw:x")) != -1)
        switch (option) {
            case 'c':
                wrapConstructor = 1;
                break;
            case 'd':
                inverse = 1;
                break;
            case 'j':
                labelJumpdests = 1;
                break;
            case 'o':
                contents = optarg;
                break;
            case 'x':
                runtime = 1;
                break;
            case 'g':
                includeGas = 1;
                break;
            case 's':
                includeStatus = 1;
                break;
            case 'l':
                includeLogs = 1;
                break;
            case 'u':
                updateConfigFile = 1;
                break;
            case 'w':
                if (configFile == NULL) {
                    evmInit();
                }
                configFile = optarg;
                dioInit(selfPath);
                loadConfig(configFile, updateConfigFile);
                break;
            case '?':
            default:
                USAGE;
                return 1;
        }
    if (inverse && wrapConstructor) {
        fputs("-c cannot be used with -d\n", stderr);
        USAGE;
        return 1;
    }
    if (inverse && labelJumpdests) {
        fputs("-j cannot be used with -d\n", stderr);
        USAGE;
        return 1;
    }
    if (runtime && wrapConstructor) {
        fputs("-c cannot be used with -x\n", stderr);
        USAGE;
        return 1;
    }
    if (runtime && labelJumpdests) {
        fputs("-j cannot be used with -x\n", stderr);
        USAGE;
        return 1;
    }
    if (inverse && runtime) {
        fputs("-d cannot be used with -x\n", stderr);
        USAGE;
        return 1;
    }
    void (*subprogram)(const char*);
    if (inverse) {
        subprogram = disassemble;
    } else if (runtime) {
        subprogram = execute;
    } else if (configFile) {
        // tests should _exit(1) if they fail
        _exit(0);
    } else {
        subprogram = assemble;
    }
    if (contents != NULL) {
        // input is from the command line
        subprogram(contents);
    } else if (optind == argc) {
        // read from stdin
        size_t bufferSize = 4;
        size_t capacity = bufferSize - 1;
        char *input = calloc(1, bufferSize);
        char *pos = input;
        while (1) {
            ssize_t red = read(0, pos, capacity);
            if (red == -1) {
                perror("stdin");
                return 1;
            }
            if (red == 0) {
                // EOF
                break;
            }
            capacity -= red;
            if (capacity) {
                pos += red;
            } else {
                char *next = calloc(1, bufferSize << 1);
                memcpy(next, input, bufferSize);
                pos = next + bufferSize - 1;
                capacity = bufferSize;
                bufferSize <<= 1;
                free(input);
                input = next;
            }
        }
        subprogram(input);
        // free is redundant with program termination but makes valgrind happy
        free(input);
    } else for (int i = optind; i < argc; i++) {
        int fd = open(argv[i], O_RDONLY);
        if (fd == -1) {
            perror(argv[i]);
            _exit(1);
        }

        struct stat fstatus;
        int fstatSuccess = fstat(fd, &fstatus);
        if (fstatSuccess == -1) {
            perror(argv[i]);
            _exit(1);
        }
        
        contents = mmap(NULL, fstatus.st_size, PROT_READ, MAP_PRIVATE | MAP_FILE, fd, 0);
        if (contents == NULL) {
            perror(argv[i]);
        }
        subprogram(contents);
        munmap(contents, fstatus.st_size);
        close(fd);
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, 0x1d609(%rip)     # 0x209f0
movq $0x0, -0x20(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x16cef(%rip), %rdx     # 0x1a0ec
callq 0x3270
movl %eax, -0x14(%rbp)
cmpl $-0x1, %eax
je 0x352a
movl -0x14(%rbp), %eax
addl $-0x3f, %eax
movl %eax, %ecx
movq %rcx, -0x100(%rbp)
subl $0x39, %eax
ja 0x3503
movq -0x100(%rbp), %rax
leaq 0x16bd0(%rip), %rcx     # 0x1a004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x1, 0x1d5b1(%rip)     # 0x209f8
jmp 0x3525
movl $0x1, 0x1d5a6(%rip)     # 0x209fc
jmp 0x3525
movl $0x1, 0x1d59b(%rip)     # 0x20a00
jmp 0x3525
movq 0x1cb67(%rip), %rax     # 0x1ffd8
movq (%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x3525
movl $0x1, 0x1d57d(%rip)     # 0x20a04
jmp 0x3525
movl $0x1, 0x1d572(%rip)     # 0x20a08
jmp 0x3525
movl $0x1, 0x1d567(%rip)     # 0x20a0c
jmp 0x3525
movl $0x1, 0x1d55f(%rip)     # 0x20a10
jmp 0x3525
movl $0x1, 0x1d557(%rip)     # 0x20a14
jmp 0x3525
cmpq $0x0, 0x1d551(%rip)     # 0x20a18
jne 0x34d0
movb $0x0, %al
callq 0x8870
movq 0x1cb01(%rip), %rax     # 0x1ffd8
movq (%rax), %rax
movq %rax, 0x1d537(%rip)     # 0x20a18
movq 0x1d508(%rip), %rdi     # 0x209f0
callq 0x3fa0
movq 0x1d524(%rip), %rdi     # 0x20a18
movl 0x1d51a(%rip), %esi     # 0x20a14
callq 0x5970
jmp 0x3525
jmp 0x3503
movq 0x1caee(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16be5(%rip), %rdi     # 0x1a0f9
callq 0x3130
movl $0x1, -0x4(%rbp)
jmp 0x391a
jmp 0x33ef
cmpl $0x0, 0x1d4cb(%rip)     # 0x209fc
je 0x3574
cmpl $0x0, 0x1d4be(%rip)     # 0x209f8
je 0x3574
movq 0x1cab5(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16bff(%rip), %rdi     # 0x1a14c
callq 0x3130
movq 0x1ca9f(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16b96(%rip), %rdi     # 0x1a0f9
callq 0x3130
movl $0x1, -0x4(%rbp)
jmp 0x391a
cmpl $0x0, 0x1d481(%rip)     # 0x209fc
je 0x35be
cmpl $0x0, 0x1d47c(%rip)     # 0x20a00
je 0x35be
movq 0x1ca6b(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16bd0(%rip), %rdi     # 0x1a167
callq 0x3130
movq 0x1ca55(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16b4c(%rip), %rdi     # 0x1a0f9
callq 0x3130
movl $0x1, -0x4(%rbp)
jmp 0x391a
cmpl $0x0, 0x1d43f(%rip)     # 0x20a04
je 0x3608
cmpl $0x0, 0x1d42a(%rip)     # 0x209f8
je 0x3608
movq 0x1ca21(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16ba1(%rip), %rdi     # 0x1a182
callq 0x3130
movq 0x1ca0b(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16b02(%rip), %rdi     # 0x1a0f9
callq 0x3130
movl $0x1, -0x4(%rbp)
jmp 0x391a
cmpl $0x0, 0x1d3f5(%rip)     # 0x20a04
je 0x3652
cmpl $0x0, 0x1d3e8(%rip)     # 0x20a00
je 0x3652
movq 0x1c9d7(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16b72(%rip), %rdi     # 0x1a19d
callq 0x3130
movq 0x1c9c1(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16ab8(%rip), %rdi     # 0x1a0f9
callq 0x3130
movl $0x1, -0x4(%rbp)
jmp 0x391a
cmpl $0x0, 0x1d3a3(%rip)     # 0x209fc
je 0x369c
cmpl $0x0, 0x1d3a2(%rip)     # 0x20a04
je 0x369c
movq 0x1c98d(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16b43(%rip), %rdi     # 0x1a1b8
callq 0x3130
movq 0x1c977(%rip), %rax     # 0x1fff8
movq (%rax), %rsi
leaq 0x16a6e(%rip), %rdi     # 0x1a0f9
callq 0x3130
movl $0x1, -0x4(%rbp)
jmp 0x391a
cmpl $0x0, 0x1d359(%rip)     # 0x209fc
je 0x36b2
leaq 0x284(%rip), %rax       # 0x3930
movq %rax, -0x28(%rbp)
jmp 0x36e8
cmpl $0x0, 0x1d34b(%rip)     # 0x20a04
je 0x36c8
leaq 0x2ae(%rip), %rax       # 0x3970
movq %rax, -0x28(%rbp)
jmp 0x36e6
cmpq $0x0, 0x1d348(%rip)     # 0x20a18
je 0x36d9
xorl %edi, %edi
callq 0x3080
leaq 0x570(%rip), %rax       # 0x3c50
movq %rax, -0x28(%rbp)
jmp 0x36e6
jmp 0x36e8
cmpq $0x0, -0x20(%rbp)
je 0x36fe
movq -0x28(%rbp), %rax
movq -0x20(%rbp), %rdi
callq *%rax
jmp 0x3913
movq 0x1c8cb(%rip), %rax     # 0x1ffd0
movl (%rax), %eax
cmpl -0x8(%rbp), %eax
jne 0x3817
movq $0x4, -0x30(%rbp)
movq -0x30(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rsi
movl $0x1, %edi
callq 0x31c0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rsi
movq -0x38(%rbp), %rdx
xorl %edi, %edi
callq 0x3190
movq %rax, -0x50(%rbp)
cmpq $-0x1, -0x50(%rbp)
jne 0x3770
leaq 0x16a74(%rip), %rdi     # 0x1a1d3
callq 0x3260
movl $0x1, -0x4(%rbp)
jmp 0x391a
cmpq $0x0, -0x50(%rbp)
jne 0x377c
jmp 0x37ff
movq -0x50(%rbp), %rcx
movq -0x38(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x37a0
movq -0x50(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x37fa
movq -0x30(%rbp), %rsi
shlq %rsi
movl $0x1, %edi
callq 0x31c0
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x3200
movq -0x58(%rbp), %rax
addq -0x30(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x48(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
shlq %rax
movq %rax, -0x30(%rbp)
movq -0x40(%rbp), %rdi
callq 0x3040
movq -0x58(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x373e
movq -0x28(%rbp), %rax
movq -0x40(%rbp), %rdi
callq *%rax
movq -0x40(%rbp), %rdi
callq 0x3040
jmp 0x3911
movq 0x1c7b2(%rip), %rax     # 0x1ffd0
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x390f
movq -0x10(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
xorl %esi, %esi
movb $0x0, %al
callq 0x3250
movl %eax, -0x60(%rbp)
cmpl $-0x1, -0x60(%rbp)
jne 0x3868
movq -0x10(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3260
movl $0x1, %edi
callq 0x3080
movl -0x60(%rbp), %edi
leaq -0xf0(%rbp), %rsi
callq 0x3290
movl %eax, -0xf4(%rbp)
cmpl $-0x1, -0xf4(%rbp)
jne 0x38a1
movq -0x10(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3260
movl $0x1, %edi
callq 0x3080
movq -0xc0(%rbp), %rsi
movl -0x60(%rbp), %r8d
xorl %eax, %eax
movl %eax, %r9d
movl $0x1, %edx
movl $0x2, %ecx
movq %r9, %rdi
callq 0x30d0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x38df
movq -0x10(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3260
movq -0x28(%rbp), %rax
movq -0x20(%rbp), %rdi
callq *%rax
movq -0x20(%rbp), %rdi
movq -0xc0(%rbp), %rsi
callq 0x3230
movl -0x60(%rbp), %edi
callq 0x3160
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x3823
jmp 0x3911
jmp 0x3913
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopw %cs:(%rax,%rax)