.global is_alpha, is_digit, is_alnum, is_upper, is_lower, write_out, read_file, exit, memcmp, write_error .section .rodata .equ SYS_READ, 63 .equ SYS_WRITE, 64 .equ SYS_EXIT, 93 .equ STDIN, 0 .equ STDOUT, 1 .equ STDERR, 2 new_line: .ascii "\n" .section .text # Write the current token to stderr. # a0 - String pointer. # a1 - String length. .type write_error, @function write_error: mv t0, a0 mv t1, a1 li a0, STDERR mv a1, t0 mv a2, t1 li a7, SYS_WRITE ecall li a0, STDERR la a1, new_line li a2, 1 li a7, SYS_WRITE ecall ret # a0 - First pointer. # a1 - Second pointer. # a2 - The length to compare. # # Returns 0 in a0 if memory regions are equal. .type memcmp, @function memcmp: mv t0, a0 li a0, 0 .Lmemcmp_loop: beqz a2, .Lmemcmp_end lbu t1, (t0) lbu t2, (a1) sub a0, t1, t2 bnez a0, .Lmemcmp_end addi t0, t0, 1 addi a1, a1, 1 addi a2, a2, -1 j .Lmemcmp_loop .Lmemcmp_end: ret # Detects if a0 is an uppercase character. Sets a0 to 1 if so, otherwise to 0. is_upper: li t0, 'A' - 1 sltu t1, t0, a0 # t1 = a0 >= 'A' sltiu t2, a0, 'Z' + 1 # t2 = a0 <= 'Z' and a0, t1, t2 # t1 = a0 >= 'A' & a0 <= 'Z' ret # Detects if a0 is an lowercase character. Sets a0 to 1 if so, otherwise to 0. .type is_lower, @function is_lower: li t0, 'a' - 1 sltu t2, t0, a0 # t2 = a0 >= 'a' sltiu t3, a0, 'z' + 1 # t3 = a0 <= 'z' and a0, t2, t3 # t2 = a0 >= 'a' & a0 <= 'z' ret # Detects if the passed character is a 7-bit alpha character or an underscore. # The character is passed in a0. # Sets a0 to 1 if the character is an alpha character or underscore, sets it to 0 otherwise. .type is_alpha, @function is_alpha: # Prologue. addi sp, sp, -16 sw ra, 12(sp) sw s0, 8(sp) addi s0, sp, 16 sw a0, 4(sp) call is_upper sw a0, 0(sp) lw a0, 4(sp) call is_lower lw t0, 4(sp) xori t1, t0, '_' seqz t1, t1 lw t0, 0(sp) or a0, a0, t0 or a0, a0, t1 # Epilogue. lw ra, 12(sp) lw s0, 8(sp) addi sp, sp, 16 ret .type is_digit, @function is_digit: li t0, '0' - 1 sltu t1, t0, a0 # t1 = a0 >= '0' sltiu t2, a0, '9' + 1 # t2 = a0 <= '9' and a0, t1, t2 ret .type is_alnum, @function is_alnum: # Prologue. addi sp, sp, -16 sw ra, 12(sp) sw s0, 8(sp) addi s0, sp, 16 sw a0, 4(sp) call is_alpha sw a0, 0(sp) lw a0, 4(sp) call is_digit lw a1, 0(sp) or a0, a0, a1 # Epilogue. lw ra, 12(sp) lw s0, 8(sp) addi sp, sp, 16 ret .type write, @function write_out: # Prologue. addi sp, sp, -8 sw ra, 4(sp) sw s0, 0(sp) addi s0, sp, 8 mv a2, a1 mv a1, a0 li a0, STDOUT li a7, SYS_WRITE ecall # Epilogue. lw ra, 4(sp) lw s0, 0(sp) addi sp, sp, 8 ret # Reads standard input into a buffer. # a0 - Buffer pointer. # a1 - Buffer size. # # Returns the result in a0. .type read_file, @function read_file: # Prologue. addi sp, sp, -8 sw ra, 4(sp) sw s0, 0(sp) addi s0, sp, 8 mv a2, a1 mv a1, a0 li a0, STDIN li a7, SYS_READ ecall # Epilogue. lw ra, 4(sp) lw s0, 0(sp) addi sp, sp, 8 ret # Terminates the program. a0 contains the return code. exit: li a7, SYS_EXIT ecall