From a77f48fe6b273b5cfff51f489abf9666d2b0ea8d Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 27 Dec 2009 01:17:42 +1300 Subject: [PATCH] Updating x86-64 port for global register variable removal --- basis/cpu/x86/64/64.factor | 18 +++-- basis/cpu/x86/64/bootstrap.factor | 90 ++++++++++++++------- vm/cpu-x86.64.S | 127 +++++++++++++++++++----------- 3 files changed, 157 insertions(+), 78 deletions(-) diff --git a/basis/cpu/x86/64/64.factor b/basis/cpu/x86/64/64.factor index 06a348b4e6..f78fe366d9 100644 --- a/basis/cpu/x86/64/64.factor +++ b/basis/cpu/x86/64/64.factor @@ -77,9 +77,9 @@ M: stack-params copy-register* { [ 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 -- ) [ @@ -91,6 +91,12 @@ M: x86 %load-param-reg [ swap param@ ] dip %copy ; 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 @@ -206,8 +212,10 @@ M: x86.64 %unnest-stacks ( -- ) "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 ( -- ) @@ -219,7 +227,7 @@ M: x86.64 %alien-callback ( quot -- ) "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 diff --git a/basis/cpu/x86/64/bootstrap.factor b/basis/cpu/x86/64/bootstrap.factor index b77b08abe9..dbc0178ce1 100644 --- a/basis/cpu/x86/64/bootstrap.factor +++ b/basis/cpu/x86/64/bootstrap.factor @@ -1,9 +1,9 @@ ! 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 @@ -33,23 +33,52 @@ IN: bootstrap.x86 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 ; @@ -57,10 +86,13 @@ IN: bootstrap.x86 ! 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 ] @@ -74,17 +106,19 @@ IN: bootstrap.x86 ! 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 @@ -93,11 +127,12 @@ IN: bootstrap.x86 [ [ 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 @@ -106,8 +141,9 @@ IN: bootstrap.x86 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 diff --git a/vm/cpu-x86.64.S b/vm/cpu-x86.64.S index e8972b533c..37a6507206 100644 --- a/vm/cpu-x86.64.S +++ b/vm/cpu-x86.64.S @@ -1,15 +1,10 @@ #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 @@ -63,82 +58,122 @@ #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