<commit_before>! Copyright (C) 2007, 2011 <NAME>.
! See http://factorcode.org/license.txt for BSD license.
USING: bootstrap.image.private kernel kernel.private namespaces
system layouts vocabs parser compiler.constants
compiler.codegen.relocation math math.private cpu.x86.assembler
cpu.x86.assembler.operands sequences generic.single.private
threads.private locals ;
IN: bootstrap.x86

8 \ cell set

: shift-arg ( -- reg ) RCX ;
: div-arg ( -- reg ) RAX ;
: mod-arg ( -- reg ) RDX ;
: temp0 ( -- reg ) RAX ;
: temp1 ( -- reg ) RCX ;
: temp2 ( -- reg ) RDX ;
: temp3 ( -- reg ) RBX ;
: pic-tail-reg ( -- reg ) RBX ;
: return-reg ( -- reg ) RAX ;
: nv-reg ( -- reg ) RBX ;
: stack-reg ( -- reg ) RSP ;
: frame-reg ( -- reg ) RBP ;
: link-reg ( -- reg ) R11 ;
: ctx-reg ( -- reg ) R12 ;
: vm-reg ( -- reg ) R13 ;
: ds-reg ( -- reg ) R14 ;
: rs-reg ( -- reg ) R15 ;
: fixnum>slot@ ( -- ) temp0 1 SAR ;
: rex-length ( -- n ) 1 ;

: jit-call ( name -- )
    RAX 0 MOV f rc-absolute-cell rel-dlsym
    RAX CALL ;

[
    ! load entry point
    RAX 0 MOV rc-absolute-cell rel-this
    ! alignment
    RSP stack-frame-size bootstrap-cell - SUB
    ! store entry point
    RSP stack-frame-size 3 bootstrap-cells - [+] RAX MOV
    ! store stack frame size
    RSP stack-frame-size 2 bootstrap-cells - [+] stack-frame-size MOV
] jit-prolog jit-define

[
    pic-tail-reg 5 [RIP+] LEA
    0 JMP f rc-relative rel-word-pic-tail
] jit-word-jump jit-define

: jit-load-context ( -- )
    ctx-reg vm-reg vm-context-offset [+] MOV ;

: jit-save-context ( -- )
    jit-load-context
    R11 RSP -8 [+] LEA
    ctx-reg context-callstack-top-offset [+] R11 MOV
    ctx-reg context-datastack-offset [+] ds-reg MOV
    ctx-reg context-retainstack-offset [+] rs-reg MOV ;

: jit-restore-context ( -- )
    ds-reg ctx-reg context-datastack-offset [+] MOV
    rs-reg ctx-reg context-retainstack-offset [+] MOV ;

[
    ! ctx-reg is preserved across the call because it is non-volatile
    ! in the C ABI
    jit-save-context
    ! call the primitive
    arg1 vm-reg MOV
    RAX 0 MOV f f rc-absolute-cell rel-dlsym
    RAX CALL
    jit-restore-context
] jit-primitive jit-define

: jit-jump-quot ( -- ) arg1 quot-entry-point-offset [+] JMP ;

: jit-call-quot ( -- ) arg1 quot-entry-point-offset [+] CALL ;

[
    arg2 arg1 MOV
    arg1 vm-reg MOV
    "begin_callback" jit-call

    ! call the quotation
    arg1 return-reg MOV
    jit-call-quot

    arg1 vm-reg MOV
    "end_callback" jit-call
] \ c-to-factor define-sub-primitive

:: jit-signal-handler-prolog ( -- frame-size )
    ! do we also need to save XMM?
    volatile-regs length bootstrap-cells 16 align stack-frame-size + :> frame-size
    RSP frame-size bootstrap-cell - SUB ! minus a cell for return address
    volatile-regs
    [| r i | RSP i bootstrap-cells [+] r MOV ] each-index
    ! Now that the registers are saved, we can make the stack frame
    RAX 0 MOV rc-absolute-cell rel-this
    RSP frame-size 3 bootstrap-cells - [+] RAX MOV
    RSP frame-size 2 bootstrap-cells - [+] frame-size MOV
    frame-size ;

:: jit-signal-handler-epilog ( frame-size -- )
    volatile-regs<commit_msg>cpu.x86.64: also must save ctx-reg<commit_after>! Copyright (C) 2007, 2011 <NAME>.
