- RIP-relative LEA is now used to load program counter in prolog and tail calls; saves 3 bytes of code and 4 bytes of relocation information over an immediate MOV
- VM field accesses no longer involve a redundant addition
HOOK: %set-alien-vector cpu ( ptr offset value rep -- )
HOOK: %alien-global cpu ( dst symbol library -- )
+HOOK: %vm-field cpu ( dst fieldname -- )
HOOK: %vm-field-ptr cpu ( dst fieldname -- )
HOOK: %allot cpu ( dst size class temp -- )
: %load-vm-addr ( reg -- ) vm-reg MR ;
-: %load-vm-field-addr ( reg symbol -- )
- [ vm-reg ] dip vm-field-offset ADDI ;
+M: ppc %vm-field ( dst field -- )
+ [ vm-reg ] dip vm-field-offset LWZ ;
-M: ppc %vm-field-ptr ( dst field -- ) %load-vm-field-addr ;
+M: ppc %vm-field-ptr ( dst field -- )
+ [ vm-reg ] dip vm-field-offset ADDI ;
GENERIC: loc-reg ( loc -- reg )
ds-reg ds-reg 4 ADDI
int-regs return-reg ds-reg 0 STW ;
-:: %load-context-datastack ( dst -- )
- ! Load context struct
- dst "ctx" %vm-field-ptr
- dst dst 0 LWZ
- ! Load context datastack pointer
- dst dst "datastack" context-field-offset ADDI ;
-
M: ppc %push-context-stack ( -- )
- 11 %load-context-datastack
- 12 11 0 LWZ
+ 11 "ctx" %vm-field
+ 12 11 "datastack" context-field-offset LWZ
12 12 4 ADDI
- 12 11 0 STW
+ 12 11 "datastack" context-field-offset STW
int-regs return-reg 12 0 STW ;
M: ppc %pop-context-stack ( -- )
- 11 %load-context-datastack
- 12 11 0 LWZ
+ 11 "ctx" %vm-field
+ 12 11 "datastack" context-field-offset LWZ
int-regs return-reg 12 0 LWZ
12 12 4 SUBI
- 12 11 0 STW ;
+ 12 11 "datastack" context-field-offset STW ;
M: ppc %unbox ( n rep func -- )
! Value must be in r3
M: x86.32 %mov-vm-ptr ( reg -- )
0 MOV 0 rc-absolute-cell rel-vm ;
+M: x86.32 %vm-field ( dst field -- )
+ [ 0 [] MOV ] dip vm-field-offset rc-absolute-cell rel-vm ;
+
M: x86.32 %vm-field-ptr ( dst field -- )
[ 0 MOV ] dip vm-field-offset rc-absolute-cell rel-vm ;
0 PUSH rc-absolute-cell rel-this
3 cells - decr-stack-reg ;
+M: x86.32 %prepare-jump
+ pic-tail-reg 0 MOV xt-tail-pic-offset rc-absolute-cell rel-here ;
+
M: x86.32 %load-param-reg
stack-params assert=
[ [ EAX ] dip local@ MOV ] dip
EAX swap ds-reg reg-stack MOV ;
M: x86.32 %pop-context-stack ( -- )
- temp-reg %load-context-datastack
- EAX temp-reg [] MOV
+ temp-reg "ctx" %vm-field
+ EAX temp-reg "datastack" context-field-offset [+] MOV
EAX EAX [] MOV
- temp-reg [] bootstrap-cell SUB ;
+ temp-reg "datastack" context-field-offset [+] bootstrap-cell SUB ;
: call-unbox-func ( func -- )
4 save-vm-ptr
ESP stack-frame-size 3 bootstrap-cells - SUB
] jit-prolog jit-define
+[
+ temp3 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-load-vm ( -- )
vm-reg 0 MOV 0 rc-absolute-cell jit-vm ;
M: x86.64 %mov-vm-ptr ( reg -- )
vm-reg MOV ;
+M: x86.64 %vm-field ( dst field -- )
+ [ vm-reg ] dip vm-field-offset [+] MOV ;
+
M: x86.64 %vm-field-ptr ( dst field -- )
[ vm-reg ] dip vm-field-offset [+] LEA ;
: param@ ( n -- op ) reserved-stack-space + stack@ ;
M: x86.64 %prologue ( n -- )
- temp-reg 0 MOV rc-absolute-cell rel-this
+ temp-reg -7 [] LEA
dup PUSH
temp-reg PUSH
stack-reg swap 3 cells - SUB ;
+M: x86.64 %prepare-jump
+ pic-tail-reg xt-tail-pic-offset [] LEA ;
+
: load-cards-offset ( dst -- )
0 MOV rc-absolute-cell rel-cards-offset ;
param-reg-0 swap ds-reg reg-stack MOV ;
M: x86.64 %pop-context-stack ( -- )
- temp-reg %load-context-datastack
- param-reg-0 temp-reg [] MOV
+ temp-reg "ctx" %vm-field
+ param-reg-0 temp-reg "datastack" context-field-offset [+] MOV
param-reg-0 param-reg-0 [] MOV
- temp-reg [] bootstrap-cell SUB ;
+ temp-reg "datastack" context-field-offset [+] bootstrap-cell SUB ;
M:: x86.64 %unbox ( n rep func -- )
param-reg-1 %mov-vm-ptr
[
! load entry point
- safe-reg 0 MOV rc-absolute-cell rt-this jit-rel
+ safe-reg -7 [] LEA
! save stack frame size
stack-frame-size PUSH
! push entry point
RSP stack-frame-size 3 bootstrap-cells - SUB
] jit-prolog jit-define
+[
+ temp3 5 [] LEA
+ 0 JMP rc-relative rt-entry-point-pic-tail jit-rel
+] jit-word-jump jit-define
+
: jit-load-context ( -- )
ctx-reg vm-reg vm-context-offset [+] MOV ;
ds-reg [] temp0 MOV
] jit-push jit-define
-[
- temp3 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
-
[
0 CALL rc-relative rt-entry-point-pic jit-rel
] jit-word-call jit-define
#! See the comment in vm/cpu-x86.hpp
4 1 + ; inline
+HOOK: %prepare-jump cpu ( -- )
+
M: x86 %jump ( word -- )
- pic-tail-reg 0 MOV xt-tail-pic-offset rc-absolute-cell rel-here
+ %prepare-jump
0 JMP rc-relative rel-word-pic-tail ;
M: x86 %jump-label ( label -- ) 0 JMP rc-relative label-fixup ;
ds-reg cell ADD
ds-reg [] int-regs return-reg MOV ;
-:: %load-context-datastack ( dst -- )
- ! Load context struct
- dst "ctx" %vm-field-ptr
- dst dst [] MOV
- ! Load context datastack pointer
- dst "datastack" context-field-offset ADD ;
-
M: x86 %push-context-stack ( -- )
- temp-reg %load-context-datastack
- temp-reg [] bootstrap-cell ADD
- temp-reg temp-reg [] MOV
+ temp-reg "ctx" %vm-field
+ temp-reg "datastack" context-field-offset [+] bootstrap-cell ADD
+ temp-reg temp-reg "datastack" context-field-offset [+] MOV
temp-reg [] int-regs return-reg MOV ;
M: x86 %epilogue ( n -- ) cell - incr-stack-reg ;
M:: x86 %restore-context ( temp1 temp2 -- )
#! Load Factor stack pointers on entry from C to Factor.
#! Also save callstack bottom!
- temp1 "ctx" %vm-field-ptr
- temp1 temp1 [] MOV
+ temp1 "ctx" %vm-field
temp2 stack-reg stack-frame get total-size>> cell - [+] LEA
temp1 "callstack-bottom" context-field-offset [+] temp2 MOV
ds-reg temp1 "datastack" context-field-offset [+] MOV
#! Save Factor stack pointers in case the C code calls a
#! callback which does a GC, which must reliably trace
#! all roots.
- temp1 "ctx" %vm-field-ptr
- temp1 temp1 [] MOV
+ temp1 "ctx" %vm-field
temp2 stack-reg cell neg [+] LEA
temp1 "callstack-top" context-field-offset [+] temp2 MOV
temp1 "datastack" context-field-offset [+] ds-reg MOV
void word_jump(cell word_)
{
data_root<word> word(word_,parent);
+#ifndef FACTOR_AMD64
literal(tag_fixnum(xt_tail_pic_offset));
+#endif
literal(word.value());
emit(parent->special_objects[JIT_WORD_JUMP]);
}