[ align-code ]
bi ;
-! Registers for fastcall
-: param-reg-1 ( -- reg ) EAX ;
-: param-reg-2 ( -- reg ) EDX ;
-
M: x86.32 pic-tail-reg EBX ;
M: x86.32 reserved-stack-space 4 cells ;
M: x86.32 %alien-callback ( quot -- )
EAX swap %load-reference
- EDX %mov-vm-ptr
+ 0 stack@ EAX MOV
+ 4 save-vm-ptr
"c_to_factor" f %alien-invoke ;
M: x86.32 %callback-value ( ctype -- )
! Copyright (C) 2007, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: bootstrap.image.private kernel namespaces system
-cpu.x86.assembler cpu.x86.assembler.operands layouts
+USING: bootstrap.image.private kernel kernel.private namespaces
+system cpu.x86.assembler cpu.x86.assembler.operands layouts
vocabs parser compiler.constants sequences math math.private
generic.single.private ;
IN: bootstrap.x86
: shift-arg ( -- reg ) ECX ;
: div-arg ( -- reg ) EAX ;
: mod-arg ( -- reg ) EDX ;
-: arg1 ( -- reg ) EAX ;
-: arg2 ( -- reg ) EDX ;
: temp0 ( -- reg ) EAX ;
: temp1 ( -- reg ) EDX ;
: temp2 ( -- reg ) ECX ;
jit-restore-context
] jit-primitive jit-define
+[
+ ! load from stack
+ EAX ds-reg [] MOV
+ ! pop stack
+ ds-reg bootstrap-cell SUB
+ ! load VM pointer
+ EDX 0 MOV 0 rc-absolute-cell jit-vm
+]
+[
+
+ ! pass quotation
+ ESP [] EAX MOV
+ ! pass VM pointer
+ ESP 4 [+] EDX MOV
+ ! call XT
+ EAX quot-xt-offset [+] CALL
+]
+[
+ ! pass quotation
+ ESP 4 [+] EAX MOV
+ ! pass VM pointer
+ ESP 8 [+] EDX MOV
+ ! jump to XT
+ EAX quot-xt-offset [+] JMP
+]
+\ (call) define-sub-primitive*
+
! Inline cache miss entry points
: jit-load-return-address ( -- )
EBX ESP stack-frame-size bootstrap-cell - [+] MOV ;
ds-reg [] ECX MOV
[ JNO ]
[
- ECX EBP MOV
+ ESP [] EAX MOV
+ ESP 4 [+] EDX MOV
+ ESP 8 [+] EBP MOV
[ 0 CALL ] dip f rc-relative jit-dlsym
]
jit-conditional ;
ds-reg [] EAX MOV
[ JNO ]
[
- EAX ECX MOV
- EAX tag-bits get SAR
- EDX EBX MOV
- ECX EBP MOV
+ ECX tag-bits get SAR
+ ESP [] ECX MOV
+ ESP 4 [+] EBX MOV
+ ESP 8 [+] EBP MOV
0 CALL "overflow_fixnum_multiply" f rc-relative jit-dlsym
]
jit-conditional
[
! load from stack
- arg1 ds-reg [] MOV
- ! pop stack
- ds-reg bootstrap-cell SUB
- ! pass 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*
-
-[
- ! load from stack
- arg1 ds-reg [] MOV
+ temp0 ds-reg [] MOV
! pop stack
ds-reg bootstrap-cell SUB
]
-[ arg1 word-xt-offset [+] CALL ]
-[ arg1 word-xt-offset [+] JMP ]
+[ temp0 word-xt-offset [+] CALL ]
+[ temp0 word-xt-offset [+] JMP ]
\ (execute) define-sub-primitive*
[
- arg1 ds-reg [] MOV
+ temp0 ds-reg [] MOV
ds-reg bootstrap-cell SUB
- arg1 word-xt-offset [+] JMP
+ temp0 word-xt-offset [+] JMP
] jit-execute jit-define
[
if(q->code)
parent->set_quot_xt(q,visitor(q->code));
else
- q->xt = (void *)lazy_jit_compile;
+ q->xt = (void *)lazy_jit_compile_impl;
break;
}
case CALLSTACK_TYPE:
mtlr r0
JUMP_QUOT /* call the quotation */
-DEF(void,lazy_jit_compile,(cell quot, void *vm)):
+DEF(void,lazy_jit_compile_impl,(cell quot, void *vm)):
mr r5,r4 /* vm ptr is 3rd arg */
mr r4,r1 /* save stack pointer */
PROLOGUE
- bl MANGLE(lazy_jit_compile_impl)
+ bl MANGLE(lazy_jit_compile)
EPILOGUE
JUMP_QUOT /* call the quotation */
{
#define FACTOR_CPU_STRING "ppc"
-#define VM_ASM_API VM_C_API
/* In the instruction sequence:
/* Defined in assembly */
VM_C_API void c_to_factor(cell quot, void *vm);
VM_C_API void throw_impl(cell quot, void *new_stack, void *vm);
-VM_C_API void lazy_jit_compile(cell quot, void *vm);
+VM_C_API void lazy_jit_compile_impl(cell quot, void *vm);
VM_C_API void flush_icache(cell start, cell len);
VM_C_API void set_callstack(
#include "asm.h"
-#define ARG0 %eax
-#define ARG1 %edx
-#define ARG2 %ecx
-#define STACK_REG %esp
#define DS_REG %esi
#define RS_REG %edi
#define RETURN_REG %eax
-#define NV0 %ebx
-#define NV1 %ebp
+#define QUOT_XT_OFFSET 12
-#define CELL_SIZE 4
-#define STACK_PADDING 12
+DEF(void,c_to_factor,(cell quot, void *vm)):
+ /* Load parameters */
+ mov 4(%esp),%eax
+ mov 8(%esp),%edx
-#define PUSH_NONVOLATILE \
- push %ebx ; \
- push %ebp ; \
- push %esi ; \
+ /* Save non-volatile registers */
+ push %ebx
+ push %ebp
+ push %esi
push %edi
-#define POP_NONVOLATILE \
- pop %edi ; \
- pop %esi ; \
- pop %ebp ; \
+ /* Save old stack pointer and align */
+ mov %esp,%ebp
+ and $-16,%esp
+ push %ebp
+
+ /* Set up stack frame for the call to the boot quotation */
+ sub $4,%esp
+ push %edx
+ push %eax
+
+ /* Load context */
+ mov (%edx),%ecx
+
+ /* Load ctx->datastack */
+ mov 8(%ecx),DS_REG
+
+ /* Load ctx->retainstack */
+ mov 12(%ecx),RS_REG
+
+ /* Save ctx->callstack_bottom */
+ lea -4(%esp),%ebx
+ mov %ebx,4(%ecx)
+
+ /* Call quot-xt. Parameters are already on the stack */
+ call *QUOT_XT_OFFSET(%eax)
+
+ /* Tear down stack frame for the call to the boot quotation */
+ pop %edx
+ pop %eax
+ add $4,%esp
+
+ /* Undo stack alignment */
+ pop %ebp
+ mov %ebp,%esp
+
+ /* Load context */
+ mov (%edx),%ecx
+
+ /* Save ctx->datastack */
+ mov DS_REG,8(%ecx)
+
+ /* Save ctx->retainstack */
+ mov RS_REG,12(%ecx)
+
+ /* Restore non-volatile registers */
+ pop %edi
+ pop %esi
+ pop %ebp
pop %ebx
-#define QUOT_XT_OFFSET 12
+ ret
DEF(void,set_callstack,(void *vm, stack_frame *to, stack_frame *from, cell length, void *memcpy)):
- mov 4(%esp),%ebx /* vm */
- mov 8(%esp),%ebp /* to */
- mov 12(%esp),%edx /* from */
- mov 16(%esp),%ecx /* length */
- mov 20(%esp),%eax /* memcpy */
- sub %ecx,%ebp /* compute new stack pointer */
+ /* load arguments */
+ mov 4(%esp),%ebx /* vm - to non-volatile register */
+ mov 8(%esp),%ebp /* to */
+ mov 12(%esp),%edx /* from */
+ mov 16(%esp),%ecx /* length */
+ mov 20(%esp),%eax /* memcpy */
+
+ /* compute new stack pointer */
+ sub %ecx,%ebp
mov %ebp,%esp
- push %ecx /* pass length */
- push %edx /* pass src */
- push %ebp /* pass dst */
- call *%eax /* call memcpy */
- add $12,%esp /* pop args from the stack */
- mov (%ebx),%ebx /* load context */
- mov 8(%ebx),DS_REG /* load datastack */
- mov 12(%ebx),RS_REG /* load retainstack */
- ret /* return _with new stack_ */
+
+ /* call memcpy */
+ push %ecx /* pass length */
+ push %edx /* pass src */
+ push %ebp /* pass dst */
+ call *%eax
+ add $12,%esp
+
+ /* load context */
+ mov (%ebx),%ecx
+ /* load datastack */
+ mov 8(%ecx),DS_REG
+ /* load retainstack */
+ mov 12(%ecx),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 */
fninit
fldcw (%esp)
add $2,%esp
+
/* load quotation and vm parameters */
mov 4(%esp),%eax
mov 12(%esp),%edx
+
/* load new stack pointer */
mov 8(%esp),%esp
+
/* load context */
- mov (%edx),%ebx
+ mov (%edx),%ecx
/* load datastack */
- mov 8(%ebx),DS_REG
+ mov 8(%ecx),DS_REG
/* load retainstack */
- mov 12(%ebx),RS_REG
+ mov 12(%ecx),RS_REG
+
+ /* pass arguments to error handler */
+ mov %eax,4(%esp)
+ mov %edx,8(%esp)
+
/* call the error handler */
jmp *QUOT_XT_OFFSET(%eax)
-DEF(VM_ASM_API void,lazy_jit_compile,(cell quot, void *vm)):
+DEF(void,lazy_jit_compile_impl,(cell quot, void *vm)):
+ /* load arguments */
+ mov 4(%esp),%eax
+ mov 8(%esp),%edx
+
/* load context */
- mov (ARG1),%ebx
- /* save callstack */
- lea -4(%esp),%ebp
- mov %ebp,(%ebx)
+ mov (%edx),%ecx
/* save datastack */
- mov DS_REG,8(%ebx)
+ mov DS_REG,8(%ecx)
/* save retainstack */
- mov RS_REG,12(%ebx)
+ mov RS_REG,12(%ecx)
+ /* save callstack */
+ lea -4(%esp),%ebp
+ mov %ebp,(%ecx)
+
/* compile quotation */
sub $4,%esp
- push ARG1
- push ARG0
- call MANGLE(lazy_jit_compile_impl)
+ push %edx
+ push %eax
+ call MANGLE(lazy_jit_compile)
add $12,%esp
+
/* call quotation */
jmp *QUOT_XT_OFFSET(%eax)
{
#define FACTOR_CPU_STRING "x86.32"
-#define VM_ASM_API VM_C_API __attribute__ ((regparm (3)))
}
#define QUOT_XT_OFFSET 28
+DEF(F_FASTCALL void,c_to_factor,(CELL quot, void *vm)):
+ PUSH_NONVOLATILE
+ mov ARG0,NV0
+ mov ARG1,NV1
+
+ push ARG0
+ push ARG1
+
+ /* Create register shadow area (required for Win64 only) */
+ sub $32,STACK_REG
+
+ /* Load context */
+ mov (NV1),ARG0
+
+ /* Save ctx->callstack_bottom */
+ lea -CELL_SIZE(STACK_REG),ARG1
+ mov ARG1,CELL_SIZE(ARG0)
+
+ /* Load ctx->datastack */
+ mov (CELL_SIZE * 2)(ARG0),DS_REG
+
+ /* Load ctx->retainstack */
+ mov (CELL_SIZE * 3)(ARG0),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
+
+ /* Load context */
+ pop ARG1
+ pop ARG0
+ mov (ARG1),ARG0
+
+ /* Save ctx->datastack */
+ mov DS_REG,(CELL_SIZE * 2)(ARG0)
+
+ /* Save ctx->retainstack */
+ mov RS_REG,(CELL_SIZE * 3)(ARG0)
+
+ 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 */
fldcw (STACK_REG)
/* rewind_to */
mov ARG1,STACK_REG
- mov ARG2,ARG1 /* make vm ptr 2nd arg in case quot_xt = lazy_jit_compile */
+ mov ARG2,ARG1 /* make vm ptr 2nd arg in case quot_xt = lazy_jit_compile_impl */
jmp *QUOT_XT_OFFSET(ARG0)
-DEF(F_FASTCALL void,lazy_jit_compile,(CELL quot, void *vm)):
+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
- call MANGLE(lazy_jit_compile_impl)
+ 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 */
{
#define FACTOR_CPU_STRING "x86.64"
-#define VM_ASM_API VM_C_API
}
-DEF(F_FASTCALL void,c_to_factor,(CELL quot, void *vm)):
- PUSH_NONVOLATILE
- mov ARG0,NV0
- mov ARG1,NV1
-
- push ARG0
- push ARG1
-
- /* Save old stack pointer and align */
- mov STACK_REG,ARG0
- and $-16,STACK_REG
- add $CELL_SIZE,STACK_REG
- push ARG0
-
- /* Create register shadow area (required for Win64 only) */
- sub $32,STACK_REG
-
- /* Load context */
- mov (NV1),ARG0
-
- /* Save ctx->callstack_bottom */
- lea -CELL_SIZE(STACK_REG),ARG1
- mov ARG1,CELL_SIZE(ARG0)
-
- /* Load ctx->datastack */
- mov (CELL_SIZE * 2)(ARG0),DS_REG
-
- /* Load ctx->retainstack */
- mov (CELL_SIZE * 3)(ARG0),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
-
- /* Undo stack alignment */
- mov (STACK_REG),STACK_REG
-
- /* Load context */
- pop ARG1
- pop ARG0
- mov (ARG1),ARG0
-
- /* Save ctx->datastack */
- mov DS_REG,(CELL_SIZE * 2)(ARG0)
-
- /* Save ctx->retainstack */
- mov RS_REG,(CELL_SIZE * 3)(ARG0)
-
- POP_NONVOLATILE
- ret
-
/* cpu.x86.features calls this */
DEF(bool,sse_version,(void)):
mov $0x1,RETURN_REG
}
/* Defined in assembly */
-VM_ASM_API void c_to_factor(cell quot, void *vm);
+VM_C_API void c_to_factor(cell quot, void *vm);
VM_C_API void throw_impl(cell quot, void *new_stack, void *vm);
-VM_ASM_API void lazy_jit_compile(cell quot, void *vm);
+VM_C_API void lazy_jit_compile_impl(cell quot, void *vm);
VM_C_API void set_callstack(
void *vm,
untag_fixnum(x) + untag_fixnum(y))));
}
-VM_ASM_API void overflow_fixnum_add(fixnum x, fixnum y, factor_vm *parent)
+VM_C_API void overflow_fixnum_add(fixnum x, fixnum y, factor_vm *parent)
{
parent->overflow_fixnum_add(x,y);
}
untag_fixnum(x) - untag_fixnum(y))));
}
-VM_ASM_API void overflow_fixnum_subtract(fixnum x, fixnum y, factor_vm *parent)
+VM_C_API void overflow_fixnum_subtract(fixnum x, fixnum y, factor_vm *parent)
{
parent->overflow_fixnum_subtract(x,y);
}
ctx->replace(tag<bignum>(bignum_multiply(bx,by)));
}
-VM_ASM_API void overflow_fixnum_multiply(fixnum x, fixnum y, factor_vm *parent)
+VM_C_API void overflow_fixnum_multiply(fixnum x, fixnum y, factor_vm *parent)
{
parent->overflow_fixnum_multiply(x,y);
}
VM_C_API fixnum to_fixnum(cell tagged, factor_vm *vm);
VM_C_API cell to_cell(cell tagged, factor_vm *vm);
-VM_ASM_API void overflow_fixnum_add(fixnum x, fixnum y, factor_vm *parent);
-VM_ASM_API void overflow_fixnum_subtract(fixnum x, fixnum y, factor_vm *parent);
-VM_ASM_API void overflow_fixnum_multiply(fixnum x, fixnum y, factor_vm *parent);
+VM_C_API void overflow_fixnum_add(fixnum x, fixnum y, factor_vm *parent);
+VM_C_API void overflow_fixnum_subtract(fixnum x, fixnum y, factor_vm *parent);
+VM_C_API void overflow_fixnum_multiply(fixnum x, fixnum y, factor_vm *parent);
}
quot->array = ctx->peek();
quot->cached_effect = false_object;
quot->cache_counter = false_object;
- quot->xt = (void *)lazy_jit_compile;
+ quot->xt = (void *)lazy_jit_compile_impl;
quot->code = NULL;
ctx->replace(tag<quotation>(quot));
}
return compiler.get_position();
}
-cell factor_vm::lazy_jit_compile_impl(cell quot_)
+cell factor_vm::lazy_jit_compile(cell quot_)
{
data_root<quotation> quot(quot_,this);
jit_compile_quot(quot.value(),true);
return quot.value();
}
-VM_C_API cell lazy_jit_compile_impl(cell quot, factor_vm *parent)
+VM_C_API cell lazy_jit_compile(cell quot, factor_vm *parent)
{
- return parent->lazy_jit_compile_impl(quot);
+ return parent->lazy_jit_compile(quot);
}
void factor_vm::primitive_quot_compiled_p()
void iterate_quotation();
};
-VM_C_API cell lazy_jit_compile_impl(cell quot, factor_vm *parent);
+VM_C_API cell lazy_jit_compile(cell quot, factor_vm *parent);
}
code_block *jit_compile_quot(cell owner_, cell quot_, bool relocating);
void jit_compile_quot(cell quot_, bool relocating);
fixnum quot_code_offset_to_scan(cell quot_, cell offset);
- cell lazy_jit_compile_impl(cell quot);
+ cell lazy_jit_compile(cell quot);
void primitive_quot_compiled_p();
//dispatch