print_nl:
  push r2
  iset r0, 2
  iset r1, newline
  iset r2, 1
  syscall
  pop r2
  ret

print_str:
  push r2
  mov r2, r1
  mov r1, r0
  iset r0, 2
  syscall
  pop r2
  ret

print_uint32_dec:
  push r0
  push r1
  push r2
  push r3
  push r5
  push r6
  push r8
  push r9

  spget r2
  iset r3, 3
  spadd r3
  xor r3, r3, r3
  istore8 r3, r2, -1
  iset r3, 10
  xor r8, r8, r8
  xor r9, r9, r9
print_uint32_dec_1:
  udiv r5, r0, r3
  mul r6, r5, r3
  sub r0, r0, r6
  inc r6, r0, 48
  istore8 r6, r2, -1
  dec r2, r2, 1
  inc r9, r9, 1
  mov r0, r5
  cmp r0, r8
  jnz print_uint32_dec_1
  iset r0, 2
  mov r1, r2
  mov r2, r9
  syscall
  iset r2, 3
  spsub r2

  pop r9
  pop r8
  pop r6
  pop r5
  pop r3
  pop r2
  pop r1
  pop r0
  ret

print_uint64_dec:
  push r0
  push r1
  push r2
  push r3
  push r4
  push r5
  push r6
  push r7
  push r8
  push r9
  push r10
  push r11
  push r12
  push r13
  push r14
  push r15

  spget r2
  iset r3, 6
  spadd r3
  xor r3, r3, r3
  iset r5, div10_const
  iload32 r4, r5, 0
  iload32 r5, r5, 4
  xor r15, r15, r15
  iset r14, 10
print_uint64_dec_1:
  umul r7, r6, r0, r4
  umul r9, r8, r0, r5
  umul r11, r10, r1, r4
  umul r13, r12, r1, r5
  add r8, r8, r7
  adc r9, r9, r15
  adc r11, r11, r15
  adc r13, r13, r15
  add r8, r8, r10
  adc r9, r9, r11
  adc r13, r13, r15
  add r9, r9, r12
  adc r13, r13, r15
  ishl r7, r13, 29
  ishr r13, r13, 3
  ishr r9, r9, 3
  or r9, r9, r7
  mul r6, r9, r14
  sub r6, r0, r6
  inc r6, r6, 48
  dec r2, r2, 1
  istore8 r6, r2, 0
  inc r3, r3, 1
  mov r0, r9
  mov r1, r13
  cmp r1, r15
  jnz print_uint64_dec_1
  cmp r0, r15
  jnz print_uint64_dec_1

  iset r0, 2
  mov r1, r2
  mov r2, r3
  syscall

  iset r2, 6
  spsub r2

  pop r15
  pop r14
  pop r13
  pop r12
  pop r11
  pop r10
  pop r9
  pop r8
  pop r7
  pop r6
  pop r5
  pop r4
  pop r3
  pop r2
  pop r1
  pop r0
  ret

.text
newline:
    db 10
div10_const:
    dw 0xCCCCCCCD, 0xCCCCCCCC
