5 Commits f5f9504860 ... 04ec27ab3d

Author SHA1 Message Date
  Giovanni Mascellani 04ec27ab3d Push more register saving outward. 5 years ago
  Giovanni Mascellani 9359798c5f Push register saving outward. 5 years ago
  Giovanni Mascellani 2689cdb234 Minor. 5 years ago
  Giovanni Mascellani 2c7176ca5b Introduce push_token to remove some duplicated code. 5 years ago
  Giovanni Mascellani 4e0f7b6bfd Rewrite push_expr. 5 years ago
2 changed files with 126 additions and 201 deletions
  1. 113 200
      asmg/asmg.asm
  2. 13 1
      asmg/kernel-asmg.asm

+ 113 - 200
asmg/asmg.asm

@@ -67,6 +67,7 @@ read_ptr_end:
 
   section .text
 
+  ;; Return: EAX
 gen_label:
   ;; Increment by 1 gen_label and return its original value
   mov eax, [label_num]
@@ -101,11 +102,8 @@ write_label_loop:
 
 
   ;; Input in EDX (variable name)
-  ;; Destroys: EAX
+  ;; Destroys: EAX, ESI, EDI
 push_var:
-  push esi
-  push edi
-
   ;; Check input length
   mov esi, edx
   call check_symbol_length
@@ -124,9 +122,6 @@ push_var:
   ;; Increment the stack depth
   inc DWORD [stack_depth]
 
-  pop edi
-  pop esi
-
   ;; If this is a temp var, increment also temp_depth
   cmp edx, temp_var
   jne push_var_non_temp
@@ -178,12 +173,9 @@ pop_temps_ret:
 
 
   ;; Input in EDX
-  ;; Destroys: ECX
+  ;; Destroys: ECX, ESI, EDI
   ;; Returns: EAX
 find_in_stack:
-  push esi
-  push edi
-
   xor ecx, ecx
 find_in_stack_loop:
   ;; Check for termination
@@ -216,8 +208,6 @@ find_in_stack_found:
   jmp find_in_stack_end
 
 find_in_stack_end:
-  pop edi
-  pop esi
   ret
 
 
@@ -496,26 +486,21 @@ add_symbol_label:
   ret
 
 
+  ;; Input in [ESP+4] (name) and [ESP+8] (want_address)
+  ;; Destroys: EAX, ECX, EDX, EBX, ESI, EDI
 push_expr:
-  push ebp
-  mov ebp, esp
-  push ebx
-  push esi
-
   ;; Try to interpret argument as number
-  mov eax, [ebp+8]
+  mov eax, [esp+4]
   call decode_number_or_char
-  mov ebx, edx
   cmp eax, 0
   je push_expr_stack
 
   ;; It is a number, check that we do not want the address
-  cmp DWORD [ebp+12], 0
+  cmp DWORD [esp+8], 0
   jne platform_panic
 
   ;; Emit the code
-  mov edx, temp_var
-  call push_var
+  mov ebx, edx
   mov cl, 0x68                  ; push ??
   call emit
   mov ecx, ebx
@@ -525,7 +510,7 @@ push_expr:
 
 push_expr_stack:
   ;; Call find_in_stack
-  mov edx, [ebp+8]
+  mov edx, [esp+4]
   call find_in_stack
   cmp eax, -1
   je push_expr_symbol
@@ -535,12 +520,10 @@ push_expr_stack:
   shl ebx, 2
 
   ;; It is on the stack: check if we want the address or not
-  cmp DWORD [ebp+12], 0
+  cmp DWORD [esp+8], 0
   jne push_expr_stack_addr
 
   ;; We want the value, emit the code
-  mov edx, temp_var
-  call push_var
   mov ecx, 0x24b4ff             ; push [esp+??]
   call emit24
   mov ecx, ebx
@@ -550,8 +533,6 @@ push_expr_stack:
 
 push_expr_stack_addr:
   ;; We want the address, emit the code
-  mov edx, temp_var
-  call push_var
   mov ecx, 0x24848d             ; lea eax, [esp+??]
   call emit24
   mov ecx, ebx
@@ -563,39 +544,31 @@ push_expr_stack_addr:
 
 push_expr_symbol:
   ;; Get symbol data
-  mov edx, [ebp+8]
+  mov edx, [esp+4]
   call find_symbol_or_panic
   mov ebx, eax
 
-  ;; If arity is -2, check we do not want the address
-  cmp edx, -2
-  jne push_expr_after_assert
-  cmp DWORD [ebp+12], 0
-  jne platform_panic
-
-push_expr_after_assert:
-  ;; Check if we want the address or arity is -2
+  ;; Handle (in this order) global constants, cases when we want the
+  ;; address and global variables
   cmp edx, -2
