summaryrefslogtreecommitdiff
path: root/boot/common-boot.s
diff options
context:
space:
mode:
Diffstat (limited to 'boot/common-boot.s')
-rw-r--r--boot/common-boot.s67
1 files changed, 67 insertions, 0 deletions
diff --git a/boot/common-boot.s b/boot/common-boot.s
index 0cf31f1..26dad8d 100644
--- a/boot/common-boot.s
+++ b/boot/common-boot.s
@@ -2,6 +2,7 @@
.global _write_out, _read_file, _write_error, _put_char, _printi
.global _get, _memcmp, _memchr, _memmem, _memcpy
.global _divide_by_zero_error, _exit
+.global _strings_index
.section .rodata
@@ -424,3 +425,69 @@ _memcpy:
.Lmemcpy_end:
mv a0, t0
ret
+
+# Searches for a string in a string array.
+#
+# Parameters:
+# a0 - Number of elements in the string array.
+# a1 - String array.
+# a2 - Needle length.
+# a3 - Needle.
+#
+# Sets a0 to the 1-based index of the needle in the haystack or to 0 if the
+# element could not be found.
+.type _strings_index, @function
+_strings_index:
+ # Prologue.
+ addi sp, sp, -32
+ sw ra, 28(sp)
+ sw s0, 24(sp)
+ addi s0, sp, 32
+
+ sw s1, 20(sp)
+ mv s1, a0
+ sw s2, 16(sp)
+ mv s2, a1
+ sw s3, 12(sp)
+ mv s3, a2
+ sw s4, 8(sp)
+ mv s4, a3
+ sw s5, 4(sp)
+ li s5, 0 # Index counter.
+
+.Lstrings_index_loop:
+ addi s5, s5, 1
+ beqz s1, .Lstrings_index_missing
+
+ lw a2, (s2) # Read the length of the current element in the haystack.
+ bne a2, s3, .Lstrings_index_next # Lengths don't match, skip the iteration.
+
+ addi a0, s2, 4
+ mv a1, s4
+ call _memcmp
+
+ beqz a0, .Lstrings_index_end
+
+.Lstrings_index_next:
+ addi s2, s2, 4
+ add s2, s2, a2
+ addi s1, s1, -1
+ j .Lstrings_index_loop
+
+.Lstrings_index_missing:
+ li s5, 0
+
+.Lstrings_index_end:
+ mv a0, s5
+
+ lw s1, 20(sp)
+ lw s2, 16(sp)
+ lw s3, 12(sp)
+ lw s4, 8(sp)
+ lw s5, 4(sp)
+
+ # Epilogue.
+ lw ra, 28(sp)
+ lw s0, 24(sp)
+ add sp, sp, 32
+ ret