factor/library/compiler/intrinsics.factor

206 lines
4.5 KiB
Factor
Raw Normal View History

2006-04-01 19:50:33 -05:00
! Copyright (C) 2005, 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
2005-05-09 02:34:15 -04:00
IN: compiler-frontend
USING: arrays assembler compiler-backend generic hashtables
inference kernel kernel-internals lists math math-internals
namespaces sequences 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.
2005-09-23 01:22:04 -04:00
node-classes ?hash dup [
2005-09-18 01:37:28 -04:00
types [ type-tag ] map dup all-equal?
2005-09-24 15:21:17 -04:00
[ first ] [ drop f ] if
] [
drop f
2005-09-24 15:21:17 -04:00
] if ;
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-slice dup first dup value? [
value-literal cells swap second
2005-09-24 15:21:17 -04:00
rot value-tag dup [ - ] [ 2drop f ] if
] [
3drop f
2005-09-24 15:21:17 -04:00
] if ;
2005-05-09 22:34:47 -04:00
2005-05-06 18:33:40 -04:00
\ slot [
dup slot@ [
2005-09-08 22:23:54 -04:00
-1 %inc-d ,
2006-04-01 19:50:33 -05:00
dup in-1 >r slot@ r> %fast-slot ,
2005-05-06 18:33:40 -04:00
] [
2006-04-01 19:50:33 -05:00
in-2 swap
2005-09-08 22:23:54 -04:00
-1 %inc-d ,
2006-04-01 19:50:33 -05:00
dup %untag ,
%slot ,
] if T{ vreg f 0 } out-1
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ set-slot [
dup slot@ [
2005-09-08 22:23:54 -04:00
-1 %inc-d ,
2006-04-01 19:50:33 -05:00
dup in-2
2005-09-08 22:23:54 -04:00
-2 %inc-d ,
2006-04-01 19:50:33 -05:00
rot slot@ %fast-set-slot ,
] [
in-3
2005-09-08 22:23:54 -04:00
-3 %inc-d ,
2006-04-01 19:50:33 -05:00
over %untag ,
%set-slot ,
2005-09-24 15:21:17 -04:00
] if
2006-04-01 19:50:33 -05:00
T{ vreg f 1 } %write-barrier ,
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
2006-01-31 21:31:53 -05:00
\ char-slot [
in-2
-1 %inc-d ,
2006-04-01 19:50:33 -05:00
[ %char-slot , ] keep
out-1
2006-01-31 21:31:53 -05:00
] "intrinsic" set-word-prop
\ set-char-slot [
in-3
-3 %inc-d ,
2006-04-01 19:50:33 -05:00
swap %set-char-slot ,
2006-01-31 21:31:53 -05:00
] "intrinsic" set-word-prop
\ type [
2006-04-01 19:50:33 -05:00
in-1 [ %type , ] keep out-1
] "intrinsic" set-word-prop
\ tag [
2006-04-01 19:50:33 -05:00
in-1 [ %tag , ] keep out-1
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ getenv [
2006-04-01 19:50:33 -05:00
T{ vreg f 0 } [
-1 %inc-d ,
swap node-peek value-literal %getenv ,
1 %inc-d ,
] keep out-1
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
2006-04-01 19:50:33 -05:00
: binary-imm ( node -- in1 in2 )
node-in-d { T{ vreg f 0 } f } intrinsic-inputs first2 swap
-2 %inc-d , ;
\ setenv [
2006-04-01 19:50:33 -05:00
binary-imm
%setenv ,
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
2006-04-01 19:50:33 -05:00
: binary-reg ( node -- in1 in2 )
node-in-d { T{ vreg f 0 } T{ vreg f 1 } } intrinsic-inputs
first2 swap -2 %inc-d , ;
: literal-immediate? ( value -- ? )
dup value? [ value-literal immediate? ] [ drop f ] if ;
2006-04-01 19:50:33 -05:00
: (binary-op) ( node -- in1 in2 )
fixnum-imm? [
dup node-peek literal-immediate?
[ binary-imm ] [ binary-reg ] if
] [
binary-reg
] if ;
2005-06-07 23:29:47 -04:00
: binary-op ( node op -- )
2006-04-01 19:50:33 -05:00
>r (binary-op) dup r> execute ,
1 %inc-d ,
T{ vreg f 0 } out-1 ; inline
: binary-op-reg ( node op -- )
>r binary-reg dup r> execute ,
1 %inc-d ,
T{ vreg f 0 } out-1 ; inline
{
{ fixnum+ %fixnum+ }
{ fixnum- %fixnum- }
{ fixnum-bitand %fixnum-bitand }
{ fixnum-bitor %fixnum-bitor }
{ fixnum-bitxor %fixnum-bitxor }
} [
2005-10-01 01:44:49 -04:00
first2 [ binary-op ] curry "intrinsic" set-word-prop
] each
: binary-jump ( node label op -- )
2006-04-01 19:50:33 -05:00
>r >r (binary-op) r> r> execute , ; inline
2005-10-04 03:16:50 -04:00
{
{ fixnum<= %jump-fixnum<= }
{ fixnum< %jump-fixnum< }
{ fixnum>= %jump-fixnum>= }
{ fixnum> %jump-fixnum> }
{ eq? %jump-eq? }
} [
2005-10-01 01:44:49 -04:00
first2 [ binary-jump ] curry "if-intrinsic" set-word-prop
] each
\ fixnum/i [
\ %fixnum/i binary-op-reg
] "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.
2006-04-01 19:50:33 -05:00
in-2 swap
2005-09-08 22:23:54 -04:00
-1 %inc-d ,
2006-04-01 19:50:33 -05:00
[ dup %fixnum-mod , ] keep out-1
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ fixnum/mod [
! See the remark on fixnum-mod for vreg usage
2006-04-01 19:50:33 -05:00
in-2 swap 2array
{ T{ vreg f 2 } T{ vreg f 0 } }
%fixnum/mod ,
2006-04-01 19:50:33 -05:00
{ T{ vreg f 0 } T{ vreg f 2 } } out-n
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
\ fixnum-bitnot [
2006-04-01 19:50:33 -05:00
in-1 [ dup %fixnum-bitnot , ] keep out-1
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop
2005-05-09 22:34:47 -04:00
\ fixnum* [
\ %fixnum* binary-op-reg
] "intrinsic" set-word-prop
2005-05-09 22:34:47 -04:00
: slow-shift ( -- ) \ fixnum-shift %call , ;
: negative-shift ( n -- )
2005-09-08 22:23:54 -04:00
-1 %inc-d ,
2006-04-01 19:50:33 -05:00
{ f } { T{ vreg f 0 } } intrinsic-inputs drop
2005-12-13 18:18:16 -05:00
dup cell-bits neg <= [
2006-04-01 19:50:33 -05:00
drop T{ vreg f 0 } T{ vreg f 2 } %fixnum-sgn ,
T{ vreg f 2 } out-1
2005-05-09 22:34:47 -04:00
] [
2006-04-01 19:50:33 -05:00
neg T{ vreg f 0 } T{ vreg f 0 } %fixnum>> ,
T{ vreg f 0 } out-1
2005-09-24 15:21:17 -04:00
] if ;
2005-05-09 22:34:47 -04:00
: fast-shift ( n -- )
2006-01-28 15:49:31 -05:00
dup zero? [
2005-09-08 22:23:54 -04:00
-1 %inc-d ,
2005-05-09 22:34:47 -04:00
drop
] [
dup 0 < [
negative-shift
] [
drop slow-shift
2005-09-24 15:21:17 -04:00
] if
] if ;
2005-05-09 22:34:47 -04:00
\ fixnum-shift [
node-peek dup value? [
value-literal fast-shift
2005-05-09 22:34:47 -04:00
] [
drop slow-shift
2005-09-24 15:21:17 -04:00
] if
2005-05-17 16:13:08 -04:00
] "intrinsic" set-word-prop