-  je push_expr_addr
-  cmp DWORD [ebp+12], 0
-  jne push_expr_addr
-
-  ;; Check if arity is -1
+  je push_expr_symbol_const
+  cmp DWORD [esp+8], 0
+  jne push_expr_symbol_addr
   cmp edx, -1
-  je push_expr_val
-  mov esi, edx
+  je push_expr_symbol_var
 
-  ;; This is a real function call, emit the code (part 1)
+  ;; This is a real function call, save arity and emit the call
+  mov esi, edx
   mov cl, 0xe8                  ; call ??
   call emit
   mov eax, ebx
   call compute_rel
   mov ecx, eax
   call emit32
+
+  ;; Multiply the arity by 4 and emit stack unwinding
   mov ecx, 0xc481               ; add esp, ??
   call emit16
-
-  ;; Multiply the arity by 4 and continue emitting code
   mov ecx, esi
   shl ecx, 2
   call emit32
@@ -603,10 +576,10 @@ push_expr_after_assert:
   call emit
 
   ;; Update stack variables
-push_expr_symbol_loop:
+push_expr_symbol_call_loop:
   ;; Check for termination
   cmp esi, 0
-  je push_expr_symbol_loop_end
+  je push_expr_ret
 
   ;; Call pop_var
   mov eax, 1
@@ -614,18 +587,18 @@ push_expr_symbol_loop:
 
   ;; Decrement arity and reloop
   dec esi
-  jmp push_expr_symbol_loop
+  jmp push_expr_symbol_call_loop
 
-push_expr_symbol_loop_end:
-  mov edx, temp_var
-  call push_var
+push_expr_symbol_const:
+  ;; Check we do not want the address
+  cmp DWORD [esp+8], 0
+  jne platform_panic
 
-  jmp push_expr_ret
+  ;; But we actually emit the address, because there is where the
+  ;; constant value is stored
 
-push_expr_addr:
+push_expr_symbol_addr:
   ;; We want the address, emit the code
-  mov edx, temp_var
-  call push_var
   mov cl, 0x68                  ; push ??
   call emit
   mov ecx, ebx
@@ -633,48 +606,49 @@ push_expr_addr:
 
   jmp push_expr_ret
 
-push_expr_val:
+push_expr_symbol_var:
   ;; We want the value, emit the code
-  mov edx, temp_var
-  call push_var
-  mov cl, 0xb8                  ; mov eax, ??
-  call emit
+  mov ecx, 0x35ff               ; push [??]
+  call emit16
   mov ecx, ebx
   call emit32
-  mov ecx, 0x30ff               ; push [eax]
-  call emit16
 
   jmp push_expr_ret
 
 push_expr_ret:
-  pop esi
-  pop ebx
-  pop ebp
+  ;; Keep note of the new temporary
+  mov edx, temp_var
+  call push_var
+
   ret
 
 
-push_expr_until_brace:
-  push ebx
-  push esi
-  push edi
+  ;; Input in EAX
+  ;; Destroys: EAX, ECX, EDX, EBX, ESI, EDI
+push_token:
+  ;; Check if it is a string
+  cmp BYTE [eax], QUOTE
+  je push_token_str
 
-push_expr_until_brace_loop:
-  ;; Get a token
-  call get_token
-  mov ebx, eax
+  ;; Check if we want the address
+  xor edx, edx
+  cmp BYTE [eax], AT_SIGN
+  jne push_token_value
+  inc eax
+  inc edx
 
-  ;; If it is an open brace, exit loop
-  mov ecx, [eax]
-  and ecx, 0xffff
-  cmp ecx, '{'
-  je push_expr_until_brace_end
+push_token_value:
+  ;; Call push_expr
+  push edx
+  push eax
+  call push_expr
+  add esp, 8
 
-  ;; If not, branch depending on whether it is a string or not
-  cmp BYTE [ebx], QUOTE
-  je push_expr_until_brace_string
-  jmp push_expr_until_brace_push
+  ret
+
+push_token_str:
+  mov ebx, eax
 
-push_expr_until_brace_string:
   ;; Generate a jump (in esi) and a string (in edi) label
   call gen_label
   mov esi, eax
@@ -707,8 +681,6 @@ push_expr_until_brace_string:
   call add_symbol_label
 
   ;; Emit code to push the string label
-  mov edx, temp_var
-  call push_var
   mov cl, 0x68                  ; push ??
   call emit
   mov edx, edi
@@ -718,26 +690,29 @@ push_expr_until_brace_string:
   mov ecx, eax
   call emit32
 
