summaryrefslogtreecommitdiff
path: root/boot/echo-boot.s
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-04-23 23:16:00 +0200
committerEugen Wissner <belka@caraus.de>2025-04-23 23:16:00 +0200
commitf343296463f8271720cf1e9cb1d45f30c288d872 (patch)
tree24aaa3124762ed64bb754475c03cc5e5736e2bec /boot/echo-boot.s
parent5aaf9ded3646f5312e26fc7b3502f141c2e556f5 (diff)
downloadelna-f343296463f8271720cf1e9cb1d45f30c288d872.tar.gz
Compile procedure headers
Diffstat (limited to 'boot/echo-boot.s')
-rw-r--r--boot/echo-boot.s359
1 files changed, 345 insertions, 14 deletions
diff --git a/boot/echo-boot.s b/boot/echo-boot.s
index a8faecb..22d59d0 100644
--- a/boot/echo-boot.s
+++ b/boot/echo-boot.s
@@ -188,7 +188,7 @@ _compile_program:
sw t0, 8(sp)
addi a0, sp, 8
- li a1, 16
+ li a1, 15
call write_out
addi s1, s1, 8 # program\n.
@@ -496,7 +496,160 @@ _compile_procedure:
addi s1, s1, 1 # Skip opening argument paren.
call _skip_spaces
addi s1, s1, 1 # Skip closing argument paren.
+
+ li t0, 0x6e # n
+ sw t0, 12(sp)
+ li t0, 0x69676562 # begi
+ sw t0, 8(sp)
+
+ # Skip all declarations until we find the "begin" keyword, denoting the
+ # beginning of the procedure body.
+.Lcompile_procedure_begin:
call _skip_spaces
+ call _read_token
+
+ mv a1, a0
+ mv a0, s1
+ addi a2, sp, 8
+ add s1, s1, a1
+ call _token_compare
+
+ bnez a0, .Lcompile_procedure_begin
+
+ # Generate the procedure prologue with a predefined stack size.
+ li t0, 0x69646461 # addi
+ sw t0, 12(sp)
+ addi a0, sp, 12
+ li a1, 4
+ call write_out
+
+ li t0, 0x2c707320 # _sp,
+ sw t0, 12(sp)
+
+ addi a0, sp, 12
+ li a1, 4
+ call write_out
+
+ addi a0, sp, 12
+ li a1, 4
+ call write_out
+
+ li t0, 0x0a36392d # -96\n
+ sw t0, 12(sp)
+ addi a0, sp, 12
+ li a1, 4
+ call write_out
+
+ li t0, 0x0a29 # )\n
+ sw t0, 12(sp)
+ li t0, 0x70732832 # 2(sp
+ sw t0, 8(sp)
+ li t0, 0x39202c61 # a, 9
+ sw t0, 4(sp)
+ li t0, 0x72207773 # sw r
+ sw t0, 0(sp)
+ addi a0, sp, 0
+ li a1, 14
+ call write_out
+
+ li t0, 0x0a29 # )\n
+ sw t0, 12(sp)
+ li t0, 0x70732838 # 2(sp
+ sw t0, 8(sp)
+ li t0, 0x38202c30 # 0, 8
+ sw t0, 4(sp)
+ li t0, 0x73207773 # sw s
+ sw t0, 0(sp)
+ addi a0, sp, 0
+ li a1, 14
+ call write_out
+
+ li t0, 0x0a363920 # _96\n
+ sw t0, 12(sp)
+ li t0, 0x2c707320 # _sp,
+ sw t0, 8(sp)
+ li t0, 0x2c307320 # _s0,
+ sw t0, 4(sp)
+ li t0, 0x69646461 # addi
+ sw t0, 0(sp)
+ addi a0, sp, 0
+ li a1, 16
+ call write_out
+
+ # Generate the body of the procedure.
+.Lcompile_procedure_body:
+ call _skip_indentation
+ call _read_line
+ sw a0, 12(sp)
+ li t0, 0x0a646e65 # end\n
+ sw t0, 8(sp)
+ mv a0, s1
+ addi a1, sp, 8
+ li a2, 4
+ call memcmp
+
+ beqz a0, .Lcompile_procedure_end
+
+ lw a0, 12(sp)
+ call _compile_line
+ j .Lcompile_procedure_body
+
+.Lcompile_procedure_end:
+ add s1, s1, 4 # Skip end\n.
+
+ # Generate the procedure epilogue with a predefined stack size.
+ li t0, 0x0a29 # )\n
+ sw t0, 12(sp)
+ li t0, 0x70732832 # 2(sp
+ sw t0, 8(sp)
+ li t0, 0x39202c61 # a, 9
+ sw t0, 4(sp)
+ li t0, 0x7220776c # lw r
+ sw t0, 0(sp)
+ addi a0, sp, 0
+ li a1, 14
+ call write_out
+
+ li t0, 0x0a29 # )\n
+ sw t0, 12(sp)
+ li t0, 0x70732838 # 2(sp
+ sw t0, 8(sp)
+ li t0, 0x38202c30 # 0, 8
+ sw t0, 4(sp)
+ li t0, 0x7320776c # lw s
+ sw t0, 0(sp)
+ addi a0, sp, 0
+ li a1, 14
+ call write_out
+
+ li t0, 0x69646461 # addi
+ sw t0, 12(sp)
+ addi a0, sp, 12
+ li a1, 4
+ call write_out
+
+ li t0, 0x2c707320 # _sp,
+ sw t0, 12(sp)
+
+ addi a0, sp, 12
+ li a1, 4
+ call write_out
+
+ addi a0, sp, 12
+ li a1, 4
+ call write_out
+
+ li t0, 0x0a3639 # 96\n
+ sw t0, 12(sp)
+ addi a0, sp, 12
+ li a1, 3
+ call write_out
+
+ li t0, 0x0a746572 # ret\n
+ sw t0, 12(sp)
+ addi a0, sp, 12
+ li a1, 4
+ call write_out
# Epilogue.
lw ra, 28(sp)
@@ -504,8 +657,52 @@ _compile_procedure:
addi sp, sp, 32
ret
+# Compares two string, which of one has a length, the other one is null-terminated.
+#
+# a0 - The address of the token string.
+# a1 - The length of the string in a0.
+# a2 - The address of the null-terminated string.
+#
+# If the strings match sets a0 to 0, otherwise sets it to 1.
+.type _token_compare, @function
+_token_compare:
+ addi t0, a0, 0
+ addi t1, a1, 0
+ addi t2, a2, 0
+
+.Ltoken_compare_loop:
+ lbu t3, (t2)
+
+ # Will only be 0 if the current character in the null terminated string is \0 and the remaining length of the
+ # another string is 0.
+ or t4, t3, t1
+ beqz t4, .Ltoken_compare_equal
+
+ beqz t1, .Ltoken_compare_not_equal
+ beqz t3, .Ltoken_compare_not_equal
+
+ lbu t4, (t0)
+ bne t3, t4, .Ltoken_compare_not_equal
+
+ addi t0, t0, 1
+ addi t1, t1, -1
+ addi t2, t2, 1
+ j .Ltoken_compare_loop
+
+.Ltoken_compare_not_equal:
+ li a0, 1
+ j .Ltoken_compare_end
+
+.Ltoken_compare_equal:
+ li a0, 0
+
+.Ltoken_compare_end:
+ ret
+
# Parameters:
# a0 - Line length.
+# Returns 1 in a0 if the parsed line contained a text section element such a
+# procedure or the program entry point. Otherwise sets a0 to 0.
.type _compile_line, @function
_compile_line:
# Prologue.
@@ -560,14 +757,42 @@ _compile_line:
call memcmp
beqz a0, .Lcompile_line_procedure
+ li t0, 0x0a6e # n\n
+ sw t0, 16(sp)
+ li t0, 0x69676562 # begi
+ sw t0, 12(sp)
+ mv a0, s1
+ addi a1, sp, 12
+ li a2, 6
+ call memcmp
+ beqz a0, .Lcompile_line_begin
+
+ li t0, 0x2e646e65 # end.
+ sw t0, 16(sp)
+ mv a0, s1
+ addi a1, sp, 16
+ li a2, 4
+ call memcmp
+ beqz a0, .Lcompile_line_exit
+
j .Lcompile_line_unchanged # Else.
+.Lcompile_line_exit:
+ call _compile_exit
+ j .Lcompile_line_section
+
+.Lcompile_line_begin:
+ call _compile_entry_point
+ li a0, 1
+ j .Lcompile_line_end
+
.Lcompile_line_const:
call _compile_constant_section
- j .Lcompile_line_end
+ j .Lcompile_line_section
.Lcompile_line_procedure:
call _compile_procedure
+ li a0, 1
j .Lcompile_line_end
.Lcompile_line_var:
@@ -578,25 +803,28 @@ _compile_line:
call write_error */
call _compile_variable_section
- j .Lcompile_line_end
+ j .Lcompile_line_section
.Lcompile_line_program:
call _compile_program
- j .Lcompile_line_end
+ j .Lcompile_line_section
.Lcompile_line_comment:
lw a0, 20(sp)
call _skip_comment
- j .Lcompile_line_end
+ j .Lcompile_line_section
.Lcompile_line_empty:
addi s1, s1, 1
- j .Lcompile_line_end
+ j .Lcompile_line_section
.Lcompile_line_unchanged:
lw a0, 20(sp)
call _compile_assembly
- j .Lcompile_line_end
+ j .Lcompile_line_section
+
+.Lcompile_line_section:
+ mv a0, zero
.Lcompile_line_end:
# Epilogue.
@@ -605,6 +833,109 @@ _compile_line:
addi sp, sp, 32
ret
+.type _compile_text_section, @function
+_compile_text_section:
+ # Prologue.
+ addi sp, sp, -24
+ sw ra, 20(sp)
+ sw s0, 16(sp)
+ addi s0, sp, 24
+
+ # .section .text
+ li t0, 0x0a7478 # xt\n
+ sw t0, 12(sp)
+ li t0, 0x65742e20 # _.te
+ sw t0, 8(sp)
+ li t0, 0x6e6f6974 # tion
+ sw t0, 4(sp)
+ li t0, 0x6365732e # .sec
+ sw t0, 0(sp)
+
+ addi a0, sp, 0
+ li a1, 15
+ call write_out
+
+ # Epilogue.
+ lw ra, 20(sp)
+ lw s0, 16(sp)
+ addi sp, sp, 24
+ ret
+
+.type _compile_entry_point, @function
+_compile_entry_point:
+ # Prologue.
+ addi sp, sp, -64
+ sw ra, 60(sp)
+ sw s0, 56(sp)
+ addi s0, sp, 64
+
+ # .type _start, @function
+ li t0, 0x0a3a7472 # rt:\n
+ sw t0, 52(sp)
+ li t0, 0x6174735f # _sta
+ sw t0, 48(sp)
+ li t0, 0x0a6e6f69 # ion\n
+ sw t0, 44(sp)
+ li t0, 0x74636e75 # unct
+ sw t0, 40(sp)
+ li t0, 0x6640202c # , @f
+ sw t0, 36(sp)
+ li t0, 0x74726174 # tart
+ sw t0, 32(sp)
+ li t0, 0x735f2065 # e _s
+ sw t0, 28(sp)
+ li t0, 0x7079742e # .typ
+ sw t0, 24(sp)
+ addi a0, sp, 24
+ li a1, 32
+ call write_out
+
+ addi s1, s1, 6 # Skip begin\n.
+
+ # Epilogue.
+ lw ra, 60(sp)
+ lw s0, 56(sp)
+ addi sp, sp, 64
+ ret
+
+.type _compile_exit, @function
+_compile_exit:
+ # Prologue.
+ addi sp, sp, -64
+ sw ra, 60(sp)
+ sw s0, 56(sp)
+ addi s0, sp, 64
+
+ # li a0, 0
+ # li a7, SYS_EXIT
+ # ecall
+ li t0, 0x0a # \n
+ sw t0, 52(sp)
+ li t0, 0x6c6c6163 # call
+ sw t0, 48(sp)
+ li t0, 0x650a3339 # 93\ne
+ sw t0, 44(sp)
+ li t0, 0x202c3761 # a7,_
+ sw t0, 40(sp)
+ li t0, 0x20696c0a # \nli_
+ sw t0, 36(sp)
+ li t0, 0x30202c30 # 0, 0
+ sw t0, 32(sp)
+ li t0, 0x6120696c # li a
+ sw t0, 28(sp)
+ addi a0, sp, 28
+ li a1, 25
+ call write_out
+
+ addi s1, s1, 4 # Skip end.
+ call _skip_spaces # Read the possible new line at the end of the file.
+
+ # Epilogue.
+ lw ra, 60(sp)
+ lw s0, 56(sp)
+ addi sp, sp, 64
+ ret
+
# Finds the end of the line and returns its length in a0.
.type _read_line, @function
_read_line:
@@ -626,10 +957,10 @@ _read_line:
.type _compile, @function
_compile:
# Prologue.
- addi sp, sp, -8
- sw ra, 4(sp)
- sw s0, 0(sp)
- addi s0, sp, 8
+ addi sp, sp, -16
+ sw ra, 12(sp)
+ sw s0, 8(sp)
+ addi s0, sp, 16
.Lcompile_do:
lbu t0, (s1) # t0 = Current character.
@@ -643,9 +974,9 @@ _compile:
.Lcompile_end:
# Epilogue.
- lw ra, 4(sp)
- lw s0, 0(sp)
- addi sp, sp, 8
+ lw ra, 12(sp)
+ lw s0, 8(sp)
+ addi sp, sp, 16
ret
# Entry point.