{ [ over integer? ] [ R11 swap MOV param@ R11 MOV ] }
} cond ;
-M: x86 %save-param-reg [ param@ ] 2dip %copy ;
+M: x86.64 %save-param-reg [ param@ ] 2dip %copy ;
-M: x86 %load-param-reg [ swap param@ ] dip %copy ;
+M: x86.64 %load-param-reg [ swap param@ ] dip %copy ;
: with-return-regs ( quot -- )
[
M: x86.64 %pop-stack ( n -- )
param-reg-1 swap ds-reg reg-stack MOV ;
+M: x86.64 %pop-context-stack ( -- )
+ temp-reg %load-context-datastack
+ param-reg-1 temp-reg [] MOV
+ param-reg-1 param-reg-1 [] MOV
+ temp-reg [] bootstrap-cell SUB ;
+
M:: x86.64 %unbox ( n rep func -- )
param-reg-2 %mov-vm-ptr
! Call the unboxer
"unnest_stacks" f %alien-invoke ;
M: x86.64 %prepare-alien-indirect ( -- )
- param-reg-1 %mov-vm-ptr
- "unbox_alien" f %alien-invoke
+ param-reg-1 ds-reg [] MOV
+ ds-reg 8 SUB
+ param-reg-2 %mov-vm-ptr
+ "pinned_alien_offset" f %alien-invoke
RBP RAX MOV ;
M: x86.64 %alien-indirect ( -- )
"c_to_factor" f %alien-invoke ;
M: x86.64 %callback-value ( ctype -- )
- 0 %pop-stack
+ %pop-context-stack
RSP 8 SUB
param-reg-1 PUSH
param-reg-1 %mov-vm-ptr
! Copyright (C) 2007, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: bootstrap.image.private kernel namespaces system
-layouts vocabs parser compiler.constants math math.private
-cpu.x86.assembler cpu.x86.assembler.operands sequences
-generic.single.private ;
+USING: bootstrap.image.private kernel kernel.private namespaces
+system layouts vocabs parser compiler.constants math
+math.private cpu.x86.assembler cpu.x86.assembler.operands
+sequences generic.single.private ;
IN: bootstrap.x86
8 \ cell set
RSP stack-frame-size 3 bootstrap-cells - SUB
] jit-prolog jit-define
+: jit-load-vm ( -- )
+ RBP 0 MOV 0 rc-absolute-cell jit-vm ;
+
: jit-save-context ( -- )
- temp0 0 MOV rc-absolute-cell rt-context jit-rel
- temp0 temp0 [] MOV
- ! save stack pointer
- temp1 stack-reg bootstrap-cell neg [+] LEA
- temp0 [] temp1 MOV ;
+ ! VM pointer must be in RBP already
+ RCX RBP [] MOV
+ ! save ctx->callstack_top
+ RAX RSP -8 [+] LEA
+ RCX [] RAX MOV
+ ! save ctx->datastack
+ RCX 16 [+] ds-reg MOV
+ ! save ctx->retainstack
+ RCX 24 [+] rs-reg MOV ;
+
+: jit-restore-context ( -- )
+ ! VM pointer must be in EBP already
+ RCX RBP [] MOV
+ ! restore ctx->datastack
+ ds-reg RCX 16 [+] MOV
+ ! restore ctx->retainstack
+ rs-reg RCX 24 [+] MOV ;
[
+ jit-load-vm
+ ! save ds, rs registers
jit-save-context
- ! load vm ptr
- arg1 0 MOV rc-absolute-cell rt-vm jit-rel
- ! load XT
- temp1 0 MOV rc-absolute-cell rt-primitive jit-rel
- ! go
- temp1 CALL
+ ! call the primitive
+ arg1 RBP MOV
+ RAX 0 MOV rc-absolute-cell rt-primitive jit-rel
+ RAX CALL
+ ! restore ds, rs registers
+ jit-restore-context
] jit-primitive jit-define
+[
+ ! load from stack
+ arg1 ds-reg [] MOV
+ ! pop stack
+ ds-reg bootstrap-cell SUB
+ ! load VM pointer
+ arg2 0 MOV 0 rc-absolute-cell jit-vm
+]
+[ arg1 quot-xt-offset [+] CALL ]
+[ arg1 quot-xt-offset [+] JMP ]
+\ (call) define-sub-primitive*
+
! Inline cache miss entry points
: jit-load-return-address ( -- )
RBX RSP 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-inline-cache-miss ( -- )
+ jit-load-vm
jit-save-context
arg1 RBX MOV
- arg2 0 MOV 0 rc-absolute-cell jit-vm
- 0 CALL "inline_cache_miss" f rc-relative jit-dlsym ;
+ arg2 RBP MOV
+ RAX 0 MOV "inline_cache_miss" f rc-absolute-cell jit-dlsym
+ RAX CALL
+ jit-restore-context ;
[ jit-load-return-address jit-inline-cache-miss ]
[ RAX CALL ]
! Overflowing fixnum arithmetic
: jit-overflow ( insn func -- )
+ ds-reg 8 SUB
+ jit-load-vm
jit-save-context
- arg1 ds-reg bootstrap-cell neg [+] MOV
- arg2 ds-reg [] MOV
- ds-reg bootstrap-cell SUB
+ arg1 ds-reg [] MOV
+ arg2 ds-reg 8 [+] MOV
arg3 arg1 MOV
[ [ arg3 arg2 ] dip call ] dip
ds-reg [] arg3 MOV
[ JNO ]
[
- arg3 0 MOV 0 rc-absolute-cell jit-vm
- [ 0 CALL ] dip f rc-relative jit-dlsym
+ arg3 RBP MOV
+ RAX 0 MOV f rc-absolute-cell jit-dlsym
+ RAX CALL
]
jit-conditional ; inline
[ [ SUB ] "overflow_fixnum_subtract" jit-overflow ] \ fixnum- define-sub-primitive
[
+ ds-reg 8 SUB
+ jit-load-vm
jit-save-context
- RCX ds-reg bootstrap-cell neg [+] MOV
- RBX ds-reg [] MOV
+ RCX ds-reg [] MOV
+ RBX ds-reg 8 [+] MOV
RBX tag-bits get SAR
- ds-reg bootstrap-cell SUB
RAX RCX MOV
RBX IMUL
ds-reg [] RAX MOV
arg1 RCX MOV
arg1 tag-bits get SAR
arg2 RBX MOV
- arg3 0 MOV 0 rc-absolute-cell jit-vm
- 0 CALL "overflow_fixnum_multiply" f rc-relative jit-dlsym
+ arg3 RBP MOV
+ RAX 0 MOV "overflow_fixnum_multiply" f rc-absolute-cell jit-dlsym
+ RAX CALL
]
jit-conditional
] \ fixnum* define-sub-primitive
#include "asm.h"
-#define STACK_REG %rsp
#define DS_REG %r14
#define RS_REG %r15
#define RETURN_REG %rax
-#define CELL_SIZE 8
-#define STACK_PADDING 56
-
-#define NV0 %rbp
-#define NV1 %r12
+#define QUOT_XT_OFFSET 28
#ifdef WINDOWS
#endif
-#define QUOT_XT_OFFSET 28
-
-DEF(F_FASTCALL void,c_to_factor,(CELL quot, void *vm)):
+DEF(void,c_to_factor,(cell quot, void *vm)):
PUSH_NONVOLATILE
- mov ARG0,NV0
- mov ARG1,NV1
+ /* Save old stack pointer and align */
+ mov %rsp,%rbp
+ and $-16,%rsp
+ push %rbp
+
+ /* Set up stack frame for the call to the boot quotation */
push ARG0
push ARG1
/* Create register shadow area (required for Win64 only) */
- sub $32,STACK_REG
+ sub $40,%rsp
/* Load context */
- mov (NV1),ARG0
+ mov (ARG1),ARG2
/* Save ctx->callstack_bottom */
- lea -CELL_SIZE(STACK_REG),ARG1
- mov ARG1,CELL_SIZE(ARG0)
+ lea -8(%rsp),ARG3
+ mov ARG3,8(ARG2)
/* Load ctx->datastack */
- mov (CELL_SIZE * 2)(ARG0),DS_REG
+ mov 16(ARG2),DS_REG
/* Load ctx->retainstack */
- mov (CELL_SIZE * 3)(ARG0),RS_REG
+ mov 24(ARG2),RS_REG
/* Call quot-xt */
- mov NV0,ARG0
- mov NV1,ARG1
call *QUOT_XT_OFFSET(ARG0)
/* Tear down register shadow area */
- add $32,STACK_REG
+ add $40,%rsp
- /* Load context */
+ /* Tear down stack frame for the call to the boot quotation */
pop ARG1
pop ARG0
- mov (ARG1),ARG0
+
+ /* Undo stack alignment */
+ pop %rbp
+ mov %rbp,%rsp
+
+ /* Load context */
+ mov (ARG1),ARG2
/* Save ctx->datastack */
- mov DS_REG,(CELL_SIZE * 2)(ARG0)
+ mov DS_REG,16(ARG2)
/* Save ctx->retainstack */
- mov RS_REG,(CELL_SIZE * 3)(ARG0)
+ mov RS_REG,24(ARG2)
POP_NONVOLATILE
ret
-/* We pass a function pointer to memcpy to work around a Mac OS X
-ABI limitation which would otherwise require us to do a bizzaro PC-relative
-trampoline to retrieve the function address */
-DEF(void,set_callstack,(F_STACK_FRAME *to, F_STACK_FRAME *from, CELL length, void *memcpy)):
- sub ARG2,ARG0 /* compute new stack pointer */
- mov ARG0,%rsp
- call *ARG3 /* call memcpy */
- ret /* return _with new stack_ */
+DEF(void,set_callstack,(void *vm, stack_frame *to, stack_frame *from, cell length)):
+ /* save VM pointer in non-volatile register */
+ mov ARG0,%rbp
-DEF(F_FASTCALL void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to, void *vm)):
+ /* compute new stack pointer */
+ sub ARG3,ARG1
+ mov ARG1,%rsp
+
+ /* call memcpy */
+ mov ARG1,ARG0
+ mov ARG2,ARG1
+ mov ARG3,ARG2
+ call MANGLE(memcpy)
+
+ /* load context */
+ mov (%rbp),ARG2
+ /* load datastack */
+ mov 16(ARG2),DS_REG
+ /* load retainstack */
+ mov 24(ARG2),RS_REG
+
+ /* return with new stack */
+ ret
+
+DEF(void,throw_impl,(cell quot, void *new_stack, void *vm)):
/* clear x87 stack, but preserve rounding mode and exception flags */
- sub $2,STACK_REG
- fnstcw (STACK_REG)
+ sub $2,%rsp
+ fnstcw (%rsp)
fninit
- fldcw (STACK_REG)
- /* rewind_to */
- mov ARG1,STACK_REG
- mov ARG2,ARG1 /* make vm ptr 2nd arg in case quot_xt = lazy_jit_compile_impl */
+ fldcw (%rsp)
+
+ /* shuffle args */
+ mov ARG1,%rsp
+ mov ARG2,ARG1
+
+ /* load context */
+ mov (ARG1),ARG2
+ /* load datastack */
+ mov 16(ARG2),DS_REG
+ /* load retainstack */
+ mov 24(ARG2),RS_REG
+
jmp *QUOT_XT_OFFSET(ARG0)
-DEF(F_FASTCALL void,lazy_jit_compile_impl,(CELL quot, void *vm)):
- mov ARG1,ARG2 /* vm is 3rd arg */
- mov STACK_REG,ARG1 /* Save stack pointer */
- sub $STACK_PADDING,STACK_REG
+DEF(void,lazy_jit_compile_impl,(cell quot, void *vm)):
+ /* load context */
+ mov (ARG1),ARG2
+ /* save datastack */
+ mov DS_REG,16(ARG2)
+ /* save retainstack */
+ mov RS_REG,24(ARG2)
+ /* save callstack */
+ lea -8(%rsp),%rbp
+ mov %rbp,(ARG2)
+
+ /* compile quotation */
+ sub $8,%rsp
call MANGLE(lazy_jit_compile)
- mov RETURN_REG,ARG0 /* No-op on 32-bit */
- add $STACK_PADDING,STACK_REG
- jmp *QUOT_XT_OFFSET(ARG0) /* Call the quotation */
+ add $8,%rsp
+
+ /* call quotation */
+ jmp *QUOT_XT_OFFSET(RETURN_REG)
DEF(long long,read_timestamp_counter,(void)):
mov $0,%rax