// File: /workspace/github_c_makefile_star2_O0/janet-lang[P]janet/src/core/corelib.c
// Function: templatize_varop
static void templatize_varop(
    JanetTable *env,
    int32_t flags,
    const char *name,
    int32_t nullary,
    int32_t unary,
    uint32_t op,
    const char *doc) {

    /* Variadic operator assembly. Must be templatized for each different opcode. */
    /* Reg 0: Argument tuple (args) */
    /* Reg 1: Argument count (argn) */
    /* Reg 2: Jump flag (jump?) */
    /* Reg 3: Accumulator (accum) */
    /* Reg 4: Next operand (operand) */
    /* Reg 5: Loop iterator (i) */
    uint32_t varop_asm[] = {
        SS(JOP_LENGTH, 1, 0), /* Put number of arguments in register 1 -> argn = count(args) */

        /* Check nullary */
        SSS(JOP_EQUALS_IMMEDIATE, 2, 1, 0), /* Check if numargs equal to 0 */
        SI(JOP_JUMP_IF_NOT, 2, 3), /* If not 0, jump to next check */
        /* Nullary */
        SI(JOP_LOAD_INTEGER, 3, nullary),  /* accum = nullary value */
        S(JOP_RETURN, 3), /* return accum */

        /* Check unary */
        SSI(JOP_EQUALS_IMMEDIATE, 2, 1, 1), /* Check if numargs equal to 1 */
        SI(JOP_JUMP_IF_NOT, 2, 5), /* If not 1, jump to next check */
        /* Unary */
        SI(JOP_LOAD_INTEGER, 3, unary), /* accum = unary value */
        SSI(JOP_GET_INDEX, 4, 0, 0), /* operand = args[0] */
        SSS(op, 3, 3, 4), /* accum = accum op operand */
        S(JOP_RETURN, 3), /* return accum */

        /* Mutli (2 or more) arity */
        /* Prime loop */
        SSI(JOP_GET_INDEX, 3, 0, 0), /* accum = args[0] */
        SI(JOP_LOAD_INTEGER, 5, 1), /* i = 1 */
        /* Main loop */
        SSS(JOP_IN, 4, 0, 5), /* operand = args[i] */
        SSS(op, 3, 3, 4), /* accum = accum op operand */
        SSI(JOP_ADD_IMMEDIATE, 5, 5, 1), /* i++ */
        SSI(JOP_EQUALS, 2, 5, 1), /* jump? = (i == argn) */
        SI(JOP_JUMP_IF_NOT, 2, -4), /* if not jump? go back 4 */

        /* Done, do last and return accumulator */
        S(JOP_RETURN, 3) /* return accum */
    };

    janet_quick_asm(
        env,
        flags | JANET_FUNCDEF_FLAG_VARARG,
        name,
        0,
        0,
        INT32_MAX,
        6,
        varop_asm,
        sizeof(varop_asm),
        doc);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movl %r9d, -0x24(%rbp)
movl $0x13f, -0x70(%rbp)     # imm = 0x13F
movl $0x10226, -0x6c(%rbp)   # imm = 0x10226
movl $0x3021e, -0x68(%rbp)   # imm = 0x3021E
movl -0x1c(%rbp), %eax
shll $0x10, %eax
orl $0x32b, %eax            # imm = 0x32B
movl %eax, -0x64(%rbp)
movl $0x303, -0x60(%rbp)     # imm = 0x303
movl $0x1010226, -0x5c(%rbp) # imm = 0x1010226
movl $0x5021e, -0x58(%rbp)   # imm = 0x5021E
movl -0x20(%rbp), %eax
shll $0x10, %eax
orl $0x32b, %eax            # imm = 0x32B
movl %eax, -0x54(%rbp)
movl $0x43d, -0x50(%rbp)     # imm = 0x43D
movl -0x24(%rbp), %eax
orl $0x300, %eax            # imm = 0x300
orl $0x30000, %eax          # imm = 0x30000
orl $0x4000000, %eax        # imm = 0x4000000
movl %eax, -0x4c(%rbp)
movl $0x303, -0x48(%rbp)     # imm = 0x303
movl $0x33d, -0x44(%rbp)     # imm = 0x33D
movl $0x1052b, -0x40(%rbp)   # imm = 0x1052B
movl $0x500043a, -0x3c(%rbp) # imm = 0x500043A
movl -0x24(%rbp), %eax
orl $0x300, %eax            # imm = 0x300
orl $0x30000, %eax          # imm = 0x30000
orl $0x4000000, %eax        # imm = 0x4000000
movl %eax, -0x38(%rbp)
movl $0x1050505, -0x34(%rbp) # imm = 0x1050505
movl $0x1050225, -0x30(%rbp) # imm = 0x1050225
movl $0xfffc021e, -0x2c(%rbp) # imm = 0xFFFC021E
movl $0x303, -0x28(%rbp)     # imm = 0x303
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
orl $0x10000, %esi          # imm = 0x10000
movq -0x18(%rbp), %rdx
leaq -0x70(%rbp), %r10
movq 0x10(%rbp), %rax
xorl %r8d, %r8d
movl $0x7fffffff, %r9d       # imm = 0x7FFFFFFF
movl %r8d, %ecx
movl $0x6, (%rsp)
movq %r10, 0x8(%rsp)
movq $0x4c, 0x10(%rsp)
movq %rax, 0x18(%rsp)
callq 0x27470
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)