diff options
Diffstat (limited to 'boot/stage1.s')
| -rw-r--r-- | boot/stage1.s | 240 |
1 files changed, 163 insertions, 77 deletions
diff --git a/boot/stage1.s b/boot/stage1.s index 5989ac9..61dcdec 100644 --- a/boot/stage1.s +++ b/boot/stage1.s @@ -1,5 +1,8 @@ .global _start # Program entry point. + +# Global variables or registers. # s1 - Contains the current position in the source text. +# s2 - Label counter. .equ SOURCE_BUFFER_SIZE, 81920 @@ -29,10 +32,17 @@ asm_add_a0_a1: .ascii "add a0, a0, a1\n" .equ ASM_ADD_A0_A1_SIZE, . - asm_add_a0_a1 asm_sub_a0_a1: .ascii "sub a0, a0, a1\n" .equ ASM_SUB_A0_A1_SIZE, . - asm_sub_a0_a1 +asm_mul_a0_a1: .ascii "mul a0, a0, a1\n" +.equ ASM_MUL_A0_A1_SIZE, . - asm_mul_a0_a1 asm_seqz_a0: .ascii "seqz a0, a0\n" .equ ASM_SEQZ_A0_SIZE, . - asm_seqz_a0 +asm_neg_a0: .ascii "neg a0, a0\n" +.equ ASM_NEG_A0_SIZE, . - asm_neg_a0 asm_type: .ascii ".type " .equ ASM_TYPE_SIZE, . - asm_type +asm_restore_parameters: + .ascii "lw a0, 60(sp)\nlw a1, 56(sp)\nlw a2, 52(sp)\nlw a3, 48(sp)\nlw a4, 44(sp)\nlw a5, 40(sp)\n" +.equ ASM_RESTORE_PARAMETERS_SIZE, . - asm_restore_parameters .section .bss .type source_code, @object @@ -116,6 +126,14 @@ _build_binary_expression: call _token_compare beqz a0, .L_build_binary_expression_minus + li t0, '*' + sw t0, 16(sp) + mv a0, s1 + lw a1, 20(sp) + addi a2, sp, 16 + call _token_compare + beqz a0, .L_build_binary_expression_product + j .Lbuild_binary_expression_end .L_build_binary_expression_equal: @@ -172,6 +190,16 @@ _build_binary_expression: j .Lbuild_binary_expression_end +.L_build_binary_expression_product: + addi s1, s1, 1 # Skip *. + li a0, 1 + call _build_expression + la a0, asm_mul_a0_a1 + li a1, ASM_MUL_A0_A1_SIZE + call _write_out + + j .Lbuild_binary_expression_end + .Lbuild_binary_expression_end: # Epilogue. lw ra, 28(sp) @@ -198,18 +226,19 @@ _build_expression: sw s1, 24(sp) sw a0, 20(sp) - addi a0, s1, 0 - lbu a0, (a0) + lbu a0, (s1) + li t0, '-' + beq a0, t0, .Lbuild_expression_negate + + lbu a0, (s1) li t0, '@' beq a0, t0, .Lbuild_expression_address - addi a0, s1, 0 - lbu a0, (a0) + lbu a0, (s1) call _is_digit bnez a0, .Lbuild_expression_literal - addi a0, s1, 0 - lbu a0, (a0) + lbu a0, (s1) li t0, '_' beq a0, t0, .Lbuild_expression_call @@ -241,6 +270,17 @@ _build_expression: j .Lbuild_expression_advance +.Lbuild_expression_negate: + addi s1, s1, 1 # Skip the -. + mv a0, zero + call _build_expression + + la a0, asm_neg_a0 + li a1, ASM_NEG_A0_SIZE + call _write_out + + j .Lbuild_expression_advance + .Lbuild_expression_address: lw t1, 28(sp) li t0, 0x20 # _ @@ -464,26 +504,10 @@ _compile_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. - li t1, -4 - mul t1, t0, t1 - addi t1, t1, 60 - li t2, 10 - div t3, t1, t2 - rem t4, t1, t2 - addi t3, t3, '0' - addi t4, t4, '0' - - sw t3, 8(sp) - sw t4, 4(sp) - - addi a0, sp, 8 - li a1, 1 - call _write_out - - addi a0, sp, 4 - li a1, 1 - call _write_out + li a0, -4 + mul a0, t0, a0 + addi a0, a0, 60 + call _printi li t0, '\n' sw t0, 8(sp) @@ -511,52 +535,14 @@ _compile_call: .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. - lw t0, 12(sp) - li t1, 5 - bgt t0, t1, .Lcompile_call_perform - - li t0, 0x6120776c # lw a - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 4 + la a0, asm_restore_parameters + li a1, ASM_RESTORE_PARAMETERS_SIZE call _write_out - lw t0, 12(sp) # Argument count for a procedure call. - - li t1, -4 - mul t1, t0, t1 - addi t1, t1, 60 - li t2, 10 - div t3, t1, t2 - rem t4, t1, t2 - addi t3, t3, '0' - addi t4, t4, '0' - addi t0, t0, '0' - - li t5, '\n' - sb t5, 11(sp) - li t5, 0x29707328 # (sp) - sw t5, 7(sp) - sb t4, 6(sp) - sb t3, 5(sp) - li t5, 0x202c # ,_ - sh t5, 3(sp) - sb t0, 2(sp) - - addi a0, sp, 2 - li a1, 10 - call _write_out - - lw t0, 12(sp) # Increment. - addi t0, t0, 1 - sw t0, 12(sp) - - j .Lcompile_call_restore - .Lcompile_call_perform: li t0, 0x20 sw t0, 8(sp) - li t0, 0x6c6c6163 + li t0, 0x6c6c6163 # call sw t0, 4(sp) addi a0, sp, 4 li a1, 5 @@ -566,11 +552,8 @@ _compile_call: lw a1, 16(sp) call _write_out - li t0, '\n' - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 1 - call _write_out + li a0, '\n' + call _put_char call _skip_spaces addi s1, s1, 1 # Skip the close paren. @@ -633,6 +616,9 @@ _read_token: li t1, '-' beq t0, t1, .Ltoken_character_single + li t1, '*' + beq t0, t1, .Ltoken_character_single + li t1, '@' beq t0, t1, .Ltoken_character_single # Expect an identifier or a number. @@ -1325,6 +1311,97 @@ _compile_return: addi sp, sp, 16 ret +.type _compile_if, @function +_compile_if: + # Prologue. + addi sp, sp, -32 + sw ra, 28(sp) + sw s0, 24(sp) + addi s0, sp, 32 + + addi s1, s1, 2 # Skip the if. + call _skip_spaces + + call _build_binary_expression + + call _skip_spaces + addi s1, s1, 4 # Skip the then. + + # if end marker. + li t0, 0x00646e65 # end\0 + sw t0, 20(sp) + + # Label prefix. + li t0, 0x66694c2e # .Lif + sw t0, 16(sp) + + li t0, 0x202c3061 # a0,_ + sw t0, 12(sp) + li t0, 0x207a7165 # eqz_ + sw t0, 8(sp) + li t0, 0x62626262 # bbbb + sb t0, 7(sp) + + addi a0, sp, 7 + li a1, 13 + call _write_out + + # Write the label counter. + mv a0, s2 + call _printi + + li a0, '\n' + call _put_char + +.Lcompile_if_loop: + /* DEBUG + mv a0, s1 + li a1, 6 + call _write_error + call _divide_by_zero_error */ + + call _skip_spaces + call _read_token + + mv a1, a0 + mv a0, s1 + addi a2, sp, 20 + call _token_compare + + beqz a0, .Lcompile_if_end + + call _read_line + li a1, 1 + call _compile_line + + j .Lcompile_if_loop + +.Lcompile_if_end: + # Write the label prefix. + addi a0, sp, 16 + li a1, 4 + call _write_out + + # Write the label counter. + mv a0, s2 + call _printi + + # Finalize the label. + li t0, 0x0a3a0a3a # :\n:\n + sh t0, 12(sp) + addi a0, sp, 12 + li a1, 2 + call _write_out + + addi s2, s2, 1 # Increment the label counter. + addi s1, s1, 4 # Skip the end with newline. + + # Epilogue. + lw ra, 28(sp) + lw s0, 24(sp) + addi sp, sp, 32 + ret + # Parameters: # a0 - Line length. # a1 - Whether the section header was already emitted. If not it should be @@ -1442,6 +1519,14 @@ _compile_line: call _memcmp beqz a0, .Lcompile_line_return + li t0, 0x6669 # if + sw t0, 12(sp) + mv a0, s1 + addi a1, sp, 12 + li a2, 2 + call _memcmp + beqz a0, .Lcompile_line_if + lbu t0, (s1) li t1, '.' beq t0, t1, .Lcompile_line_label @@ -1450,16 +1535,16 @@ _compile_line: j .Lcompile_line_unchanged # Else. +.Lcompile_line_if: + call _compile_if + j .Lcompile_line_section + .Lcompile_line_label: lw a0, 20(sp) call _compile_label j .Lcompile_line_section .Lcompile_line_return: - /* DEBUG - mv a0, s1 - li a1, 6 - call _write_error */ call _compile_return j .Lcompile_line_section @@ -1659,9 +1744,10 @@ _start: li a1, SOURCE_BUFFER_SIZE # Buffer size. call _read_file + li s2, 1 la s1, source_code # s1 = Source code position. call _compile # Call exit. li a0, 0 # Use 0 return code. - call exit + call _exit |
