// File: davmac314[P]dinit/src/../dasynq/include/dasynq/timerbase.h
// Function: dasynq::divide_timespec(timespec const&, timespec const&, timespec&)
static inline int divide_timespec(const struct timespec &num, const struct timespec &den, struct timespec &rem) noexcept
{
    if (num.tv_sec < den.tv_sec) {
        rem = num;
        return 0;
    }

    if (num.tv_sec == den.tv_sec) {
        if (num.tv_nsec < den.tv_nsec) {
            rem = num;
            return 0;
        }
        if (num.tv_sec == 0) {
            rem.tv_sec = 0;
            rem.tv_nsec = num.tv_nsec % den.tv_nsec;
            return num.tv_nsec / den.tv_nsec;
        }
        // num.tv_sec == den.tv_sec and both are >= 1.
        // The result can only be 1:
        rem.tv_sec = 0;
        rem.tv_nsec = num.tv_nsec - den.tv_nsec;
        return 1;
    }

    // At this point, num.tv_sec >= 1.

    time_val n = { num.tv_sec, num.tv_nsec };
    time_val d = { den.tv_sec, den.tv_nsec };
    time_val r = n;

    // starting with numerator, subtract 1*denominator
    r -= d;

    // Check now for common case: one timer expiry with no overrun
    if (r < d) {
        rem = r;
        return 1;
    }

    int nval = 1;
    int rval = 1; // we have subtracted 1*D already

    // shift denominator until it is greater than / roughly equal to numerator:
    while (d.seconds() < r.seconds()) {
        d <<= 1;
        nval *= 2;
    }

    while (nval > 0) {
        if (d <= r) {
            r -= d;
            rval += nval;
        }

        d >>= 1;
        nval /= 2;
    }

    rem = r;
    return rval;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
cmpq (%rcx), %rax
jge 0x4c59
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rax
movq (%rcx), %rdx
movq %rdx, (%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x8(%rax)
movl $0x0, -0x4(%rbp)
jmp 0x4e6d
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
cmpq (%rcx), %rax
jne 0x4d19
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x18(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jge 0x4ca1
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rax
movq (%rcx), %rdx
movq %rdx, (%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x8(%rax)
movl $0x0, -0x4(%rbp)
jmp 0x4e6d
movq -0x10(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x4cea
movq -0x20(%rbp), %rax
movq $0x0, (%rax)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x18(%rbp), %rcx
cqto
idivq 0x8(%rcx)
movq -0x20(%rbp), %rax
movq %rdx, 0x8(%rax)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x18(%rbp), %rcx
cqto
idivq 0x8(%rcx)
movl %eax, -0x4(%rbp)
jmp 0x4e6d
movq -0x20(%rbp), %rax
movq $0x0, (%rax)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x18(%rbp), %rax
subq 0x8(%rax), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movl $0x1, -0x4(%rbp)
jmp 0x4e6d
movq -0x10(%rbp), %rax
movq (%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdx
leaq -0x30(%rbp), %rdi
callq 0x53f0
movq -0x18(%rbp), %rax
movq (%rax), %rsi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdx
leaq -0x40(%rbp), %rdi
callq 0x53f0
movq -0x30(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x48(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0xfd00
leaq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0xfe10
testb $0x1, %al
jne 0x4d79
jmp 0x4da9
leaq -0x50(%rbp), %rdi
callq 0xd780
movq %rax, -0x60(%rbp)
movq %rdx, -0x58(%rbp)
movq -0x20(%rbp), %rax
movq -0x60(%rbp), %rcx
movq %rcx, (%rax)
movq -0x58(%rbp), %rcx
movq %rcx, 0x8(%rax)
movl $0x1, -0x4(%rbp)
jmp 0x4e6d
movl $0x1, -0x64(%rbp)
movl $0x1, -0x68(%rbp)
leaq -0x40(%rbp), %rdi
callq 0xe0f0
movq (%rax), %rax
movq %rax, -0x80(%rbp)
leaq -0x50(%rbp), %rdi
callq 0xe0f0
movq %rax, %rcx
movq -0x80(%rbp), %rax
cmpq (%rcx), %rax
jge 0x4df4
leaq -0x40(%rbp), %rdi
movl $0x1, %esi
callq 0xfeb0
movl -0x64(%rbp), %eax
shll %eax
movl %eax, -0x64(%rbp)
jmp 0x4db7
jmp 0x4df6
cmpl $0x0, -0x64(%rbp)
jle 0x4e43
leaq -0x40(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0xfa60
testb $0x1, %al
jne 0x4e0f
jmp 0x4e25
leaq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0xfd00
movl -0x64(%rbp), %eax
addl -0x68(%rbp), %eax
movl %eax, -0x68(%rbp)
leaq -0x40(%rbp), %rdi
movl $0x1, %esi
callq 0xff50
movl -0x64(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x64(%rbp)
jmp 0x4df6
leaq -0x50(%rbp), %rdi
callq 0xd780
movq %rax, -0x78(%rbp)
movq %rdx, -0x70(%rbp)
movq -0x20(%rbp), %rax
movq -0x78(%rbp), %rcx
movq %rcx, (%rax)
movq -0x70(%rbp), %rcx
movq %rcx, 0x8(%rax)
movl -0x68(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax)