 [ jit-call-quot ]
 [ jit-jump-quot ]
 \ lazy-jit-compile define-combinator-primitive
-
-! Objects
-[
-    3 ds-reg 0 jit-load-cell
-    3 3 tag-mask get ANDI.
-    3 3 tag-bits get jit-shift-left-logical-imm
-    3 ds-reg 0 jit-save-cell
-] \ tag define-sub-primitive
-
-[
-    3 ds-reg 0 jit-load-cell   ! Load m
-    4 ds-reg cell-size neg jit-load-cell-update ! Load obj
-    3 3 jit-shift-fixnum-slot  ! Shift to a cell-size multiple
-    4 4 jit-mask-tag-bits      ! Clear tag bits on obj
-    3 4 3 jit-load-cell-x      ! Load cell at &obj[m]
-    3 ds-reg 0 jit-save-cell   ! Push the result to the stack
-] \ slot define-sub-primitive
-
-[
-    ! load string index from stack
-    3 ds-reg cell-size neg jit-load-cell
-    3 3 jit-shift-tag-bits
-    ! load string from stack
-    4 ds-reg 0 jit-load-cell
-    ! load character
-    4 4 string-offset ADDI
-    3 3 4 LBZX
-    3 3 tag-bits get jit-shift-left-logical-imm
-    ! store character to stack
-    ds-reg ds-reg cell-size SUBI
-    3 ds-reg 0 jit-save-cell
-] \ string-nth-fast define-sub-primitive
-
-! Shufflers
-[
-    ds-reg dup cell-size SUBI
-] \ drop define-sub-primitive
-
-[
-    ds-reg dup 2 cell-size * SUBI
-] \ 2drop define-sub-primitive
-
-[
-    ds-reg dup 3 cell-size * SUBI
-] \ 3drop define-sub-primitive
-
-[
-    3 ds-reg 0 jit-load-cell
-    3 ds-reg cell-size jit-save-cell-update
-] \ dup define-sub-primitive
-
-[
-    3 ds-reg 0 jit-load-cell
-    4 ds-reg cell-size neg jit-load-cell
-    ds-reg dup 2 cell-size * ADDI
-    3 ds-reg 0 jit-save-cell
-    4 ds-reg cell-size neg jit-save-cell
-] \ 2dup define-sub-primitive
-
-[
-    3 ds-reg 0 jit-load-cell
-    4 ds-reg cell-size neg jit-load-cell
-    5 ds-reg cell-size neg 2 * jit-load-cell
-    ds-reg dup cell-size 3 * ADDI
-    3 ds-reg 0 jit-save-cell
-    4 ds-reg cell-size neg jit-save-cell
-    5 ds-reg cell-size neg 2 * jit-save-cell
-] \ 3dup define-sub-primitive
-
-[
-    3 ds-reg 0 jit-load-cell
-    ds-reg dup cell-size SUBI
-    3 ds-reg 0 jit-save-cell
-] \ nip define-sub-primitive
-
-[
-    3 ds-reg 0 jit-load-cell
-    ds-reg dup cell-size 2 * SUBI
-    3 ds-reg 0 jit-save-cell
-] \ 2nip define-sub-primitive
-
-[
-    3 ds-reg cell-size neg jit-load-cell
-    3 ds-reg cell-size jit-save-cell-update
-] \ over define-sub-primitive
-
-[
-    3 ds-reg cell-size neg 2 * jit-load-cell
-    3 ds-reg cell-size jit-save-cell-update
-] \ pick define-sub-primitive
-
-[
-    3 ds-reg 0 jit-load-cell
-    4 ds-reg cell-size neg jit-load-cell
-    4 ds-reg 0 jit-save-cell
-    3 ds-reg cell-size jit-save-cell-update
-] \ dupd define-sub-primitive
-
-[
-    3 ds-reg 0 jit-load-cell
-    4 ds-reg cell-size neg jit-load-cell
-    3 ds-reg cell-size neg jit-save-cell
-    4 ds-reg 0 jit-save-cell
-] \ swap define-sub-primitive
-
-[
-    3 ds-reg cell-size neg jit-load-cell
-    4 ds-reg cell-size neg 2 * jit-load-cell
-    3 ds-reg cell-size neg 2 * jit-save-cell
-    4 ds-reg cell-size neg jit-save-cell
-] \ swapd define-sub-primitive
-
-[
-    3 ds-reg 0 jit-load-cell
-    4 ds-reg cell-size neg jit-load-cell
-    5 ds-reg cell-size neg 2 * jit-load-cell
-    4 ds-reg cell-size neg 2 * jit-save-cell
-    3 ds-reg cell-size neg jit-save-cell
-    5 ds-reg 0 jit-save-cell
-] \ rot define-sub-primitive
-
-[
-    3 ds-reg 0 jit-load-cell
-    4 ds-reg cell-size neg jit-load-cell
-    5 ds-reg cell-size neg 2 * jit-load-cell
-    3 ds-reg cell-size neg 2 * jit-save-cell
-    5 ds-reg cell-size neg jit-save-cell
-    4 ds-reg 0 jit-save-cell
-] \ -rot define-sub-primitive
-
-[ jit->r ] \ load-local define-sub-primitive
 
 ! Comparisons
 : jit-compare ( insn -- )

    4 MTCTR BCTR
] JIT-EXECUTE jit-define

! Special primitives
[
    frame-reg 3 MR

    3 vm-reg MR
    "begin_callback" jit-call

    jit-load-context
    jit-restore-context

    ! Call quotation
    3 frame-reg MR
    jit-call-quot

    jit-save-context

    3 vm-reg MR
    "end_callback" jit-call
] \ c-to-factor define-sub-primitive

[
    ! Unwind stack frames
    1 4 MR

    ! Load VM pointer into vm-reg, since we're entering from
    ! C code
    vm-reg jit-load-vm

    ! Load ds and rs registers
    jit-load-context
    jit-restore-context

    ! We have changed the stack; load return address again
    0 1 lr-save jit-load-cell
    0 MTLR

    ! Call quotation
    jit-jump-quot
] \ unwind-native-frames define-sub-primitive

[
    7 0 LI
    7 1 lr-save jit-save-cell

    ! Load callstack object
    6 ds-reg 0 jit-load-cell
    ds-reg ds-reg cell-size SUBI
    ! Get ctx->callstack_bottom
    jit-load-context
    3 ctx-reg context-callstack-bottom-offset jit-load-cell
    ! Get top of callstack object -- 'src' for memcpy
    4 6 callstack-top-offset ADDI
    ! Get callstack length, in bytes --- 'len' for memcpy
    7 callstack-length-offset LI
    5 6 7 jit-load-cell-x
    5 5 jit-shift-tag-bits
    ! Compute new stack pointer -- 'dst' for memcpy
    3 3 5 SUB
    ! Install new stack pointer
    1 3 MR
    ! Call memcpy; arguments are now in the correct registers
    1 1 -16 cell-size * jit-save-cell-update
    "factor_memcpy" jit-call
    1 1 0 jit-load-cell
    ! Return with new callstack
    0 1 lr-save jit-load-cell
    0 MTLR
    BLR
] \ set-callstack define-sub-primitive

[
    jit-save-context
    4 vm-reg MR

    jit-push-param
    jit-jump-quot ;

: jit-delete-current-context ( -- )
    jit-load-context
    3 vm-reg MR
    "delete_context" jit-call ;

: jit-start-context-and-delete ( -- )
    jit-save-context

