! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: layouts namespaces kernel accessors sequences
-classes.algebra locals compiler.tree.propagation.info
-compiler.cfg.stacks compiler.cfg.hats compiler.cfg.registers
+USING: layouts namespaces kernel accessors sequences math
+classes.algebra locals combinators cpu.architecture
+compiler.tree.propagation.info compiler.cfg.stacks
+compiler.cfg.hats compiler.cfg.registers
compiler.cfg.instructions compiler.cfg.utilities
compiler.cfg.builder.blocks compiler.constants ;
IN: compiler.cfg.intrinsics.slots
[ [ second literal>> ] [ first value-tag ] bi ] bi*
^^slot-imm ;
+: immediate-slot-offset? ( value-info -- ? )
+ literal>> {
+ { [ dup fixnum? ] [ tag-fixnum immediate-arithmetic? ] }
+ [ drop f ]
+ } cond ;
+
: emit-slot ( node -- )
dup node-input-infos
dup first value-tag [
nip
- dup second value-info-small-fixnum?
+ dup second immediate-slot-offset?
[ (emit-slot-imm) ] [ (emit-slot) ] if
ds-push
] [ drop emit-primitive ] if ;
dup node-input-infos
dup second value-tag [
nip
- dup third value-info-small-fixnum?
+ dup third immediate-slot-offset?
[ (emit-set-slot-imm) ] [ (emit-set-slot) ] if
] [ drop emit-primitive ] if ;
compiler.cfg.value-numbering.simplify ;
IN: compiler.cfg.value-numbering.rewrite
-: vreg-small-constant? ( vreg -- ? )
+: vreg-immediate-arithmetic? ( vreg -- ? )
vreg>expr {
[ constant-expr? ]
[ value>> fixnum? ]
- [ value>> small-enough? ]
+ [ value>> immediate-arithmetic? ]
+ } 1&& ;
+
+: vreg-immediate-bitwise? ( vreg -- ? )
+ vreg>expr {
+ [ constant-expr? ]
+ [ value>> fixnum? ]
+ [ value>> immediate-bitwise? ]
} 1&& ;
! Outputs f to mean no change
M: ##compare-branch rewrite
{
- { [ dup src1>> vreg-small-constant? ] [ t >compare-imm-branch ] }
- { [ dup src2>> vreg-small-constant? ] [ f >compare-imm-branch ] }
+ { [ dup src1>> vreg-immediate-arithmetic? ] [ t >compare-imm-branch ] }
+ { [ dup src2>> vreg-immediate-arithmetic? ] [ f >compare-imm-branch ] }
{ [ dup self-compare? ] [ rewrite-self-compare-branch ] }
[ drop f ]
} cond ;
M: ##compare rewrite
{
- { [ dup src1>> vreg-small-constant? ] [ t >compare-imm ] }
- { [ dup src2>> vreg-small-constant? ] [ f >compare-imm ] }
+ { [ dup src1>> vreg-immediate-arithmetic? ] [ t >compare-imm ] }
+ { [ dup src2>> vreg-immediate-arithmetic? ] [ f >compare-imm ] }
{ [ dup self-compare? ] [ rewrite-self-compare ] }
[ drop f ]
} cond ;
M: ##not rewrite
maybe-unary-constant-fold ;
+: arithmetic-op? ( op -- ? )
+ {
+ ##add
+ ##add-imm
+ ##sub
+ ##sub-imm
+ ##mul
+ ##mul-imm
+ } memq? ;
+
+: immediate? ( value op -- ? )
+ arithmetic-op? [ immediate-arithmetic? ] [ immediate-bitwise? ] if ;
+
: reassociate ( insn op -- insn )
[
{
[ ]
} cleave constant-fold*
] dip
- over small-enough? [ new-insn ] [ 2drop 2drop f ] if ; inline
+ 2dup immediate? [ new-insn ] [ 2drop 2drop f ] if ; inline
M: ##add-imm rewrite
{
} cond ;
: sub-imm>add-imm ( insn -- insn' )
- [ dst>> ] [ src1>> ] [ src2>> neg ] tri dup small-enough?
+ [ dst>> ] [ src1>> ] [ src2>> neg ] tri dup immediate-arithmetic?
[ \ ##add-imm new-insn ] [ 3drop f ] if ;
M: ##sub-imm rewrite
[ swap ] when vreg>constant
] dip new-insn ; inline
+: vreg-immediate? ( vreg op -- ? )
+ arithmetic-op?
+ [ vreg-immediate-arithmetic? ] [ vreg-immediate-bitwise? ] if ;
+
: rewrite-arithmetic ( insn op -- ? )
{
- { [ over src2>> vreg-small-constant? ] [ f insn>imm-insn ] }
+ { [ over src2>> over vreg-immediate? ] [ f insn>imm-insn ] }
[ 2drop f ]
} cond ; inline
: rewrite-arithmetic-commutative ( insn op -- ? )
{
- { [ over src2>> vreg-small-constant? ] [ f insn>imm-insn ] }
- { [ over src1>> vreg-small-constant? ] [ t insn>imm-insn ] }
+ { [ over src2>> over vreg-immediate? ] [ f insn>imm-insn ] }
+ { [ over src1>> over vreg-immediate? ] [ t insn>imm-insn ] }
[ 2drop f ]
} cond ; inline
[ 4 ] [ 12 7 [ fixnum-bitand ] compile-call ] unit-test
[ 4 ] [ 12 [ 7 fixnum-bitand ] compile-call ] unit-test
[ 4 ] [ [ 12 7 fixnum-bitand ] compile-call ] unit-test
+[ -16 ] [ -1 [ -16 fixnum-bitand ] compile-call ] unit-test
[ 15 ] [ 12 7 [ fixnum-bitor ] compile-call ] unit-test
[ 15 ] [ 12 [ 7 fixnum-bitor ] compile-call ] unit-test
[ 15 ] [ [ 12 7 fixnum-bitor ] compile-call ] unit-test
+[ -1 ] [ -1 [ -16 fixnum-bitor ] compile-call ] unit-test
[ 11 ] [ 12 7 [ fixnum-bitxor ] compile-call ] unit-test
[ 11 ] [ 12 [ 7 fixnum-bitxor ] compile-call ] unit-test
[ 11 ] [ [ 12 7 fixnum-bitxor ] compile-call ] unit-test
+[ -16 ] [ -1 [ -16 fixnum-bitxor ] compile-call ] unit-test
[ f ] [ 12 7 [ fixnum< [ t ] [ f ] if ] compile-call ] unit-test
[ f ] [ 12 [ 7 fixnum< [ t ] [ f ] if ] compile-call ] unit-test
dup in-d>> last node-value-info
literal>> first immutable-tuple-class?
] [ drop f ] if ;
-
-: value-info-small-fixnum? ( value-info -- ? )
- literal>> {
- { [ dup fixnum? ] [ tag-fixnum small-enough? ] }
- [ drop f ]
- } cond ;
-
-: value-info-small-tagged? ( value-info -- ? )
- dup literal?>> [
- literal>> {
- { [ dup fixnum? ] [ tag-fixnum small-enough? ] }
- { [ dup not ] [ drop t ] }
- [ drop f ]
- } cond
- ] [ drop f ] if ;
M: stack-params param-reg drop ;
-! Is this integer small enough to appear in value template
-! slots?
-HOOK: small-enough? cpu ( n -- ? )
+! Is this integer small enough to be an immediate operand for
+! %add-imm, %sub-imm, and %mul-imm?
+HOOK: immediate-arithmetic? cpu ( n -- ? )
+
+! Is this integer small enough to be an immediate operand for
+! %and-imm, %or-imm, and %xor-imm?
+HOOK: immediate-bitwise? cpu ( n -- ? )
! Is this structure small enough to be returned in registers?
HOOK: return-struct-in-registers? cpu ( c-type -- ? )
! Unbox former top of data stack to return registers
unbox-return ;
-M: ppc small-enough? ( n -- ? ) -32768 32767 between? ;
+M: ppc immediate-arithmetic? ( n -- ? ) -32768 32767 between? ;
+
+M: ppc immediate-bitwise? ( n -- ? ) 0 65535 between? ;
M: ppc return-struct-in-registers? ( c-type -- ? )
c-type return-in-registers?>> ;
M: x86 value-struct? drop t ;
-M: x86 small-enough? ( n -- ? )
+M: x86 immediate-arithmetic? ( n -- ? )
+ HEX: -80000000 HEX: 7fffffff between? ;
+
+M: x86 immediate-bitwise? ( n -- ? )
HEX: -80000000 HEX: 7fffffff between? ;
: next-stack@ ( n -- operand )