: div-arg ( -- reg ) EAX ;
: mod-arg ( -- reg ) EDX ;
: temp0 ( -- reg ) EAX ;
-: temp1 ( -- reg ) EDX ;
-: temp2 ( -- reg ) ECX ;
-: temp3 ( -- reg ) EBX ;
+: temp1 ( -- reg ) ECX ;
+: temp2 ( -- reg ) EBX ;
+: temp3 ( -- reg ) EDX ;
+: pic-tail-reg ( -- reg ) EDX ;
: stack-reg ( -- reg ) ESP ;
: frame-reg ( -- reg ) EBP ;
-: vm-reg ( -- reg ) ECX ;
+: vm-reg ( -- reg ) EBX ;
: ctx-reg ( -- reg ) EBP ;
: nv-regs ( -- seq ) { ESI EDI EBX } ;
-: nv-reg ( -- reg ) EBX ;
+: nv-reg ( -- reg ) ESI ;
: ds-reg ( -- reg ) ESI ;
: rs-reg ( -- reg ) EDI ;
: fixnum>slot@ ( -- ) temp0 2 SAR ;
] jit-prolog jit-define
[
- temp3 0 MOV rc-absolute-cell rt-here jit-rel
+ pic-tail-reg 0 MOV rc-absolute-cell rt-here jit-rel
0 JMP rc-relative rt-entry-point-pic-tail jit-rel
] jit-word-jump jit-define
: jit-save-context ( -- )
jit-load-context
- EDX ESP -4 [+] LEA
- ctx-reg context-callstack-top-offset [+] EDX MOV
+ ECX ESP -4 [+] LEA
+ ctx-reg context-callstack-top-offset [+] ECX MOV
ctx-reg context-datastack-offset [+] ds-reg MOV
ctx-reg context-retainstack-offset [+] rs-reg MOV ;
[
! Load callstack object
- EBX ds-reg [] MOV
+ temp3 ds-reg [] MOV
ds-reg bootstrap-cell SUB
! Get ctx->callstack_bottom
jit-load-vm
jit-load-context
- EAX ctx-reg context-callstack-bottom-offset [+] MOV
+ temp0 ctx-reg context-callstack-bottom-offset [+] MOV
! Get top of callstack object -- 'src' for memcpy
- EBP EBX callstack-top-offset [+] LEA
+ temp1 temp3 callstack-top-offset [+] LEA
! Get callstack length, in bytes --- 'len' for memcpy
- EDX EBX callstack-length-offset [+] MOV
- EDX tag-bits get SHR
+ temp2 temp3 callstack-length-offset [+] MOV
+ temp2 tag-bits get SHR
! Compute new stack pointer -- 'dst' for memcpy
- EAX EDX SUB
+ temp0 temp2 SUB
! Install new stack pointer
- ESP EAX MOV
+ ESP temp0 MOV
! Call memcpy
- EDX PUSH
- EBP PUSH
- EAX PUSH
+ temp2 PUSH
+ temp1 PUSH
+ temp0 PUSH
"factor_memcpy" jit-call
ESP 12 ADD
! Return with new callstack
! Inline cache miss entry points
: jit-load-return-address ( -- )
- EBX ESP stack-frame-size bootstrap-cell - [+] MOV ;
+ pic-tail-reg ESP stack-frame-size bootstrap-cell - [+] MOV ;
! These are always in tail position with an existing stack
! frame, and the stack. The frame setup takes this into account.
jit-load-vm
jit-save-context
ESP 4 [+] vm-reg MOV
- ESP [] EBX MOV
+ ESP [] pic-tail-reg MOV
"inline_cache_miss" jit-call
jit-restore-context ;
[
ESP [] EAX MOV
ESP 4 [+] EDX MOV
+ jit-load-vm
ESP 8 [+] vm-reg MOV
jit-call
]
EBX tag-bits get SAR
ESP [] EBX MOV
ESP 4 [+] EBP MOV
+ jit-load-vm
ESP 8 [+] vm-reg MOV
"overflow_fixnum_multiply" jit-call
]
! Load context and parameter from datastack
EAX ds-reg [] MOV
EAX EAX alien-offset [+] MOV
- EBX ds-reg -4 [+] MOV
+ EDX ds-reg -4 [+] MOV
ds-reg 8 SUB
! Make the new context active
! Store parameter to datastack
ds-reg 4 ADD
- ds-reg [] EBX MOV ;
+ ds-reg [] EDX MOV ;
[ jit-set-context ] \ (set-context) define-sub-primitive
"new_context" jit-call
! Save pointer to quotation and parameter
- EBX ds-reg MOV
+ EDX ds-reg MOV
ds-reg 8 SUB
! Make the new context active
EAX jit-switch-context
! Push parameter
- EAX EBX -4 [+] MOV
+ EAX EDX -4 [+] MOV
ds-reg 4 ADD
ds-reg [] EAX MOV
0 PUSH
! Jump to initial quotation
- EAX EBX [] MOV
+ EAX EDX [] MOV
jit-jump-quot ;
[ jit-start-context ] \ (start-context) define-sub-primitive
: shift-arg ( -- reg ) RCX ;
: div-arg ( -- reg ) RAX ;
: mod-arg ( -- reg ) RDX ;
-: temp0 ( -- reg ) RDI ;
-: temp1 ( -- reg ) RSI ;
+: 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 ;
] jit-prolog jit-define
[
- temp3 5 [RIP+] LEA
+ pic-tail-reg 5 [RIP+] LEA
0 JMP rc-relative rt-entry-point-pic-tail jit-rel
] jit-word-jump jit-define
[
! Optimizing compiler's side of callback accesses
! arguments that are on the stack via the frame pointer.
- ! On x86-64, some arguments are passed in registers, and
- ! so the only register that is safe for use here is nv-reg.
+ ! On x86-32 fastcall, and x86-64, some arguments are passed
+ ! in registers, and so the only registers that are safe for
+ ! use here are frame-reg, nv-reg and vm-reg.
frame-reg PUSH
frame-reg stack-reg MOV
[
! Load word
- nv-reg 0 MOV rc-absolute-cell rt-literal jit-rel
+ temp0 0 MOV rc-absolute-cell rt-literal jit-rel
! Bump profiling counter
- nv-reg profile-count-offset [+] 1 tag-fixnum ADD
+ temp0 profile-count-offset [+] 1 tag-fixnum ADD
! Load word->code
- nv-reg nv-reg word-code-offset [+] MOV
+ temp0 temp0 word-code-offset [+] MOV
! Compute word entry point
- nv-reg compiled-header-size ADD
+ temp0 compiled-header-size ADD
! Jump to entry point
- nv-reg JMP
+ temp0 JMP
] jit-profiling jit-define
[
! ! ! Polymorphic inline caches
-! The PIC stubs are not permitted to touch temp3.
+! The PIC stubs are not permitted to touch pic-tail-reg.
! Load a value from a stack position
[
! load value
temp3 ds-reg [] MOV
! make a copy
- temp1 temp3 MOV
- ! compute positive shift value in temp1
- temp1 CL SHL
+ temp2 temp3 MOV
+ ! compute positive shift value in temp2
+ temp2 CL SHL
shift-arg NEG
! compute negative shift value in temp3
temp3 CL SAR
temp3 tag-mask get bitnot AND
shift-arg 0 CMP
- ! if shift count was negative, move temp0 to temp1
- temp1 temp3 CMOVGE
+ ! if shift count was negative, move temp0 to temp2
+ temp2 temp3 CMOVGE
! push to stack
- ds-reg [] temp1 MOV
+ ds-reg [] temp2 MOV
] \ fixnum-shift-fast define-sub-primitive
: jit-fixnum-/mod ( -- )
! load second parameter
- temp3 ds-reg [] MOV
+ temp1 ds-reg [] MOV
! load first parameter
div-arg ds-reg bootstrap-cell neg [+] MOV
! make a copy
! sign-extend
mod-arg bootstrap-cell-bits 1 - SAR
! divide
- temp3 IDIV ;
+ temp1 IDIV ;
[
jit-fixnum-/mod