// File: /workspace/github_c_makefile_star2_O0/simh[P]simtools/crossassemblers/macro11/macros.c
// Function: defmacro
MACRO          *defmacro(
    char *cp,
    STACK *stack,
    int called)
{
    MACRO          *mac;
    ARG            *arg,
                  **argtail;
    char           *label;

    cp = skipwhite(cp);
    label = get_symbol(cp, &cp, NULL);
    if (label == NULL) {
        report(stack->top, "Invalid macro definition\n");
        return NULL;
    }

    /* Allow redefinition of a macro; new definition replaces the old. */
    mac = (MACRO *) lookup_sym(label, &macro_st);
    if (mac) {
        /* Remove from the symbol table... */
        remove_sym(&mac->sym, &macro_st);
        free_macro(mac);
    }

    mac = new_macro(label);

    add_table(&mac->sym, &macro_st);

    argtail = &mac->args;
    cp = skipdelim(cp);

    while (!EOL(*cp)) {
        arg = new_arg();
        arg->locsym = *cp == '?';
        if (arg->locsym) /* special argument flag? */
            cp++;
        arg->label = get_symbol(cp, &cp, NULL);
        if (arg->label == NULL) {
            /* It turns out that I have code which is badly formatted
               but which MACRO.SAV assembles.  Sigh.  */
            /* So, just quit defining arguments. */
            break;
#if 0
            report(str, "Illegal macro argument\n");
            remove_sym(&mac->sym, &macro_st);
            free_macro(mac);
            return NULL;
#endif
        }

        cp = skipwhite(cp);
        if (*cp == '=') {
            /* Default substitution given */
            arg->value = getstring(cp + 1, &cp);
            if (arg->value == NULL) {
                report(stack->top, "Illegal macro argument\n");
                remove_sym(&mac->sym, &macro_st);
                free_macro(mac);
                return NULL;
            }
        }

        /* Append to list of arguments */
        arg->next = NULL;
        *argtail = arg;
        argtail = &arg->next;

        cp = skipdelim(cp);
    }

    /* Read the stream in until the end marker is hit */  {
        BUFFER         *gb;
        int             levelmod = 0;

        gb = new_buffer();

        if (!called && !list_md) {
            list_level--;
            levelmod = 1;
        }

        read_body(stack, gb, mac->sym.label, called);

        list_level += levelmod;

        if (mac->text != NULL)         /* Discard old macro body */
            buffer_free(mac->text);

        mac->text = gb;
    }

    return mac;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x10(%rbp), %rdi
callq 0xb9e0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x10(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0xbf60
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0xae1e
movq -0x18(%rbp), %rax
movq (%rax), %rdi
leaq 0xa7c3(%rip), %rsi      # 0x155cd
movb $0x0, %al
callq 0xa890
movq $0x0, -0x8(%rbp)
jmp 0xb06c
movq -0x40(%rbp), %rdi
leaq 0x168af(%rip), %rsi     # 0x216d8
callq 0xe040
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0xae52
movq -0x28(%rbp), %rdi
leaq 0x16894(%rip), %rsi     # 0x216d8
callq 0xdfb0
movq -0x28(%rbp), %rdi
callq 0xb080
movq -0x40(%rbp), %rdi
callq 0xb0c0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
leaq 0x1686e(%rip), %rsi     # 0x216d8
callq 0xe190
movq -0x28(%rbp), %rax
addq $0x28, %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
callq 0xba30
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rcx
movb $0x1, %al
cmpb $0x0, (%rcx)
movb %al, -0x4d(%rbp)
je 0xaeb7
movq -0x10(%rbp), %rax
movsbl (%rax), %ecx
movb $0x1, %al
cmpl $0xa, %ecx
movb %al, -0x4d(%rbp)
je 0xaeb7
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3b, %eax
sete %al
movb %al, -0x4d(%rbp)
movb -0x4d(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xaec5
jmp 0xafd6
callq 0xb150
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3f, %eax
sete %al
andb $0x1, %al
movzbl %al, %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x30(%rbp), %rax
cmpl $0x0, 0x8(%rax)
je 0xaefd
movq -0x10(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x10(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0xbf60
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0xaf29
jmp 0xafd6
movq -0x10(%rbp), %rdi
callq 0xb9e0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3d, %eax
jne 0xafa6
movq -0x10(%rbp), %rdi
addq $0x1, %rdi
leaq -0x10(%rbp), %rsi
callq 0xbad0
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x30(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0xafa4
movq -0x18(%rbp), %rax
movq (%rax), %rdi
leaq 0xa670(%rip), %rsi      # 0x155e7
movb $0x0, %al
callq 0xa890
movq -0x28(%rbp), %rdi
leaq 0x1674f(%rip), %rsi     # 0x216d8
callq 0xdfb0
movq -0x28(%rbp), %rdi
callq 0xb080
movq $0x0, -0x8(%rbp)
jmp 0xb06c
jmp 0xafa6
movq -0x30(%rbp), %rax
movq $0x0, (%rax)
movq -0x30(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
callq 0xba30
movq %rax, -0x10(%rbp)
jmp 0xae88
movl $0x0, -0x4c(%rbp)
callq 0x12af0
movq %rax, -0x48(%rbp)
cmpl $0x0, -0x1c(%rbp)
jne 0xb014
leaq 0xea71(%rip), %rax      # 0x19a64
cmpl $0x0, (%rax)
jne 0xb014
leaq 0xea71(%rip), %rax      # 0x19a70
movl (%rax), %ecx
addl $-0x1, %ecx
leaq 0xea65(%rip), %rax      # 0x19a70
movl %ecx, (%rax)
movl $0x1, -0x4c(%rbp)
movq -0x18(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x28(%rbp), %rax
movq (%rax), %rdx
movl -0x1c(%rbp), %ecx
callq 0xab10
movl -0x4c(%rbp), %ecx
leaq 0xea3b(%rip), %rax      # 0x19a70
addl (%rax), %ecx
leaq 0xea32(%rip), %rax      # 0x19a70
movl %ecx, (%rax)
movq -0x28(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0xb058
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x12c20
movq -0x48(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x28(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)