-  jmp push_expr_until_brace_loop
+  ;; Keep note of the new variable
+  mov edx, temp_var
+  call push_var
 
-push_expr_until_brace_push:
-  ;; Check if we want the address
-  mov esi, 0
-  cmp BYTE [ebx], AT_SIGN
-  jne push_expr_until_brace_push_value
-  mov esi, 1
-  inc ebx
+  ret
 
-push_expr_until_brace_push_value:
-  ;; Call push_expr
-  push esi
-  push ebx
-  call push_expr
-  add esp, 8
 
-  jmp push_expr_until_brace_loop
+  ;; Destroys: EAX, ECX, EDX, EBX, ESI, EDI
+push_token_until_brace:
+  ;; Get a token
+  call get_token
+
+  ;; If it is an open brace, exit loop
+  mov ecx, [eax]
+  and ecx, 0xffff
+  cmp ecx, '{'
+  je push_token_until_brace_end
+
+  call push_token
+
+  jmp push_token_until_brace
 
-push_expr_until_brace_end:
+push_token_until_brace_end:
   ;; Given the token back
   call give_back_token
 
@@ -745,18 +720,13 @@ push_expr_until_brace_end:
   cmp DWORD [temp_depth], 0
   jna platform_panic
 
-  pop edi
-  pop esi
-  pop ebx
   ret
 
 
+  ;; Destroys: EAX, ECX, EDX, ESI, EDI
 parse_block:
   push ebp
-  mov ebp, esp
   push ebx
-  push esi
-  push edi
 
   ;; Increment block depth
   inc DWORD [block_depth]
@@ -788,17 +758,22 @@ parse_block_loop:
   je parse_block_end
 
   ;; Jump to the appropriate handler
+
+  ;; semicolon
   cmp ecx, ';'
   je parse_block_semicolon
 
+  ;; ret
   cmp DWORD [ebx], 'ret'
   je parse_block_ret
 
+  ;; if
   mov eax, [ebx]
   and eax, 0xffffff
   sub eax, 'if'
   je parse_block_if
 
+  ;; while
   mov eax, [ebx]
   sub eax, 'whil'
   mov ecx, [ebx+4]
@@ -807,16 +782,18 @@ parse_block_loop:
   or eax, ecx
   je parse_block_while
 
+  ;; dollar
   cmp BYTE [ebx], DOLLAR
   je parse_block_alloc
 
+  ;; backslash
   cmp BYTE [ebx], BACKSLASH
   je parse_block_call
 
-  cmp BYTE [ebx], QUOTE
-  je parse_block_string
-
-  jmp parse_block_push
+  ;; Usual token push
+  mov eax, ebx
+  call push_token
+  jmp parse_block_loop
 
 parse_block_semicolon:
   ;; Emit code to rewind temp stack
@@ -846,8 +823,8 @@ parse_block_ret_emit:
   jmp parse_block_loop
 
 parse_block_if:
-  ;; Call push_expr_until_brace
-  call push_expr_until_brace
+  ;; Call push_token_until_brace
+  call push_token_until_brace
 
   ;; Generate the else label
   call gen_label
@@ -889,14 +866,14 @@ parse_block_if:
   jmp parse_block_loop
 
 parse_block_else:
-  ;; There is an else: generate the fi label (load in edi)
+  ;; There is an else: generate the fi label (load in EBP)
   call gen_label
-  mov edi, eax
+  mov ebp, eax
 
   ;; Emit code to jump to fi
   mov cl, 0xe9                  ; jmp ??
   call emit
-  mov edx, edi
+  mov edx, ebp
   call write_label
   mov edx, eax
   call find_symbol_or_zero
@@ -912,24 +889,26 @@ parse_block_else:
   call parse_block
 
   ;; Add the symbol for the fi label
-  mov edx, edi
+  mov edx, ebp
   call add_symbol_label
 
   jmp parse_block_loop
 
 parse_block_while:
-  ;; Generate the restart label (in esi) and the end label (in edi)
-  call gen_label
-  mov esi, eax
+  ;; Generate the restart label (in EBP)
   call gen_label
-  mov edi, eax
+  mov ebp, eax
 
   ;; Add a symbol for the restart label
-  mov edx, esi
+  mov edx, ebp
   call add_symbol_label
 
-  ;; Call push_expr_until_brace
-  call push_expr_until_brace
+  ;; Call push_token_until_brace
+  call push_token_until_brace
+
+  ;; Generate the end label (in EBX)
+  call gen_label
+  mov ebx, eax
 
   ;; Emit code to pop and possibly jump to end label
   mov eax, 1
@@ -938,7 +917,7 @@ parse_block_while:
   call emit32
   mov ecx, 0x840f               ; je ??
   call emit16
