diff options
| author | Eugen Wissner <belka@caraus.de> | 2025-04-23 23:16:00 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2025-04-23 23:16:00 +0200 |
| commit | f343296463f8271720cf1e9cb1d45f30c288d872 (patch) | |
| tree | 24aaa3124762ed64bb754475c03cc5e5736e2bec /boot/echo-boot.s | |
| parent | 5aaf9ded3646f5312e26fc7b3502f141c2e556f5 (diff) | |
| download | elna-f343296463f8271720cf1e9cb1d45f30c288d872.tar.gz | |
Compile procedure headers
Diffstat (limited to 'boot/echo-boot.s')
| -rw-r--r-- | boot/echo-boot.s | 359 |
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. |
