// File: /workspace/github_c_makefile_star2_O0/simh[P]simtools/crossassemblers/macro11/parse.c
// Function: get_mode
int get_mode(
    char *cp,
    char **endp,
    ADDR_MODE *mode)
{
    EX_TREE        *value;

    mode->offset = NULL;
    mode->rel = 0;
    mode->type = 0;

    cp = skipwhite(cp);

    /* @ means "indirect," sets bit 3 */
    if (*cp == '@') {
        cp++;
        mode->type |= 010;
    }

    /* Immediate modes #imm and @#imm */
    if (*cp == '#') {
        cp++;
        mode->type |= 027;
        mode->offset = parse_expr(cp, 0);
        if (endp)
            *endp = mode->offset->cp;
        return TRUE;
    }

    /* Check for -(Rn) */

    if (*cp == '-') {
        char           *tcp = skipwhite(cp + 1);

        if (*tcp++ == '(') {
            unsigned        reg;

            /* It's -(Rn) */
            value = parse_expr(tcp, 0);
            reg = get_register(value);
            if (reg == NO_REG || (tcp = skipwhite(value->cp), *tcp++ != ')')) {
                free_tree(value);
                return FALSE;
            }
            mode->type |= 040 | reg;
            if (endp)
                *endp = tcp;
            free_tree(value);
            return TRUE;
        }
    }

    /* Check for (Rn) */
    if (*cp == '(') {
        char           *tcp;
        unsigned        reg;

        value = parse_expr(cp + 1, 0);
        reg = get_register(value);

        if (reg == NO_REG || (tcp = skipwhite(value->cp), *tcp++ != ')')) {
            free_tree(value);
            return FALSE;
        }

        tcp = skipwhite(tcp);
        if (*tcp == '+') {
            tcp++;                     /* It's (Rn)+ */
            if (endp)
                *endp = tcp;
            mode->type |= 020 | reg;
            free_tree(value);
            return TRUE;
        }

        if (mode->type == 010) {       /* For @(Rn) there's an implied 0 offset */
            mode->offset = new_ex_lit(0);
            mode->type |= 060 | reg;
            free_tree(value);
            if (endp)
                *endp = tcp;
            return TRUE;
        }

        mode->type |= 010 | reg;       /* Mode 10 is register indirect as
                                          in (Rn) */
        free_tree(value);
        if (endp)
            *endp = tcp;
        return TRUE;
    }

    /* Modes with an offset */

    mode->offset = parse_expr(cp, 0);

    cp = skipwhite(mode->offset->cp);

    if (*cp == '(') {
        unsigned        reg;

        /* indirect register plus offset */
        value = parse_expr(cp + 1, 0);
        reg = get_register(value);
        if (reg == NO_REG || (cp = skipwhite(value->cp), *cp++ != ')')) {
            free_tree(value);
            return FALSE;              /* Syntax error in addressing mode */
        }

        mode->type |= 060 | reg;

        free_tree(value);

        if (endp)
            *endp = cp;
        return TRUE;
    }

    /* Plain old expression. */

    if (endp)
        *endp = cp;

    /* It might be a register, though. */
    if (mode->offset->type == EX_SYM) {
        SYMBOL         *sym = mode->offset->data.symbol;

        if (sym->section->type == SECTION_REGISTER) {
            free_tree(mode->offset);
            mode->offset = NULL;
            mode->type |= sym->value;
            return TRUE;
        }
    }

    /* It's either 067 (PC-relative) or 037 (absolute) mode, depending */
    /* on user option. */

    if (mode->type & 010) {            /* Have already noted indirection? */
        mode->type |= 067;             /* If so, then PC-relative is the only
                                          option */
        mode->rel = 1;                 /* Note PC-relative */
    } else if (enabl_ama) {            /* User asked for absolute adressing? */
        mode->type |= 037;             /* Give it to him. */
    } else {
        mode->type |= 067;             /* PC-relative */
        mode->rel = 1;                 /* Note PC-relative */
    }

    return TRUE;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x20(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x20(%rbp), %rax
movl $0x0, (%rax)
movq -0x10(%rbp), %rdi
callq 0xb9e0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x40, %eax
jne 0xc375
movq -0x10(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x10(%rbp)
movq -0x20(%rbp), %rax
movl (%rax), %ecx
orl $0x8, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x23, %eax
jne 0xc3d4
movq -0x10(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x10(%rbp)
movq -0x20(%rbp), %rax
movl (%rax), %ecx
orl $0x17, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0xc7b0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
cmpq $0x0, -0x18(%rbp)
je 0xc3c8
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movl $0x1, -0x4(%rbp)
jmp 0xc79f
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0xc4a8
movq -0x10(%rbp), %rdi
addq $0x1, %rdi
callq 0xb9e0
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x30(%rbp)
movsbl (%rax), %eax
cmpl $0x28, %eax
jne 0xc4a6
movq -0x30(%rbp), %rdi
xorl %esi, %esi
callq 0xc7b0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7920
movl %eax, -0x34(%rbp)
cmpl $0x1ff, -0x34(%rbp)     # imm = 0x1FF
je 0xc45c
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb9e0
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x30(%rbp)
movsbl (%rax), %eax
cmpl $0x29, %eax
je 0xc471
movq -0x28(%rbp), %rdi
callq 0x9390
movl $0x0, -0x4(%rbp)
jmp 0xc79f
movl -0x34(%rbp), %ecx
orl $0x20, %ecx
movq -0x20(%rbp), %rax
orl (%rax), %ecx
movl %ecx, (%rax)
cmpq $0x0, -0x18(%rbp)
je 0xc491
movq -0x30(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rdi
callq 0x9390
movl $0x1, -0x4(%rbp)
jmp 0xc79f
jmp 0xc4a8
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x28, %eax
jne 0xc5fc
movq -0x10(%rbp), %rdi
addq $0x1, %rdi
xorl %esi, %esi
callq 0xc7b0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7920
movl %eax, -0x44(%rbp)
cmpl $0x1ff, -0x44(%rbp)     # imm = 0x1FF
je 0xc508
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb9e0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x40(%rbp)
movsbl (%rax), %eax
cmpl $0x29, %eax
je 0xc51d
movq -0x28(%rbp), %rdi
callq 0x9390
movl $0x0, -0x4(%rbp)
jmp 0xc79f
movq -0x40(%rbp), %rdi
callq 0xb9e0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2b, %eax
jne 0xc577
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0xc554
movq -0x40(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movl -0x44(%rbp), %ecx
orl $0x10, %ecx
movq -0x20(%rbp), %rax
orl (%rax), %ecx
movl %ecx, (%rax)
movq -0x28(%rbp), %rdi
callq 0x9390
movl $0x1, -0x4(%rbp)
jmp 0xc79f
movq -0x20(%rbp), %rax
cmpl $0x8, (%rax)
jne 0xc5c7
xorl %edi, %edi
callq 0xa3c0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movl -0x44(%rbp), %ecx
orl $0x30, %ecx
movq -0x20(%rbp), %rax
orl (%rax), %ecx
movl %ecx, (%rax)
movq -0x28(%rbp), %rdi
callq 0x9390
cmpq $0x0, -0x18(%rbp)
je 0xc5bb
movq -0x40(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movl $0x1, -0x4(%rbp)
jmp 0xc79f
movl -0x44(%rbp), %ecx
orl $0x8, %ecx
movq -0x20(%rbp), %rax
orl (%rax), %ecx
movl %ecx, (%rax)
movq -0x28(%rbp), %rdi
callq 0x9390
cmpq $0x0, -0x18(%rbp)
je 0xc5f0
movq -0x40(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movl $0x1, -0x4(%rbp)
jmp 0xc79f
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0xc7b0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rdi
callq 0xb9e0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x28, %eax
jne 0xc6d1
movq -0x10(%rbp), %rdi
addq $0x1, %rdi
xorl %esi, %esi
callq 0xc7b0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7920
movl %eax, -0x48(%rbp)
cmpl $0x1ff, -0x48(%rbp)     # imm = 0x1FF
je 0xc687
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb9e0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movsbl (%rax), %eax
cmpl $0x29, %eax
je 0xc69c
movq -0x28(%rbp), %rdi
callq 0x9390
movl $0x0, -0x4(%rbp)
jmp 0xc79f
movl -0x48(%rbp), %ecx
orl $0x30, %ecx
movq -0x20(%rbp), %rax
orl (%rax), %ecx
movl %ecx, (%rax)
movq -0x28(%rbp), %rdi
callq 0x9390
cmpq $0x0, -0x18(%rbp)
je 0xc6c5
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movl $0x1, -0x4(%rbp)
jmp 0xc79f
cmpq $0x0, -0x18(%rbp)
je 0xc6e3
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x2, (%rax)
jne 0xc741
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rax
cmpl $0x5, 0x8(%rax)
jne 0xc73f
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x9390
movq -0x20(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x50(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x20(%rbp), %rax
orl (%rax), %ecx
movl %ecx, (%rax)
movl $0x1, -0x4(%rbp)
jmp 0xc79f
jmp 0xc741
movq -0x20(%rbp), %rax
movl (%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0xc767
movq -0x20(%rbp), %rax
movl (%rax), %ecx
orl $0x37, %ecx
movl %ecx, (%rax)
movq -0x20(%rbp), %rax
movl $0x1, 0x4(%rax)
jmp 0xc798
leaq 0xd42e(%rip), %rax      # 0x19b9c
cmpl $0x0, (%rax)
je 0xc780
movq -0x20(%rbp), %rax
movl (%rax), %ecx
orl $0x1f, %ecx
movl %ecx, (%rax)
jmp 0xc796
movq -0x20(%rbp), %rax
movl (%rax), %ecx
orl $0x37, %ecx
movl %ecx, (%rax)
movq -0x20(%rbp), %rax
movl $0x1, 0x4(%rax)
jmp 0xc798
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax,%rax)