-  mov edx, edi
+  mov edx, ebx
   call write_label
   mov edx, eax
   call find_symbol_or_zero
@@ -952,7 +931,7 @@ parse_block_while:
   ;; Emit code to restart the loop
   mov cl, 0xe9                  ; jmp ??
   call emit
-  mov edx, esi
+  mov edx, ebp
   call write_label
   mov edx, eax
   call find_symbol_or_zero
@@ -961,7 +940,7 @@ parse_block_while:
   call emit32
 
   ;; Add a symbol for the end label
-  mov edx, edi
+  mov edx, ebx
   call add_symbol_label
 
   jmp parse_block_loop
@@ -1020,73 +999,12 @@ parse_block_call_loop:
 
 parse_block_call_end:
   ;; Emit code to push the return value
-  mov edx, temp_var
-  call push_var
   mov cl, 0x50                  ; push eax
   call emit
 
-  jmp parse_block_loop
-
-parse_block_string:
-  ;; Generate a jump (in esi) and a string (in edi) label
-  call gen_label
-  mov esi, eax
-  call gen_label
-  mov edi, eax
-
-  ;; Emit code to jump to the jump label
-  mov cl, 0xe9                  ; jmp ??
-  call emit
-  mov edx, esi
-  call write_label
-  mov edx, eax
-  call find_symbol_or_zero
-  call compute_rel
-  mov ecx, eax
-  call emit32
-
-  ;; Add a symbol for the string label
-  mov edx, edi
-  call add_symbol_label
-
-  ;; Emit escaped string and a terminator
-  mov ecx, ebx
-  call emit_escaped_string
-  mov cl, 0
-  call emit
-
-  ;; Add a symbol for the jump label
-  mov edx, esi
-  call add_symbol_label
-
-  ;; Emit code to push the string label
+  ;; Keep not of the new pushed value
   mov edx, temp_var
   call push_var
-  mov cl, 0x68                  ; push ??
-  call emit
-  mov edx, edi
-  call write_label
-  mov edx, eax
-  call find_symbol_or_zero
-  mov ecx, eax
-  call emit32
-
-  jmp parse_block_loop
-
-parse_block_push:
-  ;; Check if we want the address
-  xor esi, esi
-  cmp BYTE [ebx], AT_SIGN
-  jne parse_block_push_value
-  mov esi, 1
-  inc ebx
-
-parse_block_push_value:
-  ;; Call push_expr
-  push esi
-  push ebx
-  call push_expr
-  add esp, 8
 
   jmp parse_block_loop
 
@@ -1110,8 +1028,6 @@ parse_block_end:
   shl ecx, 2
   call emit32
 
-  pop edi
-  pop esi
   pop ebx
   pop ebp
   ret
@@ -1138,10 +1054,8 @@ decode_number_or_symbol_symbol:
   ret
 
 
+  ;; Destroys: EAX, ECX, EDX, EBX, ESI, EDI
 parse:
-  push ebp
-  mov ebp, esp
-  push ebx
 
   ;; Main loop
 parse_loop:
@@ -1271,11 +1185,10 @@ parse_var:
   jmp parse_loop
 
 parse_ret:
-  pop ebx
-  pop ebp
   ret
 
 
+  ;; Destroys: EAX, ECX
 init_g_compiler:
   ;; Allocate stack variables list
   mov eax, STACK_VARS_LEN * MAX_SYMBOL_NAME_LEN
@@ -1303,6 +1216,7 @@ init_g_compiler:
   ret
 
 
+  ;; Destroys: EAX, ECX, EDX, EBX, ESI, EDI
 compile:
   ;; Reset depths and stage
   mov DWORD [block_depth], 0
@@ -1339,4 +1253,3 @@ compile_stage_loop:
   add DWORD [stage], 1
 
   jmp compile_stage_loop
-

+ 13 - 1
asmg/kernel-asmg.asm

@@ -51,12 +51,23 @@ str_entry:
   db 'entry'
   db 0
 
+
   section .text
 
-  ;; void platform_g_compile(char *filename)
 platform_g_compile:
   mov eax, [esp+4]
+  push ebx
+  push esi
+  push edi
+  call g_compile
+  pop edi
+  pop esi
+  pop ebx
+  ret
+
 
+  ;; Input in EAX (filename)
+  ;; Destroys: EAX, ECX, EDX, EBX, ESI, EDI
 g_compile:
   ;; Prepare to write in memory
   mov edx, [heap_ptr]
@@ -83,6 +94,7 @@ g_compile:
   ret
 
 
+  ;; Destroys: EAX, ECX, EDX
 discard_temp_labels:
   push esi
   push edi