
print_character:
        lui   t1, %hi(out_ch)
        addi  t1, t1, %lo(out_ch)
        sw    t0, (t1)
        PUTCHAR
        ret

write_packed_char_n:
        add   sp, sp, -8
        sd    ra, (sp)

        mv    s2, s4
        srli  s2, s2, 2
        mv    s5, s2
        slli  s2, s2, 2
        sub   s4, s4, s2
        mv    s6, s4 # s6 = count - ((count >> 2) << 2
        mv    s4, s5 # s4 = count >> 2

        beq   s6, zero, .WP_L1
        addi  s3, s3, -4
        lw    s5, (s3) # s5 = top of stack
        andi  t0, s5, 255
        call  print_character
        li    t0, 1
        ble   s6, t0, .WP_L1
        srli  s5, s5, 8
        andi  t0, s5, 255
        call  print_character
        li    t0, 2
        ble   s6, t0, .WP_L1
        srli  s5, s5, 8
        andi  t0, s5, 255
        call  print_character

.WP_L1:
        beq   s4, zero, .WP_L2
        addi  s4, s4, -1
        addi  s3, s3, -4
        lw    s5, (s3)
        andi  t0, s5, 255
        call  print_character
        srli  s5, s5, 8
        andi  t0, s5, 255
        call  print_character
        srli  s5, s5, 8
        andi  t0, s5, 255
        call  print_character
        srli  s5, s5, 8
        andi  t0, s5, 255
        call  print_character
        j     .WP_L1

.WP_L2:
        ld    ra, (sp)
        add   sp, sp, 8
        jr    ra

print_integer:
        add   sp, sp, -8
        sd    ra, (sp)
# ( n == $80000000 ) 
        lui   s1, %hi(0x80000000)
        addi  s1, s1, %lo(0x80000000)
        bne   s0, s1, .LL_P_I_0

        # print negative maximum 32 bit integer

        li    t0, 45
        call  print_character
        li    t0, 50
        call  print_character
        li    t0, 49
        call  print_character
        li    t0, 52
        call  print_character
        li    t0, 55
        call  print_character
        li    t0, 52
        call  print_character
        li    t0, 56
        call  print_character
        li    t0, 51
        call  print_character
        li    t0, 54
        call  print_character
        li    t0, 52
        call  print_character
        li    t0, 56
        call  print_character

        j     .LL_P_I_8

.LL_P_I_0:
# ( n < 0 ) 
        bge   s0, zero, .LL_P_I_2
# putchar ( 45 ) 
        mv    s5, s0 # save
        li    t0, 45
        call  print_character
        mv    s0, s5 # restore

# n = #NEG n 
        sub   s0, zero, s0

.LL_P_I_2:
# string_size = 0 
        li    s1, 0
# n_temp = n 
        mv    s4, s0

        li    s2, 10
.LL_P_I_3:
# string_size = string_size + 1 
        addi  s1, s1, 1
# n_temp = n_temp / 10 
        div   s4, s4, s2

# ( ! ( n_temp == 0 ) ) 
        bne   s4, zero, .LL_P_I_3

.LL_P_I_4:
# string_idx = string_size 
        mv    s2, s1

        li    s6, 10
        lui   s5, %hi(buf)
        addi  s5, s5, %lo(buf)

.LL_P_I_5:
# string_idx > 0 
        blt   s2, zero, .LL_P_I_6
        beq   s2, zero, .LL_P_I_6

# string [ string_idx - 1 ] = n % 10 + 48 
        rem   s9, s0, s6
        addi  s9, s9, 48
        addi  s2, s2, -1
        slli  s7, s2, 2
        add   s7, s5, s7
        sw    s9, (s7)

# n = n / 10 
        div   s0, s0, s6

# string_idx = string_idx - 1 
#       addi  s2, s2, -1
        j     .LL_P_I_5

.LL_P_I_6:
# string_idx = 0 
        li    s2, 0

.LL_P_I_7:
# string_idx < string_size 
        bge   s2, s1, .LL_P_I_8

# putchar ( string [ string_idx ] ) 
        slli  s7, s2, 2
        add   s7, s7, s5
        mv    s11, s1 # save
        lw    t0, (s7)
        call  print_character
        mv    s1, s11 # restore

# string_idx = string_idx + 1 
        add   s2, s2, 1

        j     .LL_P_I_7

.LL_P_I_8:
# (return)
        ld    ra, (sp)
        add   sp, sp, 8
        jr    ra

_read_char:
# (= eof_reached FALSE)
        lui    s1, %hi(eof_reached)
        addi   s1, s1, %lo(eof_reached)
        lw     s0, (s1)
        bne    s0, zero, .L0
# (my_read)
        GETCHAR
# (= read_length 0)
        bne    a0, zero, .L1
# (set! in_ch -1)
        addi   s1, zero, -1
        lui    s0, %hi(in_ch)
        addi   s0, s0, %lo(in_ch)
        sw     s1, (s0)
# (set! eof_reached TRUE)
        li     s1, 1
        lui    s0, %hi(eof_reached)
        addi   s0, s0, %lo(eof_reached)
        sw     s1, (s0)
.L1:
.L0:
        ret

