summaryrefslogtreecommitdiff
path: root/boot/stage1.s
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-04-26 23:14:38 +0200
committerEugen Wissner <belka@caraus.de>2025-04-26 23:14:38 +0200
commita60e623af5eff3b0252cf6100cf0c366a9d3058b (patch)
tree0a0e134923d0a8380949536f52535109fab051f7 /boot/stage1.s
parentfee1781a5bb097b28056a43138713095dfa47a4a (diff)
downloadelna-a60e623af5eff3b0252cf6100cf0c366a9d3058b.tar.gz
Implement simple binary expressions
Diffstat (limited to 'boot/stage1.s')
-rw-r--r--boot/stage1.s312
1 files changed, 184 insertions, 128 deletions
diff --git a/boot/stage1.s b/boot/stage1.s
index fbfa16d..32c4e79 100644
--- a/boot/stage1.s
+++ b/boot/stage1.s
@@ -16,6 +16,14 @@ prologue: .ascii "addi sp, sp, -96\nsw ra, 92(sp)\nsw s0, 88(sp)\naddi s0, sp, 9
.equ PROLOGUE_SIZE, . - prologue
epilogue: .ascii "lw ra, 92(sp)\nlw s0, 88(sp)\naddi sp, sp, 96\nret\n"
.equ EPILOGUE_SIZE, . - epilogue
+asm_exit: .ascii "li a0, 0\nli a7, 93\necall\n"
+.equ ASM_EXIT_SIZE, . - asm_exit
+asm_start: .ascii ".type _start, @function\n_start:\n"
+.equ ASM_START_SIZE, . - asm_start
+asm_and_a0_a1: .ascii "and a0, a0, a1\n"
+.equ ASM_AND_A0_A1_SIZE, . - asm_and_a0_a1
+asm_or_a0_a1: .ascii "or a0, a0, a1\n"
+.equ ASM_OR_A0_A1_SIZE, . - asm_or_a0_a1
.section .bss
.type source_code, @object
@@ -67,18 +75,21 @@ _build_binary_expression:
call _token_compare
beqz a0, .L_build_binary_expression_and
- li t0, 0x3d # =
+ li t0, 0x726f # or
sw t0, 16(sp)
mv a0, s1
lw a1, 20(sp)
addi a2, sp, 16
call _token_compare
- beqz a0, .L_build_binary_expression_equal
+ beqz a0, .L_build_binary_expression_or
- /* DEBUG
+ li t0, 0x3d # =
+ sw t0, 16(sp)
mv a0, s1
- li a1, 8
- call _write_error */
+ lw a1, 20(sp)
+ addi a2, sp, 16
+ call _token_compare
+ beqz a0, .L_build_binary_expression_equal
j .Lbuild_binary_expression_end
@@ -114,16 +125,18 @@ _build_binary_expression:
addi s1, s1, 1 # Skip &.
li a0, 1
call _build_expression
- li t0, 0x0a3161 # a1\n
- sw t0, 16(sp)
- li t0, 0x202c3061 # a0,_
- sw t0, 12(sp)
- li t0, 0x202c3061 # a0,_
- sw t0, 8(sp)
- li t0, 0x20646e61 # and_
- sw t0, 4(sp)
- addi a0, sp, 4
- li a1, 15
+ la a0, asm_and_a0_a1
+ li a1, ASM_AND_A0_A1_SIZE
+ call _write_out
+
+ j .Lbuild_binary_expression_end
+
+.L_build_binary_expression_or:
+ addi s1, s1, 2 # Skip or.
+ li a0, 1
+ call _build_expression
+ la a0, asm_or_a0_a1
+ li a1, ASM_OR_A0_A1_SIZE
call _write_out
j .Lbuild_binary_expression_end
@@ -141,20 +154,24 @@ _build_binary_expression:
.type _build_expression, @function
_build_expression:
# Prologue.
- addi sp, sp, -32
- sw ra, 28(sp)
- sw s0, 24(sp)
- addi s0, sp, 32
+ addi sp, sp, -40
+ sw ra, 36(sp)
+ sw s0, 32(sp)
+ addi s0, sp, 40
addi a0, a0, '0' # Make the register number to a character.
- sw a0, 20(sp) # And save it.
+ sw a0, 28(sp) # And save it.
call _skip_spaces
call _read_token
- sw s1, 16(sp)
- sw a0, 12(sp)
+ sw s1, 24(sp)
+ sw a0, 20(sp)
+
+ addi a0, s1, 0
+ lbu a0, (a0)
+ li t0, '@'
+ beq a0, t0, .Lbuild_expression_address
- # Integer literal.
addi a0, s1, 0
lbu a0, (a0)
call _is_digit
@@ -162,7 +179,7 @@ _build_expression:
addi a0, s1, 0
lbu a0, (a0)
- li t0, 0x5f # _
+ li t0, '_'
beq a0, t0, .Lbuild_expression_call
li t0, 0x61636f6c # loca
@@ -174,7 +191,7 @@ _build_expression:
beqz a0, .Lbuild_expression_identifier
# Named identifier.
- lw t1, 20(sp)
+ lw t1, 28(sp)
li t0, 0x00202c00 # \0,_
or t0, t0, t1
sw t0, 8(sp)
@@ -184,48 +201,80 @@ _build_expression:
li a1, 7
call _write_out
- lw a0, 16(sp)
- lw a1, 12(sp)
+ lw a0, 24(sp)
+ lw a1, 20(sp)
call _write_out
- li t0, 0x0a # \n
+ li a0, '\n'
+ call _put_char
+
+ j .Lbuild_expression_advance
+
+.Lbuild_expression_address:
+ lw t1, 28(sp)
+ li t0, 0x20 # _
+ sw t0, 16(sp)
+ li t0, 0x2c707320 # _sp,
+ sw t0, 12(sp)
+ li t0, 0x2c006120 # _a\0,
sw t0, 8(sp)
- addi a0, sp, 8
+ sb t1, 10(sp)
+ li t0, 0x69646461 # addi
+ sw t0, 4(sp)
+ addi a0, sp, 4
+ li a1, 13
+ call _write_out
+
+ addi s1, s1, 1 # Skip @.
+ call _skip_spaces
+ call _read_token
+ sw s1, 24(sp)
+ sw a0, 20(sp)
+
+ lw a0, 24(sp)
+ lw a1, 20(sp)
+ addi a0, a0, 4 # Skip the "loca" variable prefix.
+ addi a1, a1, -4 # Skip the "loca" variable prefix.
+ call _write_out
+
+ li t0, 0x0a # \n
+ sw t0, 16(sp)
+ addi a0, sp, 16
li a1, 1
call _write_out
j .Lbuild_expression_advance
.Lbuild_expression_identifier:
- lw t1, 20(sp)
+ lw t1, 28(sp)
li t0, 0x00202c00 # \0,_
or t0, t0, t1
- sw t0, 8(sp)
+ sw t0, 16(sp)
li t0, 0x6120776c # lw a
- sw t0, 4(sp)
- addi a0, sp, 4
+ sw t0, 12(sp)
+ addi a0, sp, 12
li a1, 7
call _write_out
- lw a0, 16(sp)
- lw a1, 12(sp)
+ lw a0, 24(sp)
+ lw a1, 20(sp)
addi a0, a0, 4 # Skip the "loca" variable prefix.
addi a1, a1, -4 # Skip the "loca" variable prefix.
call _write_out
li t0, 0x0a # \n
- sw t0, 8(sp)
+ sw t0, 16(sp)
li t0, 0x29707328 # (sp)
- sw t0, 4(sp)
- addi a0, sp, 4
+ sw t0, 12(sp)
+ addi a0, sp, 12
li a1, 5
call _write_out
j .Lbuild_expression_advance
.Lbuild_expression_call:
- lw a0, 16(sp)
- lw a1, 12(sp)
+ lw a0, 24(sp)
+ lw a1, 20(sp)
add s1, s1, a1
addi s1, s1, 1
call _compile_call
@@ -233,37 +282,34 @@ _build_expression:
j .Lbuild_expression_end
.Lbuild_expression_literal:
- lw t1, 20(sp)
+ lw t1, 28(sp)
li t0, 0x00202c00 # \0,_
or t0, t0, t1
- sw t0, 8(sp)
+ sw t0, 16(sp)
li t0, 0x6120696c # li a
- sw t0, 4(sp)
- addi a0, sp, 4
+ sw t0, 12(sp)
+ addi a0, sp, 12
li a1, 7
call _write_out
- lw a0, 16(sp)
- lw a1, 12(sp)
+ lw a0, 24(sp)
+ lw a1, 20(sp)
call _write_out
- li t0, 0x0a # \n
- sw t0, 8(sp)
- addi a0, sp, 8
- li a1, 1
- call _write_out
+ li a0, '\n'
+ call _put_char
j .Lbuild_expression_advance
.Lbuild_expression_advance:
- lw a0, 12(sp)
+ lw a0, 20(sp)
add s1, s1, a0
.Lbuild_expression_end:
# Epilogue.
- lw ra, 28(sp)
- lw s0, 24(sp)
- addi sp, sp, 32
+ lw ra, 36(sp)
+ lw s0, 32(sp)
+ addi sp, sp, 40
ret
# Compiles a statement beginning with an identifier.
@@ -554,6 +600,9 @@ _read_token:
li t1, '='
beq t0, t1, .Ltoken_character_single
+
+ li t1, '@'
+ beq t0, t1, .Ltoken_character_single
# Expect an identifier or a number.
.Ltoken_character_loop_do:
lw t6, 4(sp)
@@ -638,8 +687,50 @@ _skip_indentation:
# a0 - Line length.
.type _skip_comment, @function
_skip_comment:
- add s1, s1, a0
- addi s1, s1, 1 # Skip the new line.
+ # Prologue.
+ addi sp, sp, -16
+ sw ra, 12(sp)
+ sw s0, 8(sp)
+ addi s0, sp, 16
+
+ /* DEBUG
+ mv a0, s1
+ li a1, 8
+ call _write_error */
+
+ # Check whether this is a comment.
+ li t0, 0x2a28 # (*
+ sw t0, 4(sp)
+ addi a0, sp, 4
+ mv a1, s1
+ li a2, 2
+ call _memcmp
+ bnez a0, .Lskip_comment_end
+
+ addi s1, s1, 2 # Skip (*.
+
+ li t0, 0x292a # *)
+ sw t0, 4(sp)
+
+.Lskip_comment_loop:
+ addi a0, sp, 4
+ mv a1, s1
+ li a2, 2
+ call _memcmp
+ beqz a0, .Lskip_comment_close
+
+ addi s1, s1, 1
+
+ j .Lskip_comment_loop
+
+.Lskip_comment_close:
+ addi s1, s1, 2 # Skip *).
+
+.Lskip_comment_end:
+ # Epilogue.
+ lw ra, 12(sp)
+ lw s0, 8(sp)
+ addi sp, sp, 16
ret
# Parameters:
@@ -662,11 +753,8 @@ _compile_assembly:
lw t0, 4(sp)
add s1, s1, t0
- li t0, '\n'
- sb t0, 0(sp)
- addi a0, sp, 0
- li a1, 1
- call _write_out
+ li a0, '\n'
+ call _put_char
addi s1, s1, 1 # Skip the new line.
@@ -742,7 +830,6 @@ _compile_constant:
call _write_out
call _skip_spaces
- call _read_token
addi s1, s1, 2 # Skip the assignment sign.
# : .long
@@ -762,11 +849,8 @@ _compile_constant:
add s1, s1, a1
call _write_out
- li t0, '\n'
- sw t0, 4(sp)
- addi a0, sp, 4
- li a1, 1
- call _write_out
+ li a0, '\n'
+ call _put_char
# Epilogue.
lw ra, 12(sp)
@@ -1234,7 +1318,7 @@ _compile_line:
beqz a0, .Lcompile_line_empty # Skip an empty line.
lbu t0, (s1)
- li t1, '#'
+ li t1, '('
beq t0, t1, .Lcompile_line_comment
li t0, 0x0a6d6172 # ram\n
@@ -1396,6 +1480,11 @@ _compile_line:
mv a0, zero
.Lcompile_line_end:
+ sw a0, 12(sp)
+ call _skip_spaces
+ call _skip_comment
+ lw a0, 12(sp)
+
# Epilogue.
lw ra, 28(sp)
lw s0, 24(sp)
@@ -1406,94 +1495,61 @@ _compile_line:
.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
+ addi sp, sp, -8
+ sw ra, 4(sp)
+ sw s0, 0(sp)
+ addi s0, sp, 8
la a0, section_text
li a1, SECTION_TEXT_SIZE
call _write_out
# Epilogue.
- lw ra, 20(sp)
- lw s0, 16(sp)
- addi sp, sp, 24
+ lw ra, 4(sp)
+ lw s0, 0(sp)
+ addi sp, sp, 8
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
+ addi sp, sp, -8
+ sw ra, 4(sp)
+ sw s0, 0(sp)
+ addi s0, sp, 8
# .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
+ la a0, asm_start
+ li a1, ASM_START_SIZE
call _write_out
addi s1, s1, 6 # Skip begin\n.
# Epilogue.
- lw ra, 60(sp)
- lw s0, 56(sp)
- addi sp, sp, 64
+ lw ra, 4(sp)
+ lw s0, 0(sp)
+ addi sp, sp, 8
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
+ addi sp, sp, -8
+ sw ra, 4(sp)
+ sw s0, 0(sp)
+ addi s0, sp, 8
+
+ la a0, asm_exit
+ li a1, ASM_EXIT_SIZE
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
+ lw ra, 4(sp)
+ lw s0, 0(sp)
+ addi sp, sp, 8
ret
# Finds the end of the line and returns its length in a0.