factor/library/compiler/intrinsics.factor

243 lines
5.2 KiB
Factor
Raw Normal View History

2005-05-06 18:33:40 -04:00
! Copyright (C) 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
2005-05-09 02:34:15 -04:00
IN: compiler-frontend
USING: assembler compiler-backend generic hashtables inference
kernel kernel-internals lists math math-internals namespaces
sequences vectors words ;
2005-05-06 18:33:40 -04:00
: node-peek ( node -- value ) node-in-d peek ;
2005-08-19 21:46:12 -04:00
: type-tag ( type -- tag )
#! Given a type number, return the tag number.
dup 6 > [ drop 3 ] when ;
: value-tag ( value node -- n/f )
#! If the tag is known, output it, otherwise f.
node-classes hash dup [
2005-09-03 17:00:49 -04:00
types [ type-tag ] map dup [ = ] monotonic?
[ first ] [ drop f ] ifte
] [
drop f
] ifte ;
2005-05-06 18:33:40 -04:00
: slot@ ( node -- n/f )
2005-05-06 18:33:40 -04:00
#! Compute slot offset.
dup node-in-d reverse dup first dup literal? [
literal-value cell * swap second
rot value-tag dup [ - ] [ 2drop f ] ifte
] [
3drop f
] ifte ;
2005-05-09 22:34:47 -04:00
2005-05-06 18:33:40 -04:00
\ slot [
dup slot@ [
2005-09-04 17:07:59 -04:00
-1 %inc-d,
2005-05-06 18:33:40 -04:00
in-1
0 swap slot@ %fast-slot ,
] [
drop
in-2
2005-09-04 17:07:59 -04:00
-1 %inc-d,
0 %untag ,
2005-05-06 18:33:40 -04:00
1 0 %slot ,
] ifte out-1
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ set-slot [
dup slot@ [
2005-09-04 17:07:59 -04:00
-1 %inc-d,
in-2
2005-09-04 17:07:59 -04:00
-2 %inc-d,
slot@ >r 0 1 r> %fast-set-slot ,
] [
drop
in-3
2005-09-04 17:07:59 -04:00
-3 %inc-d,
1 %untag ,
0 1 2 %set-slot ,
] ifte
1 %write-barrier ,
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ type [
drop
in-1
0 %type ,
0 %retag-fixnum ,
out-1
] "intrinsic" set-word-prop
\ tag [
drop
in-1
0 %tag ,
0 %retag-fixnum ,
out-1
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ getenv [
2005-09-04 17:07:59 -04:00
-1 %inc-d,
node-peek literal-value 0 <vreg> swap %getenv ,
2005-09-04 17:07:59 -04:00
1 %inc-d,
out-1
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ setenv [
2005-09-04 17:07:59 -04:00
-1 %inc-d,
in-1
node-peek literal-value 0 <vreg> swap %setenv ,
2005-09-04 17:07:59 -04:00
-1 %inc-d,
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
2005-06-07 23:29:47 -04:00
: value/vreg-list ( in -- list )
[ 0 swap length 1 - ] keep
[ >r 2dup r> 3vector >r 1 - >r 1 + r> r> ] map 2nip ;
2005-06-07 23:29:47 -04:00
: values>vregs ( in -- in )
value/vreg-list
dup [ first3 load-value ] each
[ first <vreg> ] map ;
2005-06-07 23:29:47 -04:00
: load-inputs ( node -- in )
dup node-in-d values>vregs
2005-09-04 17:07:59 -04:00
[ >r node-out-d length r> length - %inc-d, ] keep ;
2005-06-07 23:29:47 -04:00
: binary-op-reg ( node op -- )
>r load-inputs first2 swap dup r> execute ,
2005-06-07 23:29:47 -04:00
0 0 %replace-d , ; inline
2005-08-29 18:18:10 -04:00
: literal-immediate? ( value -- ? )
dup literal? [ literal-value immediate? ] [ drop f ] ifte ;
2005-05-15 21:17:56 -04:00
2005-06-07 23:29:47 -04:00
: binary-op-imm ( imm op -- )
2005-09-04 17:07:59 -04:00
-1 %inc-d, in-1
2005-06-07 23:29:47 -04:00
>r 0 <vreg> dup r> execute ,
0 0 %replace-d , ; inline
2005-06-07 03:44:34 -04:00
2005-06-07 23:29:47 -04:00
: binary-op ( node op -- )
#! out is a vreg where the vop stores the result.
2005-06-07 03:44:34 -04:00
fixnum-imm? [
2005-08-29 18:18:10 -04:00
>r dup node-peek dup literal-immediate? [
2005-06-07 23:29:47 -04:00
literal-value r> binary-op-imm drop
2005-06-07 03:44:34 -04:00
] [
2005-06-07 23:29:47 -04:00
drop r> binary-op-reg
2005-06-07 03:44:34 -04:00
] ifte
] [
2005-06-07 23:29:47 -04:00
binary-op-reg
] ifte ;
[
[[ fixnum+ %fixnum+ ]]
[[ fixnum- %fixnum- ]]
[[ fixnum-bitand %fixnum-bitand ]]
[[ fixnum-bitor %fixnum-bitor ]]
[[ fixnum-bitxor %fixnum-bitxor ]]
[[ fixnum<= %fixnum<= ]]
[[ fixnum< %fixnum< ]]
[[ fixnum>= %fixnum>= ]]
[[ fixnum> %fixnum> ]]
2005-05-09 02:34:15 -04:00
[[ eq? %eq? ]]
] [
2005-08-25 15:27:38 -04:00
uncons [ literalize , \ binary-op , ] [ ] make
2005-05-17 16:13:08 -04:00
"intrinsic" set-word-prop
] each
2005-06-07 23:29:47 -04:00
: fast-fixnum* ( n -- )
2005-09-04 17:07:59 -04:00
-1 %inc-d,
2005-06-07 23:29:47 -04:00
in-1
log2 0 <vreg> 0 <vreg> %fixnum<< ,
0 0 %replace-d , ;
: slow-fixnum* ( node -- ) \ %fixnum* binary-op-reg ;
2005-05-09 23:25:46 -04:00
\ fixnum* [
2005-05-09 22:34:47 -04:00
! Turn multiplication by a power of two into a left shift.
2005-08-30 03:31:20 -04:00
dup node-peek dup literal-immediate? [
2005-05-09 22:34:47 -04:00
literal-value dup power-of-2? [
2005-06-07 23:29:47 -04:00
nip fast-fixnum*
2005-05-09 22:34:47 -04:00
] [
2005-05-09 23:25:46 -04:00
drop slow-fixnum*
2005-05-09 22:34:47 -04:00
] ifte
] [
2005-05-09 23:25:46 -04:00
drop slow-fixnum*
2005-05-09 22:34:47 -04:00
] ifte
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ fixnum-mod [
! This is not clever. Because of x86, %fixnum-mod is
! hard-coded to put its output in vreg 2, which happends to
! be EDX there.
drop
in-2
2005-09-04 17:07:59 -04:00
-1 %inc-d,
1 <vreg> 0 <vreg> 2 <vreg> %fixnum-mod ,
2 0 %replace-d ,
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
2005-05-16 01:15:48 -04:00
\ fixnum/i t "intrinsic" set-word-prop
\ fixnum/i [
2005-06-07 23:29:47 -04:00
\ %fixnum/i binary-op-reg
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ fixnum/mod [
! See the remark on fixnum-mod for vreg usage
drop
in-2
[ << vreg f 1 >> << vreg f 0 >> ]
[ << vreg f 2 >> << vreg f 0 >> ]
%fixnum/mod ,
2 0 %replace-d ,
0 1 %replace-d ,
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ fixnum-bitnot [
drop
in-1
2005-06-05 02:43:05 -04:00
0 <vreg> 0 <vreg> %fixnum-bitnot ,
out-1
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
2005-05-09 22:34:47 -04:00
: slow-shift ( -- ) \ fixnum-shift %call , ;
: negative-shift ( n -- )
2005-09-04 17:07:59 -04:00
-1 %inc-d,
2005-05-09 22:34:47 -04:00
in-1
dup cell -8 * <= [
2005-06-05 02:43:05 -04:00
drop 0 <vreg> 2 <vreg> %fixnum-sgn ,
2005-05-09 22:34:47 -04:00
2 0 %replace-d ,
] [
neg 0 <vreg> 0 <vreg> %fixnum>> ,
2005-05-09 22:34:47 -04:00
out-1
] ifte ;
: positive-shift ( n -- )
dup cell 8 * tag-bits - <= [
2005-09-04 17:07:59 -04:00
-1 %inc-d,
2005-05-09 22:34:47 -04:00
in-1
0 <vreg> 0 <vreg> %fixnum<< ,
2005-05-09 22:34:47 -04:00
out-1
] [
drop slow-shift
] ifte ;
: fast-shift ( n -- )
dup 0 = [
2005-09-04 17:07:59 -04:00
-1 %inc-d,
2005-05-09 22:34:47 -04:00
drop
] [
dup 0 < [
negative-shift
] [
positive-shift
] ifte
] ifte ;
\ fixnum-shift [
node-peek dup literal? [
literal-value fast-shift
] [
drop slow-shift
] ifte
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop