]> gitweb.factorcode.org Git - factor.git/blob - basis/compiler/cfg/intrinsics/fixnum/fixnum.factor
compiler.cfg.*: more fixes to pass basic-block on the stack than in a
[factor.git] / basis / compiler / cfg / intrinsics / fixnum / fixnum.factor
1 ! Copyright (C) 2008, 2010 Slava Pestov, Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays combinators compiler.cfg
4 compiler.cfg.builder.blocks compiler.cfg.comparisons compiler.cfg.hats
5 compiler.cfg.instructions compiler.cfg.registers compiler.cfg.stacks
6 compiler.cfg.stacks.local compiler.tree.propagation.info
7 cpu.architecture fry kernel layouts math math.intervals namespaces
8 sequences ;
9 IN: compiler.cfg.intrinsics.fixnum
10
11 : emit-both-fixnums? ( -- )
12     [
13         [ ^^tagged>integer ] bi@
14         ^^or tag-mask get ^^and-imm
15         0 cc= ^^compare-integer-imm
16     ] binary-op ;
17
18 : emit-fixnum-left-shift ( -- )
19     [ ^^shl ] binary-op ;
20
21 : emit-fixnum-right-shift ( -- )
22     [
23         [ tag-bits get ^^shl-imm ] dip
24         ^^neg ^^sar
25         tag-bits get ^^sar-imm
26     ] binary-op ;
27
28 : emit-fixnum-shift-general ( -- )
29     ds-peek 0 cc> ##compare-integer-imm-branch,
30     [ emit-fixnum-left-shift ] with-branch
31     [ emit-fixnum-right-shift ] with-branch
32     2array basic-block get emit-conditional ;
33
34 : emit-fixnum-shift-fast ( node -- )
35     node-input-infos second interval>> {
36         { [ dup 0 [a,inf] interval-subset? ] [ drop emit-fixnum-left-shift ] }
37         { [ dup 0 [-inf,a] interval-subset? ] [ drop emit-fixnum-right-shift ] }
38         [ drop emit-fixnum-shift-general ]
39     } cond ;
40
41 : emit-fixnum-comparison ( cc -- )
42     '[ _ ^^compare-integer ] binary-op ;
43
44 : emit-no-overflow-case ( dst -- final-bb )
45     [ D: -2 inc-stack ds-push ] with-branch ;
46
47 : emit-overflow-case ( word -- final-bb )
48     [
49         -1 basic-block get emit-call-block
50     ] with-branch ;
51
52 : emit-fixnum-overflow-op ( quot word -- )
53     ! Inputs to the final instruction need to be copied because
54     ! of loc>vreg sync
55     [ [ (2inputs) [ any-rep ^^copy ] bi@ cc/o ] dip call ] dip
56     [ emit-no-overflow-case ] [ emit-overflow-case ] bi* 2array
57     basic-block get emit-conditional ; inline
58
59 : fixnum+overflow ( x y -- z ) [ >bignum ] bi@ + ;
60
61 : fixnum-overflow ( x y -- z ) [ >bignum ] bi@ - ;
62
63 : fixnum*overflow ( x y -- z ) [ >bignum ] bi@ * ;
64
65 : emit-fixnum+ ( -- )
66     [ ^^fixnum-add ] \ fixnum+overflow emit-fixnum-overflow-op ;
67
68 : emit-fixnum- ( -- )
69     [ ^^fixnum-sub ] \ fixnum-overflow emit-fixnum-overflow-op ;
70
71 : emit-fixnum* ( -- )
72     [ ^^fixnum-mul ] \ fixnum*overflow emit-fixnum-overflow-op ;