idiv:
        str    x30, [sp, -16]!
        udiv   x2, x0, x1
  ldr    x30, [sp], 16
        ret
.ltorg

_print_character:
        str    x30, [sp, -16]!
        PUTCHAR
  ldr    x30, [sp], 16
        ret
.ltorg

_read_char:
        str    x30, [sp, -16]!
        GETCHAR
  ldr    x30, [sp], 16
        ret
.ltorg

signed_quotient:
        // input x0 - numerator
        // input x1 - denominator
        // output x0 - quotient
        str    x30, [sp, -16]!
// (< N 0)
        cmp    w0, 0
        bge    .L2
// (< D 0)
        cmp    w1, 0
        bge    .L4
// (set! N (negate N 0))
        mov    w2, 0
        sub    w0, w2, w0
// (set! D (negate D 0))
        sub    w1, w2, w1
// (set! Q (quotient N D))
        bl     idiv
        mov    w0, w2
        b      .L5
.L4:
// (set! N (negate N 0))
        mov    w2, 0
        sub    w0, w2, w0
// (set! Q (quotient N D))
        bl     idiv
        mov    w0, w2
// (set! Q (negate Q 0))
        mov    w2, 0
        sub    w0, w2, w0
.L5:
        b      .L3
.L2:
// (< D 0)
        cmp    w1, 0
        bge    .L6
// (set! D (negate D 0))
        mov    w2, 0
        sub    w1, w2, w1
// (set! Q (quotient N D))
        bl     idiv
        mov    w0, w2
// (set! Q (negate Q 0))
        mov    w2, 0
        sub    w0, w2, w0
        b      .L7
.L6:
// (set! Q (quotient N D))
        bl     idiv
        mov    w0, w2
.L7:
.L3:
  ldr    x30, [sp], 16
        ret
.ltorg

signed_remainder:
        // input x0 - numerator
        // input x1 - denominator
        // output x0 - remainder
        str    x30, [sp, -16]!
        udiv   x2, x0, x1
        msub   x0, x2, x1, x0
  ldr    x30, [sp], 16
        ret
.ltorg