! See http://factorcode.org/license.txt for BSD license.
USING: bootstrap.image.private kernel kernel.private namespaces
system layouts vocabs parser compiler.constants
compiler.codegen.relocation math math.private cpu.x86.assembler
cpu.x86.assembler.operands sequences generic.single.private
threads.private locals ;
IN: bootstrap.x86

8 \ cell set

: shift-arg ( -- reg ) RCX ;
: div-arg ( -- reg ) RAX ;
: mod-arg ( -- reg ) RDX ;
: temp0 ( -- reg ) RAX ;
: temp1 ( -- reg ) RCX ;
: temp2 ( -- reg ) RDX ;
: temp3 ( -- reg ) RBX ;
: pic-tail-reg ( -- reg ) RBX ;
: return-reg ( -- reg ) RAX ;
: nv-reg ( -- reg ) RBX ;
: stack-reg ( -- reg ) RSP ;
: frame-reg ( -- reg ) RBP ;
: link-reg ( -- reg ) R11 ;
: ctx-reg ( -- reg ) R12 ;
: vm-reg ( -- reg ) R13 ;
: ds-reg ( -- reg ) R14 ;
: rs-reg ( -- reg ) R15 ;
: fixnum>slot@ ( -- ) temp0 1 SAR ;
: rex-length ( -- n ) 1 ;

: jit-call ( name -- )
    RAX 0 MOV f rc-absolute-cell rel-dlsym
    RAX CALL ;

[
    ! load entry point
    RAX 0 MOV rc-absolute-cell rel-this
    ! alignment
    RSP stack-frame-size bootstrap-cell - SUB
    ! store entry point
    RSP stack-frame-size 3 bootstrap-cells - [+] RAX MOV
    ! store stack frame size
    RSP stack-frame-size 2 bootstrap-cells - [+] stack-frame-size MOV
] jit-prolog jit-define

[
    pic-tail-reg 5 [RIP+] LEA
    0 JMP f rc-relative rel-word-pic-tail
] jit-word-jump jit-define

: jit-load-context ( -- )
    ctx-reg vm-reg vm-context-offset [+] MOV ;

: jit-save-context ( -- )
    jit-load-context
    R11 RSP -8 [+] LEA
    ctx-reg context-callstack-top-offset [+] R11 MOV
    ctx-reg context-datastack-offset [+] ds-reg MOV
    ctx-reg context-retainstack-offset [+] rs-reg MOV ;

: jit-restore-context ( -- )
    ds-reg ctx-reg context-datastack-offset [+] MOV
    rs-reg ctx-reg context-retainstack-offset [+] MOV ;

[
    ! ctx-reg is preserved across the call because it is non-volatile
    ! in the C ABI
    jit-save-context
    ! call the primitive
    arg1 vm-reg MOV
    RAX 0 MOV f f rc-absolute-cell rel-dlsym
    RAX CALL
    jit-restore-context
] jit-primitive jit-define

: jit-jump-quot ( -- ) arg1 quot-entry-point-offset [+] JMP ;

: jit-call-quot ( -- ) arg1 quot-entry-point-offset [+] CALL ;

[
    arg2 arg1 MOV
    arg1 vm-reg MOV
    "begin_callback" jit-call

    ! call the quotation
    arg1 return-reg MOV
    jit-call-quot

    arg1 vm-reg MOV
    "end_callback" jit-call
] \ c-to-factor define-sub-primitive

! In addition to the C ABI volatile regs, we also whack R12
! when we save context before calling the signal handler.
: signal-handler-save-regs ( -- regs ) volatile-regs R12 suffix ;

:: jit-signal-handler-prolog ( -- frame-size )
    ! do we also need to save XMM?
    signal-handler-save-regs :> save-regs
    save-regs length bootstrap-cells 16 align stack-frame-size + :> frame-size
    RSP frame-size bootstrap-cell - SUB ! minus a cell for return address
    save-regs
    [| r i | RSP i bootstrap-cells [+] r MOV ] each-index
    ! Now that the registers are saved, we can make the stack frame
    RAX 0 MOV rc-absolute-cell rel-this
    RSP frame-size 3 bootstrap-cells - [+] RAX MOV
    RSP frame-size 2 bootstrap-cells - [+] frame-size MOV
    frame-size ;

:: jit-signal-handler-epilog ( frame-size -- )
    signal-handler-save-regs
{'fraction_non_alphanumeric': 0.13450023030861355, 'fraction_numerical': 0.018731767234761245, 'mean_word_length': 2.428421052631579, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '225727', 'n_tokens_mistral': 2510, 'n_tokens_neox': 2372, 'n_words': 653}