summaryrefslogtreecommitdiff
path: root/boot/common-boot.s
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-04-22 22:51:11 +0200
committerEugen Wissner <belka@caraus.de>2025-04-22 22:51:11 +0200
commit5aaf9ded3646f5312e26fc7b3502f141c2e556f5 (patch)
treef8159a432af1b48e44296d178660db73a2f1805f /boot/common-boot.s
parent536443b020d01d0d5372496529086a11b2486621 (diff)
downloadelna-5aaf9ded3646f5312e26fc7b3502f141c2e556f5.tar.gz
Support global variables and constants
Diffstat (limited to 'boot/common-boot.s')
-rw-r--r--boot/common-boot.s106
1 files changed, 94 insertions, 12 deletions
diff --git a/boot/common-boot.s b/boot/common-boot.s
index bfd1dbb..2228a57 100644
--- a/boot/common-boot.s
+++ b/boot/common-boot.s
@@ -1,4 +1,4 @@
-.global is_alpha, is_digit, is_alnum, write_out, read_file, exit
+.global is_alpha, is_digit, is_alnum, is_upper, is_lower, write_out, read_file, exit, memcmp, write_error
.section .rodata
@@ -9,30 +9,112 @@
.equ STDOUT, 1
.equ STDERR, 2
+new_line: .ascii "\n"
+
.section .text
-# 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:
+# 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 t1, t1, t2 # t1 = a0 >= 'A' & 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 t2, t2, t3 # t2 = a0 >= 'a' & a0 <= 'z'
+ and a0, t2, t3 # t2 = a0 >= 'a' & a0 <= 'z'
- xori t3, a0, '_'
- seqz t3, t3
+ 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
- or a0, t1, t2
- or a0, a0, t3
+ 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