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
|
2005-07-27 20:13:11 -04:00
|
|
|
sequences vectors words ;
|
2005-05-06 18:33:40 -04:00
|
|
|
|
2005-06-07 03:44:34 -04:00
|
|
|
! Architecture description
|
|
|
|
: fixnum-imm?
|
|
|
|
#! Can fixnum operations take immediate operands?
|
|
|
|
cpu "x86" = ;
|
|
|
|
|
2005-05-06 18:33:40 -04:00
|
|
|
\ dup [
|
|
|
|
drop
|
|
|
|
in-1
|
|
|
|
1 %inc-d ,
|
|
|
|
out-1
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-06 18:33:40 -04:00
|
|
|
|
|
|
|
\ swap [
|
|
|
|
drop
|
|
|
|
in-2
|
2005-05-07 22:39:00 -04:00
|
|
|
0 0 %replace-d ,
|
|
|
|
1 1 %replace-d ,
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-06 18:33:40 -04:00
|
|
|
|
|
|
|
\ over [
|
|
|
|
drop
|
|
|
|
0 1 %peek-d ,
|
|
|
|
1 %inc-d ,
|
|
|
|
out-1
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-06 18:33:40 -04:00
|
|
|
|
|
|
|
\ pick [
|
|
|
|
drop
|
|
|
|
0 2 %peek-d ,
|
|
|
|
1 %inc-d ,
|
|
|
|
out-1
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-06 18:33:40 -04:00
|
|
|
|
|
|
|
\ >r [
|
|
|
|
drop
|
|
|
|
in-1
|
|
|
|
1 %inc-r ,
|
|
|
|
1 %dec-d ,
|
|
|
|
0 0 %replace-r ,
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-06 18:33:40 -04:00
|
|
|
|
|
|
|
\ r> [
|
|
|
|
drop
|
|
|
|
0 0 %peek-r ,
|
|
|
|
1 %inc-d ,
|
|
|
|
1 %dec-r ,
|
|
|
|
out-1
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-06 18:33:40 -04:00
|
|
|
|
2005-05-17 16:13:08 -04:00
|
|
|
: node-peek ( node -- obj ) node-in-d peek ;
|
2005-05-09 22:34:47 -04:00
|
|
|
|
2005-05-06 18:33:40 -04:00
|
|
|
: peek-2 dup length 2 - swap nth ;
|
2005-05-17 16:13:08 -04:00
|
|
|
: node-peek-2 ( node -- obj ) node-in-d peek-2 ;
|
2005-05-09 22:34:47 -04:00
|
|
|
|
|
|
|
: typed? ( value -- ? ) value-types length 1 = ;
|
2005-05-06 18:33:40 -04:00
|
|
|
|
2005-05-09 22:34:47 -04:00
|
|
|
: slot@ ( node -- n )
|
2005-05-06 18:33:40 -04:00
|
|
|
#! Compute slot offset.
|
2005-05-17 16:13:08 -04:00
|
|
|
node-in-d
|
2005-05-06 18:33:40 -04:00
|
|
|
dup peek literal-value cell *
|
|
|
|
swap peek-2 value-types car type-tag - ;
|
|
|
|
|
2005-05-09 22:34:47 -04:00
|
|
|
: typed-literal? ( node -- ? )
|
|
|
|
#! Output if the node's first input is well-typed, and the
|
|
|
|
#! second is a literal.
|
2005-08-07 00:00:57 -04:00
|
|
|
dup node-peek literal? swap node-peek-2 typed? and ;
|
2005-05-09 22:34:47 -04:00
|
|
|
|
2005-05-06 18:33:40 -04:00
|
|
|
\ slot [
|
2005-05-09 22:34:47 -04:00
|
|
|
dup typed-literal? [
|
2005-05-06 18:33:40 -04:00
|
|
|
1 %dec-d ,
|
|
|
|
in-1
|
|
|
|
0 swap slot@ %fast-slot ,
|
|
|
|
] [
|
|
|
|
drop
|
|
|
|
in-2
|
|
|
|
1 %dec-d ,
|
2005-05-07 22:39:00 -04:00
|
|
|
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
|
2005-05-13 20:37:28 -04:00
|
|
|
|
|
|
|
\ set-slot [
|
|
|
|
dup typed-literal? [
|
|
|
|
1 %dec-d ,
|
|
|
|
in-2
|
|
|
|
2 %dec-d ,
|
|
|
|
slot@ >r 0 1 r> %fast-set-slot ,
|
2005-06-04 02:20:54 -04:00
|
|
|
0 %write-barrier ,
|
2005-05-13 20:37:28 -04:00
|
|
|
] [
|
|
|
|
drop
|
|
|
|
in-3
|
|
|
|
3 %dec-d ,
|
|
|
|
1 %untag ,
|
|
|
|
0 1 2 %set-slot ,
|
2005-06-04 02:20:54 -04:00
|
|
|
1 %write-barrier ,
|
2005-05-13 20:37:28 -04:00
|
|
|
] ifte
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-06 19:49:07 -04:00
|
|
|
|
|
|
|
\ type [
|
|
|
|
drop
|
|
|
|
in-1
|
|
|
|
0 %type ,
|
2005-08-15 15:34:00 -04:00
|
|
|
0 %retag-fixnum ,
|
|
|
|
out-1
|
|
|
|
] "intrinsic" set-word-prop
|
|
|
|
|
|
|
|
\ tag [
|
|
|
|
drop
|
|
|
|
in-1
|
|
|
|
0 %tag ,
|
|
|
|
0 %retag-fixnum ,
|
2005-05-06 19:49:07 -04:00
|
|
|
out-1
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-07 22:39:00 -04:00
|
|
|
|
2005-05-13 20:37:28 -04:00
|
|
|
\ getenv [
|
|
|
|
1 %dec-d ,
|
|
|
|
node-peek literal-value 0 <vreg> swap %getenv ,
|
|
|
|
1 %inc-d ,
|
|
|
|
out-1
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-13 20:37:28 -04:00
|
|
|
|
|
|
|
\ setenv [
|
|
|
|
1 %dec-d ,
|
|
|
|
in-1
|
|
|
|
node-peek literal-value 0 <vreg> swap %setenv ,
|
|
|
|
1 %dec-d ,
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-13 20:37:28 -04:00
|
|
|
|
2005-06-07 23:29:47 -04:00
|
|
|
: value/vreg-list ( in -- list )
|
|
|
|
[ 0 swap length 1 - ] keep
|
2005-07-27 20:13:11 -04:00
|
|
|
[ >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
|
2005-07-27 20:13:11 -04:00
|
|
|
dup [ 3unseq load-value ] each
|
|
|
|
[ first <vreg> ] map ;
|
2005-06-07 23:29:47 -04:00
|
|
|
|
|
|
|
: load-inputs ( node -- in )
|
|
|
|
dup node-in-d values>vregs
|
|
|
|
[ length swap node-out-d length - %dec-d , ] keep ;
|
|
|
|
|
|
|
|
: binary-op-reg ( node op -- )
|
2005-07-27 20:13:11 -04:00
|
|
|
>r load-inputs 2unseq swap dup r> execute ,
|
2005-06-07 23:29:47 -04:00
|
|
|
0 0 %replace-d , ; inline
|
2005-05-06 19:49:07 -04:00
|
|
|
|
2005-05-15 21:17:56 -04:00
|
|
|
: literal-fixnum? ( value -- ? )
|
2005-08-07 00:00:57 -04:00
|
|
|
dup literal? [ literal-value fixnum? ] [ drop f ] ifte ;
|
2005-05-15 21:17:56 -04:00
|
|
|
|
2005-06-07 23:29:47 -04:00
|
|
|
: binary-op-imm ( imm op -- )
|
|
|
|
1 %dec-d , in-1
|
|
|
|
>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 -- )
|
2005-05-07 22:39:00 -04:00
|
|
|
#! out is a vreg where the vop stores the result.
|
2005-06-07 03:44:34 -04:00
|
|
|
fixnum-imm? [
|
2005-06-07 23:29:47 -04:00
|
|
|
>r dup node-peek dup literal-fixnum? [
|
|
|
|
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-05-06 19:49:07 -04:00
|
|
|
] [
|
2005-06-07 23:29:47 -04:00
|
|
|
binary-op-reg
|
2005-05-06 19:49:07 -04:00
|
|
|
] 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-05-06 19:49:07 -04:00
|
|
|
] [
|
2005-08-03 23:56:28 -04:00
|
|
|
uncons [ literalize , \ binary-op , ] make-list
|
2005-05-17 16:13:08 -04:00
|
|
|
"intrinsic" set-word-prop
|
2005-05-06 19:49:07 -04:00
|
|
|
] each
|
2005-05-07 22:39:00 -04:00
|
|
|
|
2005-06-07 23:29:47 -04:00
|
|
|
: fast-fixnum* ( n -- )
|
|
|
|
1 %dec-d ,
|
|
|
|
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
|
|
|
|
2005-05-07 22:39:00 -04:00
|
|
|
\ fixnum* [
|
2005-05-09 22:34:47 -04:00
|
|
|
! Turn multiplication by a power of two into a left shift.
|
2005-06-07 23:29:47 -04:00
|
|
|
dup node-peek dup literal-fixnum? [
|
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
|
2005-05-07 22:39:00 -04:00
|
|
|
|
|
|
|
\ 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.
|
2005-06-03 00:47:00 -04:00
|
|
|
drop
|
|
|
|
in-2
|
|
|
|
1 %dec-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-07 22:39:00 -04:00
|
|
|
|
2005-05-16 01:15:48 -04:00
|
|
|
\ fixnum/i t "intrinsic" set-word-prop
|
2005-05-07 22:39:00 -04:00
|
|
|
|
|
|
|
\ 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
|
2005-05-07 22:39:00 -04:00
|
|
|
|
|
|
|
\ fixnum/mod [
|
|
|
|
! See the remark on fixnum-mod for vreg usage
|
|
|
|
drop
|
|
|
|
in-2
|
2005-06-03 00:47:00 -04:00
|
|
|
[ << vreg f 1 >> << vreg f 0 >> ]
|
|
|
|
[ << vreg f 2 >> << vreg f 0 >> ]
|
|
|
|
%fixnum/mod ,
|
2005-05-07 22:39:00 -04:00
|
|
|
2 0 %replace-d ,
|
|
|
|
0 1 %replace-d ,
|
2005-05-17 16:13:08 -04:00
|
|
|
] "intrinsic" set-word-prop
|
2005-05-07 22:39:00 -04:00
|
|
|
|
|
|
|
\ fixnum-bitnot [
|
|
|
|
drop
|
|
|
|
in-1
|
2005-06-05 02:43:05 -04:00
|
|
|
0 <vreg> 0 <vreg> %fixnum-bitnot ,
|
2005-05-07 22:39:00 -04:00
|
|
|
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 -- )
|
|
|
|
1 %dec-d ,
|
|
|
|
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 ,
|
|
|
|
] [
|
2005-06-03 00:47:00 -04:00
|
|
|
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 - <= [
|
|
|
|
1 %dec-d ,
|
|
|
|
in-1
|
2005-06-03 00:47:00 -04:00
|
|
|
0 <vreg> 0 <vreg> %fixnum<< ,
|
2005-05-09 22:34:47 -04:00
|
|
|
out-1
|
|
|
|
] [
|
|
|
|
drop slow-shift
|
|
|
|
] ifte ;
|
|
|
|
|
|
|
|
: fast-shift ( n -- )
|
|
|
|
dup 0 = [
|
|
|
|
1 %dec-d ,
|
|
|
|
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
|