compiler.cfg.instructions compiler.cfg.builder
compiler.cfg.intrinsics compiler.cfg.stack-frame
cpu.x86.assembler cpu.x86.assembler.operands cpu.x86
-cpu.architecture ;
+cpu.architecture vm ;
+FROM: layouts => cell ;
IN: cpu.x86.32
M: x86.32 machine-registers
M: x86.32 frame-reg EBP ;
M: x86.32 temp-reg ECX ;
+M: x86.32 %mov-vm-ptr ( reg -- )
+ 0 MOV 0 rc-absolute-cell rel-vm ;
+
+M: x86.32 %vm-field-ptr ( dst field -- )
+ [ 0 MOV ] dip vm-field-offset rc-absolute-cell rel-vm ;
+
: local@ ( n -- op )
stack-frame get extra-stack-space dup 16 assert= + stack@ ;
: safe-reg ( -- reg ) EAX ;
: stack-reg ( -- reg ) ESP ;
: frame-reg ( -- reg ) EBP ;
-: vm-reg ( -- reg ) EBP ;
-: ctx-reg ( -- reg ) ECX ;
+: vm-reg ( -- reg ) ECX ;
+: ctx-reg ( -- reg ) EBP ;
: nv-regs ( -- seq ) { ESI EDI EBX } ;
: ds-reg ( -- reg ) ESI ;
: rs-reg ( -- reg ) EDI ;
ctx-reg vm-reg vm-context-offset [+] MOV ;
: jit-save-context ( -- )
- jit-load-context
EDX RSP -4 [+] LEA
ctx-reg context-callstack-top-offset [+] EDX MOV
ctx-reg context-datastack-offset [+] ds-reg MOV
ctx-reg context-retainstack-offset [+] rs-reg MOV ;
: jit-restore-context ( -- )
- jit-load-context
ds-reg ctx-reg context-datastack-offset [+] MOV
rs-reg ctx-reg context-retainstack-offset [+] MOV ;
[
jit-load-vm
+ jit-load-context
jit-save-context
! call the primitive
ESP [] vm-reg MOV
EAX EBP 8 [+] MOV
! save ctx->callstack_bottom, load ds, rs registers
jit-load-vm
+ jit-load-context
jit-restore-context
EDX stack-reg stack-frame-size 4 - [+] LEA
ctx-reg context-callstack-bottom-offset [+] EDX MOV
! call the quotation
EAX quot-xt-offset [+] CALL
! save ds, rs registers
- jit-load-vm
jit-save-context
] \ c-to-factor define-sub-primitive
! Load ds and rs registers
jit-load-vm
+ jit-load-context
jit-restore-context
! Call quotation
[
jit-load-vm
+ jit-load-context
jit-save-context
! Store arguments
! frame, and the stack. The frame setup takes this into account.
: jit-inline-cache-miss ( -- )
jit-load-vm
+ jit-load-context
jit-save-context
ESP 4 [+] vm-reg MOV
ESP [] EBX MOV
: jit-overflow ( insn func -- )
ds-reg 4 SUB
jit-load-vm
+ jit-load-context
jit-save-context
EAX ds-reg [] MOV
EDX ds-reg 4 [+] MOV
- ECX EAX MOV
- [ [ ECX EDX ] dip call( dst src -- ) ] dip
- ds-reg [] ECX MOV
+ EBX EAX MOV
+ [ [ EBX EDX ] dip call( dst src -- ) ] dip
+ ds-reg [] EBX MOV
[ JNO ]
[
ESP [] EAX MOV
ESP 4 [+] EDX MOV
- ESP 8 [+] EBP MOV
+ ESP 8 [+] vm-reg MOV
[ 0 CALL ] dip f rc-relative jit-dlsym
]
jit-conditional ;
[
ds-reg 4 SUB
jit-load-vm
+ jit-load-context
jit-save-context
- ECX ds-reg [] MOV
- EAX ECX MOV
- EBX ds-reg 4 [+] MOV
- EBX tag-bits get SAR
- EBX IMUL
+ EBX ds-reg [] MOV
+ EAX EBX MOV
+ EBP ds-reg 4 [+] MOV
+ EBP tag-bits get SAR
+ EBP IMUL
ds-reg [] EAX MOV
[ JNO ]
[
- ECX tag-bits get SAR
- ESP [] ECX MOV
- ESP 4 [+] EBX MOV
- ESP 8 [+] EBP MOV
+ EBX tag-bits get SAR
+ ESP [] EBX MOV
+ ESP 4 [+] EBP MOV
+ ESP 8 [+] vm-reg MOV
0 CALL "overflow_fixnum_multiply" f rc-relative jit-dlsym
]
jit-conditional
compiler.cfg.instructions compiler.cfg.builder
compiler.cfg.intrinsics compiler.cfg.stack-frame
cpu.x86.assembler cpu.x86.assembler.operands cpu.x86
-cpu.architecture ;
+cpu.architecture vm ;
+FROM: layouts => cell cells ;
IN: cpu.x86.64
: param-reg-0 ( -- reg ) 0 int-regs param-reg ; inline
M: x86.64 machine-registers
{
- { int-regs { RAX RCX RDX RBX RBP RSI RDI R8 R9 R10 R11 R12 R13 } }
+ { int-regs { RAX RCX RDX RBX RBP RSI RDI R8 R9 R10 R11 R12 } }
{ float-regs {
XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7
XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15
} }
} ;
+: vm-reg ( -- reg ) R13 ; inline
+
+M: x86.64 %mov-vm-ptr ( reg -- )
+ vm-reg 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 -- )
: safe-reg ( -- reg ) RAX ;
: stack-reg ( -- reg ) RSP ;
: frame-reg ( -- reg ) RBP ;
-: vm-reg ( -- reg ) R12 ;
-: ctx-reg ( -- reg ) R13 ;
+: ctx-reg ( -- reg ) R12 ;
+: vm-reg ( -- reg ) R13 ;
: ds-reg ( -- reg ) R14 ;
: rs-reg ( -- reg ) R15 ;
: fixnum>slot@ ( -- ) temp0 1 SAR ;
RSP stack-frame-size 3 bootstrap-cells - SUB
] jit-prolog jit-define
-: jit-load-vm ( -- )
- vm-reg 0 MOV 0 rc-absolute-cell jit-vm ;
-
: jit-load-context ( -- )
- ! VM pointer must be in vm-reg already
ctx-reg vm-reg vm-context-offset [+] MOV ;
: jit-save-context ( -- )
rs-reg ctx-reg context-retainstack-offset [+] MOV ;
[
- jit-load-vm
jit-save-context
! call the primitive
arg1 vm-reg MOV
] jit-primitive jit-define
[
- jit-load-vm
jit-restore-context
! save ctx->callstack_bottom
safe-reg stack-reg stack-frame-size 8 - [+] LEA
ctx-reg context-callstack-bottom-offset [+] safe-reg MOV
! call the quotation
arg1 quot-xt-offset [+] CALL
- jit-load-vm
jit-save-context
] \ c-to-factor define-sub-primitive
RSP arg2 MOV
! Load ds and rs registers
- jit-load-vm
jit-restore-context
! Call quotation
arg4 ds-reg [] MOV
ds-reg bootstrap-cell SUB
! Get ctx->callstack_bottom
- jit-load-vm
jit-load-context
arg1 ctx-reg context-callstack-bottom-offset [+] MOV
! Get top of callstack object -- 'src' for memcpy
] \ set-callstack define-sub-primitive
[
- jit-load-vm
jit-save-context
arg2 vm-reg MOV
safe-reg 0 MOV "lazy_jit_compile" f rc-absolute-cell jit-dlsym
! 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 vm-reg MOV
! Overflowing fixnum arithmetic
: jit-overflow ( insn func -- )
ds-reg 8 SUB
- jit-load-vm
jit-save-context
arg1 ds-reg [] MOV
arg2 ds-reg 8 [+] MOV
[
ds-reg 8 SUB
- jit-load-vm
jit-save-context
RCX ds-reg [] MOV
RBX ds-reg 8 [+] MOV
-! Copyright (C) 2007, 2009 Slava Pestov.
+! Copyright (C) 2007, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: bootstrap.image.private compiler.constants
compiler.units cpu.x86.assembler cpu.x86.assembler.operands
! hurt on other platforms
stack-reg 32 SUB
+ ! Load VM into vm-reg
+ vm-reg 0 MOV rc-absolute-cell rt-vm jit-rel
+
! Call into Factor code
safe-reg 0 MOV rc-absolute-cell rt-xt jit-rel
safe-reg CALL
-! Copyright (C) 2005, 2009 Slava Pestov.
+! Copyright (C) 2005, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs alien alien.c-types arrays strings
cpu.x86.assembler cpu.x86.assembler.private cpu.x86.assembler.operands
M: x86 %shr int-rep two-operand [ SHR ] emit-shift ;
M: x86 %sar int-rep two-operand [ SAR ] emit-shift ;
-: %mov-vm-ptr ( reg -- )
- 0 MOV 0 rc-absolute-cell rel-vm ;
-
-M: x86 %vm-field-ptr ( dst field -- )
- [ 0 MOV ] dip vm-field-offset rc-absolute-cell rel-vm ;
+HOOK: %mov-vm-ptr cpu ( reg -- )
: load-allot-ptr ( nursery-ptr allot-ptr -- )
[ drop "nursery" %vm-field-ptr ] [ swap [] MOV ] 2bi ;
callbacks = new callback_heap(size,this);
}
-void callback_heap::update(code_block *stub)
+void callback_heap::store_callback_operand(code_block *stub, cell index, cell value)
{
tagged<array> code_template(parent->special_objects[CALLBACK_STUB]);
- cell rel_class = untag_fixnum(array_nth(code_template.untagged(),1));
- cell rel_type = untag_fixnum(array_nth(code_template.untagged(),2));
- cell offset = untag_fixnum(array_nth(code_template.untagged(),3));
+ cell rel_class = untag_fixnum(array_nth(code_template.untagged(),3 * index + 1));
+ cell rel_type = untag_fixnum(array_nth(code_template.untagged(),3 * index + 2));
+ cell offset = untag_fixnum(array_nth(code_template.untagged(),3 * index + 3));
relocation_entry rel(
(relocation_type)rel_type,
offset);
instruction_operand op(rel,stub,0);
- op.store_value((cell)callback_xt(stub));
+ op.store_value(value);
+}
+void callback_heap::update(code_block *stub)
+{
+ store_callback_operand(stub,1,(cell)callback_xt(stub));
stub->flush_icache();
}
memcpy(stub->xt(),insns->data<void>(),size);
+ /* Store VM pointer */
+ store_callback_operand(stub,0,(cell)parent);
+
/* On x86, the RET instruction takes an argument which depends on
the callback's calling convention */
- if(array_capacity(code_template.untagged()) == 7)
- {
- cell rel_class = untag_fixnum(array_nth(code_template.untagged(),4));
- cell rel_type = untag_fixnum(array_nth(code_template.untagged(),5));
- cell offset = untag_fixnum(array_nth(code_template.untagged(),6));
-
- relocation_entry rel(
- (relocation_type)rel_type,
- (relocation_class)rel_class,
- offset);
-
- instruction_operand op(rel,stub,0);
- op.store_value(return_rewind);
- }
+#if defined(FACTOR_X86) || defined(FACTOR_AMD64)
+ store_callback_operand(stub,2,return_rewind);
+#endif
update(stub);
return w->xt;
}
+ void store_callback_operand(code_block *stub, cell index, cell value);
+
void update(code_block *stub);
+
code_block *add(cell owner, cell return_rewind);
void update();
/* Primitive calls */
if(primitive_call_p(i,length))
{
- /* On PowerPC, the VM pointer is stored as a register; on other
- platforms, the RT_VM relocation is used and it needs an offset
- parameter */
-#ifndef FACTOR_PPC
+ /* On x86-64 and PowerPC, the VM pointer is stored in
+ a register; on other platforms, the RT_VM relocation
+ is used and it needs an offset parameter */
+#ifdef FACTOR_X86
parameter(tag_fixnum(0));
#endif
parameter(obj.value());