aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-16 20:49:01 +0100
committerBad Diode <bd@badd10de.dev>2021-11-16 20:49:01 +0100
commit92f33efa0cb88654e1b182416dbac631abf2be49 (patch)
tree8f70b736c11b23697f510d9c26a37933d9195dbd
parent3481ac42896ae7c5a7b40bf456cd203edeeefe4a (diff)
downloadbdl-92f33efa0cb88654e1b182416dbac631abf2be49.tar.gz
bdl-92f33efa0cb88654e1b182416dbac631abf2be49.zip
Move ret pointer before closed vars in proc calls
The previous call convention we had the following before the function call: [ PROC_ADDR | CLOSED_VARS | ARGS | RP ] This was made to be compatible with the `call` instruction and the `cdecl` calling convention. This commit changes the structure to: [ RP | PROC_ADDR | CLOSED_VARS | ARGS ] With this convention, the stack frame can be discarded in its entirety if we have a tail optimized procedure.
-rw-r--r--src/compiler.h20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/compiler.h b/src/compiler.h
index d1952ed..1ef81e3 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -343,6 +343,13 @@ compile_cdr(Object *obj) {
343void 343void
344compile_call(Object *obj) { 344compile_call(Object *obj) {
345 context_printf(" ;; --> compile_call\n"); 345 context_printf(" ;; --> compile_call\n");
346
347 // Prepare return pointer.
348 char *lab_end = generate_label("BDLL");
349 context_printf(" lea rcx, [%s]\n", lab_end);
350 context_printf(" push rcx\n");
351
352 // Compile operator.
346 compile_object(obj->head); 353 compile_object(obj->head);
347 context_printf(" pop rax\n"); 354 context_printf(" pop rax\n");
348 context_printf(" mov rcx, PTR_MASK\n"); 355 context_printf(" mov rcx, PTR_MASK\n");
@@ -379,10 +386,7 @@ compile_call(Object *obj) {
379 compile_object(obj->head); 386 compile_object(obj->head);
380 } 387 }
381 388
382 char *lab_end = generate_label("BDLL");
383 context_printf(" mov rax, [rsp + %zu]\n", 8 * offset); 389 context_printf(" mov rax, [rsp + %zu]\n", 8 * offset);
384 context_printf(" lea rcx, [%s]\n", lab_end);
385 context_printf(" push rcx\n");
386 context_printf(" jmp rax\n"); 390 context_printf(" jmp rax\n");
387 context_printf("%s:\n", lab_end); 391 context_printf("%s:\n", lab_end);
388 392
@@ -535,7 +539,11 @@ compile_lambda(Object *obj) {
535 context_printf(" pop rax\n"); 539 context_printf(" pop rax\n");
536 540
537 // Restore the previous call frame. 541 // Restore the previous call frame.
538 context_printf(" mov rdi, [rbp + 8]\n"); 542 size_t n_locals = array_size(current_env->locals);
543 size_t n_params = array_size(current_env->params);
544 size_t n_captured = array_size(current_env->captured);
545 size_t offset = 8 * (n_locals + n_params + n_captured + 2);
546 context_printf(" mov rdi, [rbp + %zu]\n", offset);
539 context_printf(" mov rsp, rbp\n"); 547 context_printf(" mov rsp, rbp\n");
540 context_printf(" add rsp, %zu\n", 8 * array_size(current_env->locals)); 548 context_printf(" add rsp, %zu\n", 8 * array_size(current_env->locals));
541 context_printf(" pop rbp\n"); 549 context_printf(" pop rbp\n");
@@ -602,7 +610,7 @@ compile_symbol(Object *obj) {
602 size_t n_locals = array_size(current_env->locals); 610 size_t n_locals = array_size(current_env->locals);
603 size_t n_params = array_size(current_env->params); 611 size_t n_params = array_size(current_env->params);
604 size_t n_cap = array_size(current_env->captured); 612 size_t n_cap = array_size(current_env->captured);
605 size_t offset = 8 * (n_locals + n_params + n_cap - idx + 1); 613 size_t offset = 8 * (n_locals + n_params + n_cap - idx);
606 context_printf(" mov rcx, [rbp + %ld]\n", offset); 614 context_printf(" mov rcx, [rbp + %ld]\n", offset);
607 context_printf(" mov rax, [rcx]\n"); 615 context_printf(" mov rax, [rcx]\n");
608 context_printf(" push rax\n"); 616 context_printf(" push rax\n");
@@ -624,7 +632,7 @@ compile_symbol(Object *obj) {
624 if (idx != -1) { 632 if (idx != -1) {
625 size_t n_locals = array_size(current_env->locals); 633 size_t n_locals = array_size(current_env->locals);
626 size_t n_params = array_size(current_env->params); 634 size_t n_params = array_size(current_env->params);
627 size_t offset = 8 * (n_locals + n_params - idx + 1); 635 size_t offset = 8 * (n_locals + n_params - idx);
628 context_printf(" mov rax, [rbp + %ld]\n", offset); 636 context_printf(" mov rax, [rbp + %ld]\n", offset);
629 context_printf(" push rax\n"); 637 context_printf(" push rax\n");
630 context_printf(" ;; <-- compile_symbol\n"); 638 context_printf(" ;; <-- compile_symbol\n");