.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