]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/cfg/intrinsics/fixnum/fixnum.factor
Improve code generation for shift word: add intrinsics for fixnum-shift-fast in the...
[factor.git] / basis / compiler / cfg / intrinsics / fixnum / fixnum.factor
1 ! Copyright (C) 2008, 2009 Slava Pestov, Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: sequences accessors layouts kernel math math.intervals
4 namespaces combinators fry arrays
5 compiler.tree.propagation.info
6 compiler.cfg.hats
7 compiler.cfg.stacks
8 compiler.cfg.instructions
9 compiler.cfg.utilities
10 compiler.cfg.registers
11 compiler.cfg.comparisons ;
12 IN: compiler.cfg.intrinsics.fixnum
13
14 : emit-both-fixnums? ( -- )
15     2inputs
16     ^^or
17     tag-mask get ^^and-imm
18     0 cc= ^^compare-imm
19     ds-push ;
20
21 : tag-literal ( n -- tagged )
22     literal>> [ tag-fixnum ] [ \ f tag-number ] if* ;
23
24 : emit-fixnum-op ( insn -- )
25     [ 2inputs ] dip call ds-push ; inline
26
27 : emit-fixnum-left-shift ( -- )
28     [ ^^untag-fixnum ^^shl ] emit-fixnum-op ;
29
30 : emit-fixnum-right-shift ( -- )
31     [ ^^untag-fixnum ^^neg ^^sar dup tag-mask get ^^and-imm ^^xor ] emit-fixnum-op ;
32
33 : emit-fixnum-shift-general ( -- )
34     D 0 ^^peek 0 cc> ##compare-imm-branch
35     [ emit-fixnum-left-shift ] with-branch
36     [ emit-fixnum-right-shift ] with-branch
37     2array emit-conditional ;
38
39 : emit-fixnum-shift-fast ( node -- )
40     node-input-infos second interval>> {
41         { [ dup 0 [a,inf] interval-subset? ] [ drop emit-fixnum-left-shift ] }
42         { [ dup 0 [-inf,a] interval-subset? ] [ drop emit-fixnum-right-shift ] }
43         [ drop emit-fixnum-shift-general ]
44     } cond ;
45     
46 : emit-fixnum-bitnot ( -- )
47     ds-pop ^^not tag-mask get ^^xor-imm ds-push ;
48
49 : emit-fixnum-log2 ( -- )
50     ds-pop ^^log2 tag-bits get ^^sub-imm ^^tag-fixnum ds-push ;
51
52 : emit-fixnum*fast ( -- )
53     2inputs ^^untag-fixnum ^^mul ds-push ;
54
55 : emit-fixnum-comparison ( cc -- )
56     '[ _ ^^compare ] emit-fixnum-op ;
57
58 : emit-bignum>fixnum ( -- )
59     ds-pop ^^bignum>integer ^^tag-fixnum ds-push ;
60
61 : emit-fixnum>bignum ( -- )
62     ds-pop ^^untag-fixnum ^^integer>bignum ds-push ;
63
64 : emit-no-overflow-case ( dst -- final-bb )
65     [ -2 ##inc-d ds-push ] with-branch ;
66
67 : emit-overflow-case ( word -- final-bb )
68     [ ##call ] with-branch ;
69
70 : emit-fixnum-overflow-op ( quot word -- )
71     [ [ D 1 ^^peek D 0 ^^peek ] dip call ] dip
72     [ emit-no-overflow-case ] [ emit-overflow-case ] bi* 2array
73     emit-conditional ; inline
74
75 : fixnum+overflow ( x y -- z ) [ >bignum ] bi@ + ;
76
77 : fixnum-overflow ( x y -- z ) [ >bignum ] bi@ - ;
78
79 : fixnum*overflow ( x y -- z ) [ >bignum ] bi@ * ;
80
81 : emit-fixnum+ ( -- )
82     [ ^^fixnum-add ] \ fixnum+overflow emit-fixnum-overflow-op ;
83
84 : emit-fixnum- ( -- )
85     [ ^^fixnum-sub ] \ fixnum-overflow emit-fixnum-overflow-op ;
86
87 : emit-fixnum* ( -- )
88     [ ^^untag-fixnum ^^fixnum-mul ] \ fixnum*overflow emit-fixnum-overflow-op ;