summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/common-boot.s26
-rw-r--r--boot/stage1.s312
-rw-r--r--boot/stage2.elna926
3 files changed, 684 insertions, 580 deletions
diff --git a/boot/common-boot.s b/boot/common-boot.s
index 9c5ebc4..c6fcb98 100644
--- a/boot/common-boot.s
+++ b/boot/common-boot.s
@@ -1,4 +1,5 @@
-.global _is_alpha, _is_digit, _is_alnum, _is_upper, _is_lower, _write_out, _read_file, exit, _memcmp, _write_error
+.global _is_alpha, _is_digit, _is_alnum, _is_upper, _is_lower
+.global _write_out, _read_file, exit, _memcmp, _write_error, _put_char
.section .rodata
@@ -200,6 +201,29 @@ _read_file:
ret
# Terminates the program. a0 contains the return code.
+.type _exit, @function
exit:
li a7, SYS_EXIT
ecall
+
+# Writes a character from a0 into the standard output.
+.type _put_char, @function
+_put_char:
+ # Prologue
+ addi sp, sp, -16
+ sw ra, 12(sp)
+ sw s0, 8(sp)
+ addi s0, sp, 16
+
+ sb a0, 4(sp)
+ li a0, STDOUT
+ addi a1, sp, 4
+ li a2, 1
+ li a7, SYS_WRITE
+ ecall
+
+ # Epilogue.
+ lw ra, 12(sp)
+ lw s0, 8(sp)
+ add sp, sp, 16
+ ret
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.
diff --git a/boot/stage2.elna b/boot/stage2.elna
index 4e87e89..50bed53 100644
--- a/boot/stage2.elna
+++ b/boot/stage2.elna
@@ -1,5 +1,21 @@
+(*
+s1 - Contains the current position in the source text.
+
+- The compiler expects valid input, otherwise it will generate invalid
+assembly or hang. There is no error checking, no semantic analysis, no
+type checking.
+
+- Imports with only a module name without package, e.g.
+"import dummy", can be parsed, but are ignored.
+
+- No loops. Only labels and goto.
+
+- Only unsigned number literals are supported (in decimal or
+hexadecimal format).
+
+- Comments are accepted only at the end of a line.
+*)
program
-# s1 - Contains the current position in the source text.
import dummy
@@ -9,14 +25,14 @@ const
var
source_code: [40960]Byte
-# Ignores the import.
+(* Ignores the import. *)
proc _compile_import()
var loca0: Word
begin
_advance(6)
_skip_spaces()
loca0 := _read_token()
- _advance(loca0) # Skip the imported module name.
+ _advance(loca0) (* Skip the imported module name. *)
end
proc _build_binary_expression()
@@ -35,82 +51,98 @@ begin
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
+ goto .Lbuild_binary_expression_end
-.L_build_binary_expression_equal:
- addi s1, s1, 1 # Skip =.
+ .L_build_binary_expression_equal
+ _advance(1) (* Skip =. *)
_build_expression(1)
- 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, 0x20627573 # sub_
- sw t0, 4(sp)
- addi a0, sp, 4
- li a1, 15
- call _write_out
-
- li t0, 0x0a306120 # _a0\n
- sw t0, 16(sp)
- li t0, 0x2c306120 # _a0,
- sw t0, 12(sp)
- li t0, 0x7a716573 # seqz
- sw t0, 8(sp)
- addi a0, sp, 8
- li a1, 12
- call _write_out
-
- j .Lbuild_binary_expression_end
-
-.L_build_binary_expression_and:
- addi s1, s1, 1 # Skip &.
+ loca0 := 0x0a3161 (* a1\n *)
+ _write_out(@loca0, 4)
+ loca0 := 0x202c3061 (* a0,_ *)
+ _write_out(@loca0, 4)
+ loca0 := 0x202c3061 (* a0,_ *)
+ _write_out(@loca0, 4)
+ loca0 := 0x20627573 (* sub_ *)
+ _write_out(@loca0, 4)
+
+ loca0 := 0x7a716573 (* seqz *)
+ _write_out(@loca0, 4)
+ loca0 := 0x2c306120 (* _a0, *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a306120 (* _a0\n *)
+ _write_out(@loca0, 4)
+
+ goto .Lbuild_binary_expression_end
+
+ .L_build_binary_expression_and
+ _advance(1) (* Skip &. *)
_build_expression(1)
- 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
- call _write_out
-
- j .Lbuild_binary_expression_end
-
-.Lbuild_binary_expression_end:
+ loca0 := 0x20646e61 (* and_ *)
+ _write_out(@loca0, 4)
+ loca0 := 0x202c3061 (* a0,_ *)
+ _write_out(@loca0, 4)
+ loca0 := 0x202c3061 (* a0,_ *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a3161 (* a1\n *)
+ _write_out(@loca0, 3)
+
+ goto .Lbuild_binary_expression_end
+
+ .L_build_binary_expression_or
+ _advance(2) (* Skip or. *)
+ _build_expression(1)
+ loca0 := 0x6120726f (* or a *)
+ _write_out(@loca0, 4)
+ loca0 := 0x61202c30 (* 0, a *)
+ _write_out(@loca0, 4)
+ loca0 := 0x61202c30 (* 0, a *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a31 (* 1\n *)
+ _write_out(@loca0, 2)
+
+ goto .Lbuild_binary_expression_end
+
+ .Lbuild_binary_expression_end
end
-# Evalutes an expression and saves the result in a0.
-#
-# a0 - X in aX, the register number to save the result.
+(*
+Evalutes an expression and saves the result in a0.
+
+a0 - X in aX, the register number to save the result.
+*)
proc _build_expression()
+var
+ loca20, loca28, loca8: Word
+ loca24: ^Byte
begin
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.
_skip_spaces()
- call _read_token
- sw s1, 16(sp)
- sw a0, 12(sp)
+ loca20 := _read_token()
+ loca24 := _current()
+
+ 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
@@ -118,7 +150,7 @@ begin
addi a0, s1, 0
lbu a0, (a0)
- li t0, 0x5f # _
+ li t0, '_'
beq a0, t0, .Lbuild_expression_call
li t0, 0x61636f6c # loca
@@ -129,31 +161,54 @@ begin
call _memcmp
beqz a0, .Lbuild_expression_identifier
- # Named identifier.
- lw t1, 20(sp)
- li t0, 0x00202c00 # \0,_
- or t0, t0, t1
+ (* Named identifier. *)
+ loca8 := 0x6120616c (* la a *)
+ _write_out(@loca8, 4)
+ loca8 := 0x00202c00 or loca28
+ _write_out(@loca8, 3)
+
+ _write_out(loca24, loca20)
+ _put_char(0x0a)
+
+ goto .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)
- li t0, 0x6120616c # la a
+ sb t1, 10(sp)
+ li t0, 0x69646461 # addi
sw t0, 4(sp)
addi a0, sp, 4
- li a1, 7
+ li a1, 13
call _write_out
- lw a0, 16(sp)
- lw a1, 12(sp)
+ _advance(1) (* Skip @. *)
+ _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, 8(sp)
- addi a0, sp, 8
+ sw t0, 16(sp)
+ addi a0, sp, 16
li a1, 1
call _write_out
goto .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)
@@ -163,8 +218,8 @@ begin
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
@@ -180,16 +235,14 @@ begin
goto .Lbuild_expression_advance
.Lbuild_expression_call
- lw a0, 16(sp)
- lw a1, 12(sp)
- add s1, s1, a1
- addi s1, s1, 1
- call _compile_call
+ _advance(loca20)
+ _advance(1)
+ _compile_call(loca24, loca20)
goto .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)
@@ -199,34 +252,28 @@ begin
li a1, 7
call _write_out
- lw a0, 16(sp)
- lw a1, 12(sp)
- call _write_out
-
- li t0, 0x0a # \n
- sw t0, 8(sp)
- addi a0, sp, 8
- li a1, 1
- call _write_out
+ _write_out(loca24, loca20)
+ _put_char(0x0a) # \n
goto .Lbuild_expression_advance
.Lbuild_expression_advance
- lw a0, 12(sp)
- add s1, s1, a0
+ _advance(loca20)
.Lbuild_expression_end
end
-# Compiles a statement beginning with an identifier.
-#
-# Left values should be variables named "loca n", where n is the offset
-# of the variable on the stack, like loca8 or loca4.
+(*
+Compiles a statement beginning with an identifier.
+
+Left values should be variables named "loca n", where n is the offset
+of the variable on the stack, like loca8 or loca4.
+*)
proc _compile_identifier()
begin
call _read_token
- # Save the pointer to the identifier and its length on the stack.
+ (* Save the pointer to the identifier and its length on the stack. *)
sw s1, 20(sp)
sw a0, 16(sp)
@@ -234,7 +281,7 @@ begin
_skip_spaces()
call _read_token
- # Save the pointer and the length of the token following the identifier.
+ (* Save the pointer and the length of the token following the identifier. *)
sw s1, 12(sp)
sw a0, 8(sp)
@@ -293,11 +340,13 @@ begin
.Lcompile_identifier_end
end
-# Compiles a procedure call. Expects s1 to point to the first argument.
-# a0 - Pointer to the procedure name.
-# a1 - Length of the procedure name.
-#
-# Returns the procedure result in a0.
+(*
+Compiles a procedure call. Expects s1 to point to the first argument.
+a0 - Pointer to the procedure name.
+a1 - Length of the procedure name.
+
+Returns the procedure result in a0.
+*)
proc _compile_call()
begin
sw a0, 20(sp)
@@ -324,9 +373,11 @@ begin
lw t0, 12(sp) # Argument count for a procedure call.
- # Only 6 arguments are supported with a0-a5.
- # Save all arguments on the stack so they aren't overriden afterwards.
- # The offset on the stack always has two digits in this case.
+ (*
+ Only 6 arguments are supported with a0-a5.
+ Save all arguments on the stack so they aren't overriden afterwards.
+ The offset on the stack always has two digits in this case.
+ *)
li t1, -4
mul t1, t0, t1
addi t1, t1, 60
@@ -365,15 +416,17 @@ begin
addi t0, t0, 1
sw t0, 12(sp)
- _advance(1) # Skip the comma between the arguments.
+ _advance(1) (* Skip the comma between the arguments. *)
goto .Lcompile_call_argument
.Lcompile_call_complete
sw zero, 12(sp)
.Lcompile_call_restore
- # Just go through all a0-a5 registers and read them from stack.
- # If this stack value contains garbage, the procedure just shouldn't use it.
+ (*
+ Just go through all a0-a5 registers and read them from stack.
+ If this stack value contains garbage, the procedure just shouldn't use it.
+ *)
lw t0, 12(sp)
li t1, 5
bgt t0, t1, .Lcompile_call_perform
@@ -436,11 +489,13 @@ begin
call _write_out
_skip_spaces()
- _advance(1) # Skip the close paren.
+ _advance(1) (* Skip the close paren. *)
end
-# Reads a token and returns its length in a0.
-# _read_token doesn't change s1, it finds the length of the token s1 is pointing to.
+(*
+Reads a token and returns its length in a0.
+_read_token doesn't change s1, it finds the length of the token s1 is pointing to.
+*)
proc _read_token()
begin
lbu t0, (s1) # t0 = Current character.
@@ -478,7 +533,10 @@ begin
li t1, '='
beq t0, t1, .Ltoken_character_single
- # Expect an identifier or a number.
+
+ li t1, '@'
+ beq t0, t1, .Ltoken_character_single
+ (* Expect an identifier or a number. *)
.Ltoken_character_loop_do
lw t6, 4(sp)
add t1, s1, t6
@@ -512,7 +570,7 @@ begin
lw a0, 4(sp)
end
-# Skips the spaces till the next non space character.
+(* Skips the spaces till the next non space character. *)
proc _skip_spaces()
begin
.Lspace_loop_do
@@ -535,7 +593,7 @@ begin
.Lspace_loop_end
end
-# Skips tabs at the line beginning.
+(* Skips tabs at the line beginning. *)
proc _skip_indentation()
begin
.Lskip_indentation_do
@@ -553,72 +611,98 @@ begin
.Lskip_indentation_end
end
-# Parameters:
-# a0 - Line length.
+(*
+Parameters:
+ a0 - Line length.
+*)
proc _skip_comment(loca84: Word)
begin
- _advance(loca84)
- _advance(1) # Skip the new line.
+ (* 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
+
+ _advance(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
+
+ _advance(1)
+
+ goto .Lskip_comment_loop
+
+ .Lskip_comment_close
+ _advance(2) (* Skip "*" and ")". *)
+
+ .Lskip_comment_end
end
-# Parameters:
-# a0 - Line length.
+(*
+Parameters:
+ a0 - Line length.
+*)
proc _compile_assembly(loca84: Word)
var loca0: ^Byte
begin
- # Write the source to the standard output.
+ (* Write the source to the standard output. *)
loca0 := _current()
_write_out(loca0, loca84)
_advance(loca84)
- li t0, '\n'
- sb t0, 0(sp)
- addi a0, sp, 0
- li a1, 1
- call _write_out
+ _put_char(0xa) (* \n *)
- _advance(1) # Skip the new line.
+ _advance(1) (* Skip the new line. *)
end
proc _compile_program()
+var loca0: Word
begin
- # .global _start
- li t0, 0x0a7472 # rt\n
- sw t0, 20(sp)
- li t0, 0x6174735f # _sta
- sw t0, 16(sp)
- li t0, 0x206c6162 # bal_
- sw t0, 12(sp)
- li t0, 0x6f6c672e # .glo
- sw t0, 8(sp)
-
- addi a0, sp, 8
- li a1, 15
- call _write_out
-
- _advance(8) # program\n.
+ (* .global _start *)
+ loca0 := 0x6f6c672e (* .glo *)
+ _write_out(@loca0, 4)
+ loca0 := 0x206c6162 (* bal_ *)
+ _write_out(@loca0, 4)
+ loca0 := 0x6174735f (* _sta *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a7472 (* rt\n *)
+ _write_out(@loca0, 3)
+
+ _advance(8) (* program\n. *)
end
proc _compile_constant_section()
+var loca0: Word
begin
- # .section .rodata
- li t0, 0x0a # \n
- sw t0, 20(sp)
- li t0, 0x61746164 # data
- sw t0, 16(sp)
- li t0, 0x6f722e20 # _.ro
- sw t0, 12(sp)
- li t0, 0x6e6f6974 # tion
- sw t0, 8(sp)
- li t0, 0x6365732e # .sec
- sw t0, 4(sp)
-
- addi a0, sp, 4
- li a1, 17
- call _write_out
-
- _advance(6) # const\n.
+ (* .section .rodata *)
+ loca0 := 0x6365732e (* .sec *)
+ _write_out(@loca0, 4)
+ loca0 := 0x6e6f6974 (* tion *)
+ _write_out(@loca0, 4)
+ loca0 := 0x6f722e20 (* _.ro *)
+ _write_out(@loca0, 4)
+ loca0 := 0x61746164 (* data *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a (* \n *)
+ _write_out(@loca0, 1)
+
+ _advance(6) (* const\n. *)
.Lcompile_constant_section_item
_skip_spaces()
@@ -633,59 +717,49 @@ begin
end
proc _compile_constant()
+var
+ loca0, loca4: Word
+ loca8: ^Byte
begin
- call _read_token
+ loca4 := _read_token()
+ loca8 := _current() (* Save the identifier pointer before advancing it. *)
- mv a1, a0 # The identifier length from _read_token should be in a1.
- mv a0, s1 # Save the identifier pointer before advancing it.
- add s1, s1, a1
- call _write_out
+ _write_out(loca8, loca4)
+ _advance(loca4)
_skip_spaces()
- call _read_token
- _advance(2) # Skip the assignment sign.
+ _advance(2) (* Skip the assignment sign. *)
- # : .long
- li t0, 0x20676e6f # ong_
- sw t0, 4(sp)
- li t0, 0x6c2e203a # : .l
- sw t0, 0(sp)
- mv a0, sp
- li a1, 8
- call _write_out
+ (* : .long *)
+ loca0 := 0x6c2e203a (* : .l *)
+ _write_out(@loca0, 4)
+ loca0 := 0x20676e6f (* ong_ *)
+ _write_out(@loca0, 4)
_skip_spaces()
- call _read_token
+ loca4 := _read_token()
+ loca8 := _current() (* Save the literal pointer before advancing it. *)
- mv a1, a0 # The literal length from _read_token should be in a1.
- mv a0, s1 # Save the literal pointer before advancing it.
- add s1, s1, a1
- call _write_out
+ _write_out(loca8, loca4)
+ _advance(loca4)
- li t0, '\n'
- sw t0, 4(sp)
- addi a0, sp, 4
- li a1, 1
- call _write_out
+ _put_char(0x0a) (* \n *)
end
proc _compile_variable_section()
+var loca0: Word
begin
- # .section .bss
- li t0, 0x0a73 # s\n
- sw t0, 12(sp)
- li t0, 0x73622e20 # _.bs
- 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, 14
- call _write_out
-
- _advance(4) # var\n.
+ (* .section .bss *)
+ loca0 := 0x6365732e (* .sec *)
+ _write_out(@loca0, 4)
+ loca0 := 0x6e6f6974 (* tion *)
+ _write_out(@loca0, 4)
+ loca0 := 0x73622e20 (* _.bs *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a73 (* s\n *)
+ _write_out(@loca0, 2)
+
+ _advance(4) (* var\n. *)
.Lcompile_variable_section_item
_skip_spaces()
@@ -703,32 +777,32 @@ proc _compile_variable()
begin
call _read_token
- # Save the identifier on the stack since it should emitted multiple times.
+ (* Save the identifier on the stack since it should emitted multiple times. *)
sw s1, 28(sp)
sw a0, 24(sp)
add s1, s1, a0
_skip_spaces()
- _advance(1) # Skip the colon in front of the type.
+ _advance(1) (* Skip the colon in front of the type. *)
_skip_spaces()
- _advance(1) # Skip the opening bracket.
+ _advance(1) (* Skip the opening bracket. *)
call _read_token
- # Save the array size on the stack since it has to be emitted multiple times.
+ (* Save the array size on the stack since it has to be emitted multiple times. *)
sw s1, 20(sp)
sw a0, 16(sp)
add s1, s1, a0
_skip_spaces()
- _advance(1) # Skip the closing bracket.
+ _advance(1) (* Skip the closing bracket. *)
_skip_spaces()
call _read_token
add s1, s1, a0 # Skip the type.
- # .type identifier, @object
+ (* .type identifier, @object *)
li t0, 0x2065 # e_
sw t0, 12(sp)
li t0, 0x7079742e # .typ
@@ -751,7 +825,7 @@ begin
li a1, 10
call _write_out
- # .size identifier, size
+ (* .size identifier, size *)
li t0, 0x2065 # e_
sw t0, 12(sp)
li t0, 0x7a69732e # .siz
@@ -780,7 +854,7 @@ begin
li a1, 1
call _write_out
- # identifier: .zero size
+ (* identifier: .zero size *)
lw a0, 28(sp)
lw a1, 24(sp)
call _write_out
@@ -805,58 +879,47 @@ begin
end
proc _compile_procedure()
+var
+ loca0, loca8, loca12, loca16: Word
+ loca20: ^Char
begin
- _advance(5) # Skip proc_
- call _read_token
- sw s1, 20(sp)
- sw a0, 16(sp)
- add s1, s1, a0
+ _advance(5) (* Skip proc_ *)
+ loca16 := _read_token()
+ loca20 := _current()
+ _advance(loca16)
- # .type identifier, @function
- li t0, 0x2065 # e_
- sw t0, 12(sp)
- li t0, 0x7079742e # .typ
- sw t0, 8(sp)
- addi a0, sp, 8
- li a1, 6
- call _write_out
+ (* .type identifier, @function *)
+ loca0 := 0x7079742e (* .typ *)
+ _write_out(@loca0, 4)
+ loca0 := 0x2065 (* e_ *)
+ _write_out(@loca0, 2)
- lw a0, 20(sp)
- lw a1, 16(sp)
- call _write_out
+ _write_out(loca20, loca16)
- li t0, 0x0a6e6f69 # ion\n
- sw t0, 12(sp)
- li t0, 0x74636e75 # unct
- sw t0, 8(sp)
- li t0, 0x6640202c # , @f
- sw t0, 4(sp)
- addi a0, sp, 4
- li a1, 12
- call _write_out
+ loca0 := 0x6640202c (* , @f *)
+ _write_out(@loca0, 4)
+ loca0 := 0x74636e75 (* unct *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a6e6f69 (* ion\n *)
+ _write_out(@loca0, 4)
- lw a0, 20(sp)
- lw a1, 16(sp)
- call _write_out
+ _write_out(loca20, loca16)
- li t0, 0x0a3a # :\n
- sw t0, 12(sp)
- addi a0, sp, 12
- li a1, 2
- call _write_out
+ loca0 := 0x0a3a (* :\n *)
+ _write_out(@loca0, 2)
_skip_spaces()
- _advance(1) # Skip opening argument paren.
+ _advance(1) (* Skip opening argument paren. *)
_skip_spaces()
- _advance(1) # Skip closing argument paren.
+ _advance(1) (* Skip closing argument paren. *)
- li t0, 0x6e # n
- sw t0, 12(sp)
- li t0, 0x69676562 # begi
- sw t0, 8(sp)
+ loca12 := 0x6e (* n *)
+ loca8 := 0x69676562 (* begi *)
- # Skip all declarations until we find the "begin" keyword, denoting the
- # beginning of the procedure body.
+ (*
+ Skip all declarations until we find the "begin" keyword, denoting the
+ beginning of the procedure body.
+ *)
.Lcompile_procedure_begin
_skip_spaces()
call _read_token
@@ -869,67 +932,45 @@ begin
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 # 8(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
-
- # Save passed arguments on the stack.
+ (* Generate the procedure prologue with a predefined stack size. *)
+ loca0 := 0x69646461 (* addi *)
+ _write_out(@loca0, 4)
+
+ loca0 := 0x2c707320 (* _sp, *)
+ _write_out(@loca0, 4)
+ _write_out(@loca0, 4)
+
+ loca0 := 0x0a36392d (* -96\n *)
+ _write_out(@loca0, 4)
+
+ loca0 := 0x72207773 (* sw r *)
+ _write_out(@loca0, 4)
+ loca0 := 0x39202c61 (* a, 9 *)
+ _write_out(@loca0, 4)
+ loca0 := 0x70732832 (* 2(sp *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a29 (* )\n *)
+ _write_out(@loca0, 2)
+
+ loca0 := 0x73207773 (* sw s *)
+ _write_out(@loca0, 4)
+ loca0 := 0x38202c30 (* 0, 8 *)
+ _write_out(@loca0, 4)
+ loca0 := 0x70732838 (* 8(sp *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a29 (* )\n *)
+ _write_out(@loca0, 2)
+
+ loca0 := 0x69646461 (* addi *)
+ _write_out(@loca0, 4)
+ loca0 := 0x2c307320 (* _s0, *)
+ _write_out(@loca0, 4)
+ loca0 := 0x2c707320 (* _sp, *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a363920 (* _96\n *)
+ _write_out(@loca0, 4)
+
+ (* Save passed arguments on the stack. *)
li t0, 0x0a29 # )\n
sw t0, 12(sp)
li t0, 0x70732834 # 4(sp
@@ -982,7 +1023,7 @@ begin
li a1, 14
call _write_out
- # Generate the body of the procedure.
+ (* Generate the body of the procedure. *)
.Lcompile_procedure_body
_skip_indentation()
call _read_line
@@ -1003,68 +1044,48 @@ begin
.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 # 8(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
+ (* Generate the procedure epilogue with a predefined stack size. *)
+ loca0 := 0x7220776c # lw r
+ _write_out(@loca0, 4)
+ loca0 := 0x39202c61 # a, 9
+ _write_out(@loca0, 4)
+ loca0 := 0x70732832 # 2(sp
+ _write_out(@loca0, 4)
+ loca0 := 0x0a29 # )\n
+ _write_out(@loca0, 2)
+
+ loca0 := 0x7320776c (* lw s *)
+ _write_out(@loca0, 4)
+ loca0 := 0x38202c30 (* 0, 8 *)
+ _write_out(@loca0, 4)
+ loca0 := 0x70732838 (* 8(sp *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a29 (* )\n *)
+ _write_out(@loca0, 2)
+
+ loca0 := 0x69646461 (* addi *)
+ _write_out(@loca0, 4)
+
+ loca0 := 0x2c707320 (* _sp, *)
+ _write_out(@loca0, 4)
+ _write_out(@loca0, 4)
+
+ loca0 := 0x0a3639 (* 96\n *)
+ _write_out(@loca0, 4)
+
+ loca0 := 0x0a746572 (* ret\n *)
+ _write_out(@loca0, 4)
+end
- addi a0, sp, 12
- li a1, 4
- call _write_out
+(*
+Compares two string, which of one has a length, the other one is null-terminated.
- 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
-end
+ a0 - The address of the token string.
+ a1 - The length of the string in a0.
+ a2 - The address of the null-terminated string.
-# 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.
+If the strings match sets a0 to 0, otherwise sets it to 1.
+*)
proc _token_compare()
begin
addi t0, a0, 0
@@ -1074,8 +1095,10 @@ begin
.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.
+ (*
+ 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
@@ -1102,7 +1125,7 @@ end
proc _compile_goto()
begin
- addi s1, s1, 4 # Skip the goto keyword.
+ _advance(4) (* Skip the goto keyword. *)
li t0, 0x206a # j_
sw t0, 8(sp)
@@ -1120,7 +1143,7 @@ begin
lw a0, 8(sp) # Saved dot position.
call _write_out
- _advance(1) # Skip the new line.
+ _advance(1) (* Skip the new line. *)
li t0, 0x0a # \n
sw t0, 8(sp)
@@ -1129,12 +1152,12 @@ begin
call _write_out
end
-# a0 - Line length.
+(* a0 - Line length. *)
proc _compile_label()
begin
sw a0, 0(sp) # Save the line length.
- # Write the whole line as is.
+ (* Write the whole line as is. *)
mv a0, s1
lw a1, 0(sp)
call _write_out
@@ -1167,23 +1190,25 @@ begin
add s1, s1, a0 # Skip the line.
end
-# Parameters:
-# a0 - Line length.
-# a1 - Whether the section header was already emitted. If not it should be
-# emitted before any code is written.
-#
-# 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.
+(*
+Parameters:
+ a0 - Line length.
+ a1 - Whether the section header was already emitted. If not it should be
+ emitted before any code is written.
+
+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.
+*)
proc _compile_line()
begin
- # Preserve passed arguments.
+ (* Preserve passed arguments. *)
sw a0, 20(sp)
sw a1, 16(sp)
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
@@ -1274,7 +1299,7 @@ begin
li t1, '_'
beq t0, t1, .Lcompile_line_identifier
- goto .Lcompile_line_unchanged # Else.
+ goto .Lcompile_line_unchanged (* Else. *)
.Lcompile_line_label
lw a0, 20(sp)
@@ -1345,80 +1370,79 @@ begin
mv a0, zero
.Lcompile_line_end
+ sw a0, 12(sp)
+ _skip_spaces()
+ _skip_comment()
+ lw a0, 12(sp)
end
-# Prints ".section .text" and exits.
+(* Prints ".section .text" and exits. *)
proc _compile_text_section()
+var loca0: Word
begin
- # .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
+ (* .section .text *)
+ loca0 := 0x6365732e (* .sec *)
+ _write_out(@loca0, 4)
+ loca0 := 0x6e6f6974 (* tion *)
+ _write_out(@loca0, 4)
+ loca0 := 0x65742e20 (* _.te *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a7478 (* xt\n *)
+ _write_out(@loca0, 3)
end
proc _compile_entry_point()
+var loca0: Word
begin
- # .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
-
- _advance(6) # Skip begin\n.
+ (* .type _start, @function *)
+ loca0 := 0x7079742e (* .typ *)
+ _write_out(@loca0, 4)
+ loca0 := 0x735f2065 (* e _s *)
+ _write_out(@loca0, 4)
+ loca0 := 0x74726174 (* tart *)
+ _write_out(@loca0, 4)
+ loca0 := 0x6640202c (* , @f *)
+ _write_out(@loca0, 4)
+ loca0 := 0x74636e75 (* unct *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a6e6f69 (* ion\n *)
+ _write_out(@loca0, 4)
+ loca0 := 0x6174735f (* _sta *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a3a7472 (* rt:\n *)
+ _write_out(@loca0, 4)
+
+ _advance(6) (* Skip begin\n. *)
end
proc _compile_exit()
+var loca0: Word
begin
- # 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
-
- _advance(4) # Skip end.
- _skip_spaces() # Read the possible new line at the end of the file.
+ (*
+ li a0, 0
+ li a7, SYS_EXIT
+ ecall
+ *)
+ loca0 := 0x6120696c (* li a *)
+ _write_out(@loca0, 4)
+ loca0 := 0x30202c30 (* 0, 0 *)
+ _write_out(@loca0, 4)
+ loca0 := 0x20696c0a (* \nli_ *)
+ _write_out(@loca0, 4)
+ loca0 := 0x202c3761 (* a7,_ *)
+ _write_out(@loca0, 4)
+ loca0 := 0x650a3339 (* 93\ne *)
+ _write_out(@loca0, 4)
+ loca0 := 0x6c6c6163 (* call *)
+ _write_out(@loca0, 4)
+ loca0 := 0x0a (* \n *)
+ _write_out(@loca0, 1)
+
+ _advance(4) (* Skip end. *)
+ _skip_spaces() (* Read the possible new line at the end of the file. *)
end
-# Finds the end of the line and returns its length in a0.
+(* Finds the end of the line and returns its length in a0. *)
proc _read_line()
begin
mv t0, s1 # Local position in the source text.
@@ -1450,7 +1474,7 @@ begin
call _compile_line
beqz a0, .Lcompile_do
- # Update whether the text section header was already emitted.
+ (* Update whether the text section header was already emitted. *)
lw t0, 4(sp)
or t0, t0, a0
sw t0, 4(sp)
@@ -1459,27 +1483,27 @@ begin
.Lcompile_end
end
-# Returns the pointer to the current position in the source text in a0.
+(* Returns the pointer to the current position in the source text in a0. *)
proc _current()
begin
mv a0, s1
end
-# a0 is the number of bytes to advance in the source text.
+(* a0 is the number of bytes to advance in the source text. *)
proc _advance()
begin
add s1, s1, a0
end
-# Returns the first character in the remaining source text.
+(* Returns the first character in the remaining source text. *)
proc _front()
begin
lbu a0, (s1)
end
-# Entry point.
+(* Entry point. *)
begin
- # Read the source from the standard input.
+ (* Read the source from the standard input. *)
la a0, source_code
la a1, SOURCE_BUFFER_SIZE # Buffer size.
lw a1, (a1)