diff options
Diffstat (limited to 'include/primops.s')
| -rw-r--r-- | include/primops.s | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/include/primops.s b/include/primops.s new file mode 100644 index 0000000..bcb835f --- /dev/null +++ b/include/primops.s @@ -0,0 +1,54 @@ + +.ifndef _primops_s_file +_primops_s_file: + +.include "include/data.s" + +.macro .primop2 name +# | arg1 | arg2 | -> cont +.thunkcode \name + # push a thunk for finishing the plus + push %rsi # cont + push %rbp # ret (self) + pushq 030(%rbp) + pushq $3 + pushq $\name\()_step1 + + mov %rsp, %rsi # continue to the new thunk + enter 0x10(%rbp) # evaluate arg1 + +# arg1 -> | arg2 | ret | cont | +.thunkcode \name\()_step1 + # this is guaranteed to be entered only once (it's a cont), so we can rewrite the thunk in place + mov 020(%rbp), %rax + movq $\name\()_fini, 0(%rbp) + mov %rsi, 020(%rbp) + + mov %rbp, %rsi # continue on the rewritten thunk + enter %rax # evaluate arg1 + +# arg2 -> | arg1 | ret | cont | +.thunkcode \name\()_fini + # at this point, + # arg1 is pointed to by 020(%rbp) + # arg2 is pointed to by %rsi +.endm + +.macro primop2_ret_int val + # the result should now be in %rax + mov 030(%rbp), %rsi # save result to the original plus thunk + movq \val, 010(%rsi) + movq $INT_code, 0(%rsi) + + enter 040(%rbp) # eval cont, returning %rsi +.endm + +.macro primop2_cont_indirect new + mov 030(%rbp), %rdi # load the original thunk + mov 040(%rbp), %rsi # set the continuation + movq \new, 010(%rdi) # set the indirect to the new thunk + movq $IND_code, 0(%rdi) + enter \new # continue evaluating the new thunk +.endm + +.endif # _primops_s_file |
