factor/core/compiler/x86/allot.factor

104 lines
3.1 KiB
Factor
Raw Normal View History

2006-11-07 00:35:06 -05:00
! Copyright (C) 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
IN: compiler
USING: kernel assembler kernel-internals namespaces math ;
2006-11-09 01:27:26 -05:00
: load-zone-ptr ( -- )
2006-11-07 00:35:06 -05:00
#! Load pointer to start of zone array
2006-11-07 16:00:53 -05:00
allot-tmp-reg 0 MOV
2006-11-07 00:35:06 -05:00
"generations" f rel-absolute-cell rel-dlsym
2006-11-07 16:00:53 -05:00
allot-tmp-reg allot-tmp-reg [] MOV ;
2006-11-07 00:35:06 -05:00
2006-11-07 16:00:53 -05:00
: load-allot-ptr ( -- )
load-zone-ptr
allot-tmp-reg allot-tmp-reg cell [+] MOV ;
2006-11-07 00:35:06 -05:00
2006-11-07 16:00:53 -05:00
: inc-allot-ptr ( n -- )
load-zone-ptr
allot-tmp-reg cell [+] swap 8 align ADD ;
: store-header ( header -- )
allot-tmp-reg [] swap tag-header MOV ;
2006-11-07 00:35:06 -05:00
: %allot ( header size quot -- )
2006-11-09 00:15:02 -05:00
dup maybe-gc
2006-11-07 00:35:06 -05:00
swap >r >r
2006-11-07 16:00:53 -05:00
allot-tmp-reg PUSH
load-allot-ptr
store-header
2006-11-07 00:35:06 -05:00
r> call
2006-11-07 16:00:53 -05:00
r> inc-allot-ptr
allot-tmp-reg POP ; inline
2006-11-07 00:35:06 -05:00
: %allot-float ( loc vreg -- )
2006-11-07 16:00:53 -05:00
#! Only called by pentium4 backend, uses SSE2 instruction
2006-11-07 00:35:06 -05:00
float-tag 16 [
2006-11-09 00:25:15 -05:00
allot-tmp-reg 8 [+] swap v>operand MOVSD
2006-11-07 16:00:53 -05:00
allot-tmp-reg float-tag OR
v>operand allot-tmp-reg MOV
2006-11-07 00:35:06 -05:00
] %allot ;
: %allot-bignum ( #digits quot -- )
#! 1 cell header, 1 cell length, 1 cell sign, + digits
#! length is the # of digits + sign
bignum-tag pick 3 + cells [
2006-11-07 16:00:53 -05:00
! Write length
>r allot-tmp-reg cell [+] swap 1+ tag-bits shift MOV r>
! Call quot
2006-11-07 00:35:06 -05:00
call
] %allot ; inline
2006-11-07 16:00:53 -05:00
: %allot-bignum-signed-1 ( outreg inreg -- )
#! on entry, inreg is a signed 32-bit quantity
#! exits with tagged ptr to bignum in outreg
2006-11-07 00:35:06 -05:00
[
2006-11-07 16:00:53 -05:00
"positive" define-label
"end" define-label
2006-11-07 00:35:06 -05:00
1 [
2006-11-07 16:00:53 -05:00
dup 0 CMP
"positive" get JGE
allot-tmp-reg 2 cells [+] 1 MOV ! negative sign
dup NEG
"end" get JMP
"positive" resolve-label
allot-tmp-reg 2 cells [+] 0 MOV ! positive sign
"end" resolve-label
allot-tmp-reg 3 cells [+] swap MOV
allot-tmp-reg bignum-tag OR
allot-tmp-reg MOV
2006-11-07 00:35:06 -05:00
] %allot-bignum
] with-scope ;
2006-11-08 23:44:05 -05:00
: bignum-radix-mask 1 cell 2 - shift 1- ;
2006-11-07 00:35:06 -05:00
: %allot-bignum-signed-2 ( reg1 reg2 -- )
2006-11-08 23:44:05 -05:00
#! this word has some hairy restrictions; its really only
#! intended to be used by fixnum*.
#! - reg1 and reg2 together form a 60-bit signed quantity
#! (product of two 29-bit fixnums cannot exceed this)
#! - the quantity must be non-zero
#! (if the product of two fixnums is zero, there's no
#! overflow so this word won't be called in that case)
2006-11-07 00:35:06 -05:00
#! exits with tagged ptr to bignum in reg1
[
2006-11-08 23:44:05 -05:00
"positive" define-label
"end" define-label
2006-11-07 00:35:06 -05:00
2 [
2006-11-08 23:44:05 -05:00
0 pick CMP
"positive" get JGE
allot-tmp-reg 2 cells [+] 1 MOV
over NOT
2006-11-09 01:39:00 -05:00
dup -1 IMUL2
2006-11-08 23:44:05 -05:00
"end" get JMP
"positive" resolve-label
allot-tmp-reg 2 cells [+] 0 MOV
"end" resolve-label
dup bignum-radix-mask AND
2006-11-07 16:00:53 -05:00
allot-tmp-reg 3 cells [+] swap MOV
2006-11-08 23:44:05 -05:00
dup bignum-radix-mask AND
2006-11-07 16:00:53 -05:00
allot-tmp-reg 4 cells [+] over MOV
allot-tmp-reg bignum-tag OR
allot-tmp-reg MOV
2006-11-07 00:35:06 -05:00
] %allot-bignum
] with-scope ;