From 5184299c7dfddeba4d2d2ba95d390040368f9736 Mon Sep 17 00:00:00 2001 From: Mirek Kratochvil Date: Fri, 11 Aug 2023 22:30:22 +0200 Subject: [PATCH] ap aps --- apply.s | 47 ++++++++++++++++++++++++++++++++ include/apply.s | 65 +++++++++++++++++++++++++++++++++++++++++++++ include/data.s | 49 +++++++++++++++++++++++++++------- include/macros.s | 5 ++-- include/main_exit.s | 7 +++-- include/primops.s | 2 +- 6 files changed, 159 insertions(+), 16 deletions(-) create mode 100644 apply.s create mode 100644 include/apply.s diff --git a/apply.s b/apply.s new file mode 100644 index 0000000..21a1efc --- /dev/null +++ b/apply.s @@ -0,0 +1,47 @@ + +.include "include/uskel.s" + +.include "include/apply.s" +.include "include/intops.s" +.include "include/io.s" +.include "include/main_exit.s" + +main: + # make an integer + pushq $1 + pushq $INT_code + mov %rsp, %r11 + + # make a closure for adding stuff + pushq $0 + pushq $plus + pushq $FUN2_code + mov %rsp, %r12 + + # apply first argument + push %r11 + push %r12 + pushq $2 + pushq $apply1 + mov %rsp, %r12 + + # apply second argument (the p.a. function part is still in r12) + push %r11 + push %r12 + pushq $2 + pushq $apply1 + mov %rsp, %r12 + + # print the result + push %r12 + pushq $1 + pushq $print + mov %rsp, %r12 + + # make the continuation for main (exit) + push %rsi + pushq $1 + pushq $main_exit + + mov %rsp, %rsi + enter %r12 diff --git a/include/apply.s b/include/apply.s new file mode 100644 index 0000000..124e434 --- /dev/null +++ b/include/apply.s @@ -0,0 +1,65 @@ + +.include "include/data.s" + +# | fun | arg | -> cont +.thunkcode apply1 + # push a thunk for eval + push %rsi # cont + push %rbp # ret (self) + pushq 030(%rbp) # arg + pushq $3 + pushq $apply1_fini + + mov %rsp, %rsi # return to above thunk + enter 020(%rbp) # evaluate fun + +# fun -> | arg | ret | cont | +.thunkcode apply1_fini + # we now know that fun points to a FUN with at least one arg missing. + # we're certainly going to copy a lot of args. + mov 020(%rsi), %r11 # amount of args applied now + + # the copying code is shared so let's do that first: + pushq 020(%rbp) #push the new arg + lea 030(%rsi), %rdx # the end (first arg) + lea (%rdx, %r11, 8), %rbx # address behind the last arg + + cmp %rdx, %rbx + jle apply1_fini_cont +apply1_fini_copy: + sub $010, %rbx # iterate down + pushq (%rbx) # push what we have + cmp %rdx, %rbx # check if we are at the end + jg apply1_fini_copy # if not, continue +apply1_fini_cont: + add $1, %r11 + pushq %r11 # new number of args of fun/thunk + pushq 010(%rsi) # thunk code pointer + + # copying of all args and their thunky header is now done, let's find + # out how we need to finish it. + + mov (%rsi), %rdi # infotable for the original fun + mov -010(%rdi), %r12 # amount of args required to make the thunk + cmp %r11, %r12 + jg apply1_fini_feed # not enough args, just make a bigger FUN + + # if there was enough args, we simply have a thunk that we want to + # continue evaluating, so let's jump to it. + mov 030(%rbp), %rdi # load the original thunk + mov %rsp, 010(%rdi) # set indirect to the new thunk + movq $IND_code, 0(%rdi) + mov 040(%rbp), %rsi # set continuation to the original continuation + enter %rsp # evaluate the new thunk + +apply1_fini_feed: + # if there were not enough args, we push the function info and return + pushq (%rsi) # copy the function infoptr + + mov 030(%rbp), %rdi # load the original thunk + mov %rsp, 010(%rdi) # set the indirect to the new FUN + movq $IND_code, 0(%rdi) + mov %rsp, %rsi # return the new FUN + enter 040(%rbp) # jump to the continuation + +# TODO generalize to N args diff --git a/include/data.s b/include/data.s index 8261881..51f31dc 100644 --- a/include/data.s +++ b/include/data.s @@ -5,10 +5,18 @@ _data_s_file: # Simple values and boxed machine integers # | ptr | value | CON_evacuate1: - retq + retq # TODO CON_scavenge1: add $0x10, %rsi retq + +# Format of the info tables: +# - code +# ----- code pointer +# - 8B helper information for eval/apply (generally this is 0, and only gets used for FUN/PAP) +# - 8B pointer to scavenge +# - 8B pointer to evacuate + INT_info_table: cell CON_evacuate1 cell CON_scavenge1 @@ -36,7 +44,7 @@ LIST_info_table: LIST_code: continue -# FUN/PAP combo objects +# FUN objects # | ptr | thunkptr | args | arg[0] | arg[1] | ... | arg[args] | FUN_evacuate: retq #TODO @@ -47,29 +55,44 @@ FUN_scavenge: add %rax, %rsi retq -# Simple info for n-ary functions -# TODO continue to add as required -fun1_info_table: +# Info tables for FUN objects. +FUN0_info_table: + cell FUN_evacuate + cell FUN_scavenge + cell 0 +FUN0_code: + continue + +FUN1_info_table: cell FUN_evacuate cell FUN_scavenge cell 1 -fun1_code: +FUN1_code: continue -fun2_info_table: +FUN2_info_table: cell FUN_evacuate cell FUN_scavenge cell 2 -fun2_code: +FUN2_code: continue -fun3_info_table: +FUN3_info_table: cell FUN_evacuate cell FUN_scavenge cell 3 -fun3_code: +FUN3_code: continue +FUN4_info_table: + cell FUN_evacuate + cell FUN_scavenge + cell 4 +FUN4_code: + continue + +# TODO: add more funN here as needed + # indirection (Q: how to recognize IND and THUNK on return?) # | ptr | indptr | IND_evacuate: @@ -97,3 +120,9 @@ THU_scavenge: retq .endif # _data_s_file + +# evacuate and scavenge: +# - evacuate just copies the object +# - scavenge evacuates all children (to the new location IF they are in the old +# location), changes the pointer, and moves the scavenge pointer to the next +# object (because everything needs to be scavenged) diff --git a/include/macros.s b/include/macros.s index d915171..c857995 100644 --- a/include/macros.s +++ b/include/macros.s @@ -16,9 +16,8 @@ _macros_s_file: .endm .macro continue - mov %rsi, %rax - mov %rbp, %rsi - enter %rax + xchg %rsi, %rbp + enter_rbp .endm .macro thunkenv arg, dest diff --git a/include/main_exit.s b/include/main_exit.s index a38c5e5..1a38e5a 100644 --- a/include/main_exit.s +++ b/include/main_exit.s @@ -3,8 +3,11 @@ _main_exit_s_file: # exitcode -> | cont (unused, should be 0) | .thunkcode main_exit - mov 0x8(%rsi), %rdi # result to syscall exitcode - mov $0x3c, %rax # syscall 60 + mov 010(%rsi), %rdi # result goes to syscall exitcode + mov $60, %rax # exit=60 syscall # exit %rdi +# TODO this is a "case" kind of thunk so it's quite likely that it really +# doesn't need the continuation. + .endif # _main_exit_s_file diff --git a/include/primops.s b/include/primops.s index bcb835f..f019bca 100644 --- a/include/primops.s +++ b/include/primops.s @@ -10,7 +10,7 @@ _primops_s_file: # push a thunk for finishing the plus push %rsi # cont push %rbp # ret (self) - pushq 030(%rbp) + pushq 030(%rbp) # arg2 pushq $3 pushq $\name\()_step1