should fix in 0.82:
- another i/o bug: on factorcode eventually all i/o times out
-- update amd64 backend
-- when generating a 32-bit image on a 64-bit system, large numbers which should
- be bignums become fixnums
- get factor running on mac intel
+ io:
: align-here ( -- )
here 8 mod 4 = [ 0 emit ] when ;
-( Fixnums )
-
: emit-fixnum ( n -- ) fixnum-tag tag-address emit ;
-M: fixnum ' ( n -- tagged ) fixnum-tag tag-address ;
-
( Bignums )
: bignum-bits bootstrap-cell-bits 2 - ;
bignum-tag tag-header emit
emit-bignum align-here r> ;
+( Fixnums )
+
+M: fixnum ' ( n -- tagged )
+ #! When generating a 32-bit image on a 64-bit system,
+ #! some fixnums should be bignums.
+ dup most-negative-fixnum most-positive-fixnum between? [
+ fixnum-tag tag-address
+ ] [
+ >bignum '
+ ] if ;
+
( Floats )
M: float ' ( float -- tagged )
M: stack-params %freg>stack
>r stack-increment + cell + swap r> %stack>freg ;
-: %unbox-struct ( n reg-class size -- )
- nip
+: struct-ptr/size ( n reg-class size func -- )
+ rot drop
! Load destination address
- RDI RSP MOV
+ >r RDI RSP MOV
RDI rot ADD
! Load struct size
RSI swap MOV
! Copy the struct to the stack
- "unbox_value_struct" f compile-c-call ;
+ r> f compile-c-call ;
+
+: %unbox-struct ( n reg-class size -- )
+ "unbox_value_struct" struct-ptr/size ;
: %unbox ( n reg-class func -- )
! Call the unboxer
! Store the return value on the C stack
[ return-reg ] keep %freg>stack ;
+: %box-struct ( n reg-class size -- )
+ "box_value_struct" struct-ptr/size ;
+
: load-return-value ( reg-class -- )
dup fastcall-regs first swap return-reg
2dup eq? [ 2drop ] [ MOV ] if ;
: %box ( n reg-class func -- )
rot [
- swap [ fastcall-regs first ] keep %stack>freg
+ rot [ fastcall-regs first ] keep %stack>freg
] [
- load-return-value
+ swap load-return-value
] if*
f compile-c-call ;
reset-sse compile-c-call ;
: %alien-callback ( quot -- )
- RDI swap load-literal "run_callback" f compile-c-call ;
+ RDI load-indirect "run_callback" f compile-c-call ;
: save-return 0 swap [ return-reg ] keep %freg>stack ;
: load-return 0 swap [ return-reg ] keep %stack>freg ;
"unnest_stacks" f compile-c-call
! Restore return register
load-return ;
+
+: %cleanup ( n -- ) drop ;
: ds-reg R14 ; inline
: cs-reg R15 ; inline
: remainder-reg RDX ; inline
+: alloc-tmp-reg RBX ; inline
M: int-regs return-reg drop RAX ;
M: int-regs vregs drop { RAX RCX RDX RSI RDI R8 R9 R10 R11 } ;
R11 [ swap MOV ] keep ; inline
: compile-c-call ( symbol dll -- )
- 2dup dlsym address-operand rel-absolute-cell rel-dlsym CALL ;
+ 2dup dlsym address-operand
+ >r rel-absolute-cell rel-dlsym r> CALL ;
: compile-c-call* ( symbol dll args -- )
T{ int-regs } fastcall-regs
: prepare-division CQO ; inline
+: load-indirect ( vreg literal -- )
+ swap add-literal from 3 - [] MOV ;
+
M: object load-literal ( literal vreg -- )
#! We use RIP-relative addressing. The '3' is a hardcoded
#! instruction length.
- v>operand swap add-literal from 3 - [] MOV ;
+ v>operand load-indirect ;
: stack-increment \ stack-reserve get 16 align 8 + ;
! Copyright (C) 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-IN: compiler
USING: assembler ;
+IN: compiler
: generate-write-barrier ( -- )
#! Mark the card pointed to by vreg.
: ds-reg ESI ; inline
: cs-reg EBX ; inline
: remainder-reg EDX ; inline
+: alloc-tmp-reg EDI ; inline
: reg-stack ( n reg -- op ) swap cells neg [+] ;
: load-zone-ptr ( vreg -- )
#! Load pointer to start of zone array
- "generations" f [ dlsym [] MOV ] 2keep
- rel-absolute rel-dlsym ;
+ dup "generations" f [ dlsym MOV ] 2keep
+ rel-absolute-cell rel-dlsym
+ dup [] MOV ;
: load-allot-ptr ( vreg -- )
dup load-zone-ptr dup cell [+] MOV ;
: with-inline-alloc ( prequot postquot spec -- )
#! both quotations are called with the vreg
[
- EBX PUSH
- EBX load-allot-ptr
- EBX [] \ tag-header get call tag-header MOV
- >r call EBX \ tag get call OR
- r> call EBX \ size get call inc-allot-ptr
- EBX POP
+ alloc-tmp-reg PUSH
+ alloc-tmp-reg load-allot-ptr
+ alloc-tmp-reg [] \ tag-header get call tag-header MOV
+ >r call alloc-tmp-reg \ tag get call OR
+ r> call alloc-tmp-reg \ size get call inc-allot-ptr
+ alloc-tmp-reg POP
] bind ; inline
M: float-regs (%replace) ( vreg loc reg-class -- )
drop
- [ EBX 8 [+] rot v>operand MOVSD ]
- [ v>operand EBX MOV ] H{
+ [ alloc-tmp-reg 8 [+] rot v>operand MOVSD ]
+ [ v>operand alloc-tmp-reg MOV ] H{
{ tag-header [ float-tag ] }
{ tag [ float-tag ] }
{ size [ 16 ] }
} define-intrinsic
: define-fixnum-jump ( word op -- )
- [
- [ end-basic-block "x" operand "y" operand CMP ] % ,
- ] [ ] make H{
- { +input { { f "x" } { f "y" } } }
- } define-if-intrinsic ;
+ [ end-basic-block "x" operand "y" operand CMP ] swap add
+ H{ { +input { { f "x" } { f "y" } } } } define-if-intrinsic ;
{
{ fixnum< JL }
: %userenv ( -- )
"x" operand "userenv" f dlsym MOV
0 rel-absolute-cell rel-userenv
- "n" operand 1 SHR
+ "n" operand fixnum>slot@
"n" operand "x" operand ADD ;
\ getenv [
: e 2.7182818284590452354 ; inline
: pi 3.14159265358979323846 ; inline
: epsilon 2.2204460492503131e-16 ; inline
-: first-bignum 1 cell-bits tag-bits - 1- shift ; inline
-: most-positive-fixnum first-bignum 1- >fixnum ; inline
-: most-negative-fixnum first-bignum neg >fixnum ; inline
+: first-bignum 1 bootstrap-cell-bits tag-bits - 1- shift ;
+: most-positive-fixnum first-bignum 1- >fixnum ;
+: most-negative-fixnum first-bignum neg >fixnum ;