compiler.cfg: use x86 TEST instruction to optimize 'bitand 0 ='
parent
22625469bc
commit
5a67711bfd
|
@ -713,6 +713,14 @@ INSN: ##compare-integer-imm-branch
|
||||||
use: src1/int-rep
|
use: src1/int-rep
|
||||||
literal: src2 cc ;
|
literal: src2 cc ;
|
||||||
|
|
||||||
|
INSN: ##test-branch
|
||||||
|
use: src1/int-rep src2/int-rep
|
||||||
|
literal: cc ;
|
||||||
|
|
||||||
|
INSN: ##test-imm-branch
|
||||||
|
use: src1/int-rep
|
||||||
|
literal: src2 cc ;
|
||||||
|
|
||||||
PURE-INSN: ##compare-integer
|
PURE-INSN: ##compare-integer
|
||||||
def: dst/tagged-rep
|
def: dst/tagged-rep
|
||||||
use: src1/int-rep src2/int-rep
|
use: src1/int-rep src2/int-rep
|
||||||
|
@ -725,6 +733,18 @@ use: src1/int-rep
|
||||||
literal: src2 cc
|
literal: src2 cc
|
||||||
temp: temp/int-rep ;
|
temp: temp/int-rep ;
|
||||||
|
|
||||||
|
PURE-INSN: ##test
|
||||||
|
def: dst/tagged-rep
|
||||||
|
use: src1/int-rep src2/int-rep
|
||||||
|
literal: cc
|
||||||
|
temp: temp/int-rep ;
|
||||||
|
|
||||||
|
PURE-INSN: ##test-imm
|
||||||
|
def: dst/tagged-rep
|
||||||
|
use: src1/int-rep
|
||||||
|
literal: src2 cc
|
||||||
|
temp: temp/int-rep ;
|
||||||
|
|
||||||
! Float conditionals
|
! Float conditionals
|
||||||
INSN: ##compare-float-ordered-branch
|
INSN: ##compare-float-ordered-branch
|
||||||
use: src1/double-rep src2/double-rep
|
use: src1/double-rep src2/double-rep
|
||||||
|
@ -798,6 +818,8 @@ UNION: conditional-branch-insn
|
||||||
##compare-imm-branch
|
##compare-imm-branch
|
||||||
##compare-integer-branch
|
##compare-integer-branch
|
||||||
##compare-integer-imm-branch
|
##compare-integer-imm-branch
|
||||||
|
##test-branch
|
||||||
|
##test-imm-branch
|
||||||
##compare-float-ordered-branch
|
##compare-float-ordered-branch
|
||||||
##compare-float-unordered-branch
|
##compare-float-unordered-branch
|
||||||
##test-vector-branch
|
##test-vector-branch
|
||||||
|
|
|
@ -211,24 +211,48 @@ M: ##compare-integer-imm optimize-insn
|
||||||
[ call-next-method ]
|
[ call-next-method ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
|
M: ##test-imm optimize-insn
|
||||||
|
{
|
||||||
|
{ [ dup { [ src1-tagged? ] [ src2-tagged-bitwise? ] } 1&& ] [ >tagged-imm ] }
|
||||||
|
[ call-next-method ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
M: ##compare-integer-imm-branch optimize-insn
|
M: ##compare-integer-imm-branch optimize-insn
|
||||||
{
|
{
|
||||||
{ [ dup { [ src1-tagged? ] [ src2-tagged-arithmetic? ] } 1&& ] [ >tagged-imm ] }
|
{ [ dup { [ src1-tagged? ] [ src2-tagged-arithmetic? ] } 1&& ] [ >tagged-imm ] }
|
||||||
[ call-next-method ]
|
[ call-next-method ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
|
M: ##test-imm-branch optimize-insn
|
||||||
|
{
|
||||||
|
{ [ dup { [ src1-tagged? ] [ src2-tagged-bitwise? ] } 1&& ] [ >tagged-imm ] }
|
||||||
|
[ call-next-method ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
M: ##compare-integer optimize-insn
|
M: ##compare-integer optimize-insn
|
||||||
{
|
{
|
||||||
{ [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] }
|
{ [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] }
|
||||||
[ call-next-method ]
|
[ call-next-method ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
|
M: ##test optimize-insn
|
||||||
|
{
|
||||||
|
{ [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] }
|
||||||
|
[ call-next-method ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
M: ##compare-integer-branch optimize-insn
|
M: ##compare-integer-branch optimize-insn
|
||||||
{
|
{
|
||||||
{ [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] }
|
{ [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] }
|
||||||
[ call-next-method ]
|
[ call-next-method ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
|
M: ##test-branch optimize-insn
|
||||||
|
{
|
||||||
|
{ [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] }
|
||||||
|
[ call-next-method ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
! Identities:
|
! Identities:
|
||||||
! tag(neg(untag(x))) = x
|
! tag(neg(untag(x))) = x
|
||||||
! tag(neg(x)) = x * -2^tag-bits
|
! tag(neg(x)) = x * -2^tag-bits
|
||||||
|
|
|
@ -632,7 +632,23 @@ cpu x86.64? [
|
||||||
} test-peephole
|
} test-peephole
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
! Tag/untag elimination for ##compare-integer
|
! Tag/untag elimination for ##compare-integer and ##test
|
||||||
|
[
|
||||||
|
V{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##peek f 1 D 1 }
|
||||||
|
T{ ##test f 2 0 1 cc= }
|
||||||
|
T{ ##replace f 2 D 0 }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
V{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##peek f 1 D 1 }
|
||||||
|
T{ ##test f 2 0 1 cc= }
|
||||||
|
T{ ##replace f 2 D 0 }
|
||||||
|
} test-peephole
|
||||||
|
] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
V{
|
V{
|
||||||
T{ ##peek f 0 D 0 }
|
T{ ##peek f 0 D 0 }
|
||||||
|
@ -663,6 +679,20 @@ cpu x86.64? [
|
||||||
} test-peephole
|
} test-peephole
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
V{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##peek f 1 D 1 }
|
||||||
|
T{ ##test-branch f 0 1 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
V{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##peek f 1 D 1 }
|
||||||
|
T{ ##test-branch f 0 1 cc= }
|
||||||
|
} test-peephole
|
||||||
|
] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
V{
|
V{
|
||||||
T{ ##peek f 0 D 0 }
|
T{ ##peek f 0 D 0 }
|
||||||
|
@ -677,6 +707,20 @@ cpu x86.64? [
|
||||||
} test-peephole
|
} test-peephole
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
V{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##peek f 1 D 1 }
|
||||||
|
T{ ##test-imm-branch f 0 $[ 10 tag-fixnum ] cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
V{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##peek f 1 D 1 }
|
||||||
|
T{ ##test-imm-branch f 0 10 cc= }
|
||||||
|
} test-peephole
|
||||||
|
] unit-test
|
||||||
|
|
||||||
! Tag/untag elimination for ##neg
|
! Tag/untag elimination for ##neg
|
||||||
[
|
[
|
||||||
V{
|
V{
|
||||||
|
|
|
@ -123,6 +123,10 @@ M: ##compare-integer-imm has-peephole-opts? drop t ;
|
||||||
M: ##compare-integer has-peephole-opts? drop t ;
|
M: ##compare-integer has-peephole-opts? drop t ;
|
||||||
M: ##compare-integer-imm-branch has-peephole-opts? drop t ;
|
M: ##compare-integer-imm-branch has-peephole-opts? drop t ;
|
||||||
M: ##compare-integer-branch has-peephole-opts? drop t ;
|
M: ##compare-integer-branch has-peephole-opts? drop t ;
|
||||||
|
M: ##test-imm has-peephole-opts? drop t ;
|
||||||
|
M: ##test has-peephole-opts? drop t ;
|
||||||
|
M: ##test-imm-branch has-peephole-opts? drop t ;
|
||||||
|
M: ##test-branch has-peephole-opts? drop t ;
|
||||||
|
|
||||||
GENERIC: compute-insn-costs ( insn -- )
|
GENERIC: compute-insn-costs ( insn -- )
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
! Copyright (C) 2010 Slava Pestov.
|
! Copyright (C) 2010 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors combinators kernel math math.order namespaces
|
USING: accessors combinators kernel math math.order namespaces
|
||||||
sequences vectors combinators.short-circuit compiler.cfg
|
sequences vectors combinators.short-circuit
|
||||||
compiler.cfg.comparisons compiler.cfg.instructions
|
cpu.architecture
|
||||||
|
compiler.cfg
|
||||||
|
compiler.cfg.comparisons
|
||||||
|
compiler.cfg.instructions
|
||||||
compiler.cfg.registers
|
compiler.cfg.registers
|
||||||
compiler.cfg.value-numbering.math
|
compiler.cfg.value-numbering.math
|
||||||
compiler.cfg.value-numbering.graph
|
compiler.cfg.value-numbering.graph
|
||||||
|
@ -34,6 +37,23 @@ IN: compiler.cfg.value-numbering.comparisons
|
||||||
[ src1>> vreg>integer ] [ src2>> ] [ cc>> ] tri
|
[ src1>> vreg>integer ] [ src2>> ] [ cc>> ] tri
|
||||||
[ <=> ] dip evaluate-cc ;
|
[ <=> ] dip evaluate-cc ;
|
||||||
|
|
||||||
|
: fold-test-imm? ( insn -- ? )
|
||||||
|
src1>> vreg>insn ##load-integer? ;
|
||||||
|
|
||||||
|
: evaluate-test-imm ( insn -- ? )
|
||||||
|
[ src1>> vreg>integer ] [ src2>> ] [ cc>> ] tri
|
||||||
|
[ bitand ] dip {
|
||||||
|
{ cc= [ 0 = ] }
|
||||||
|
{ cc/= [ 0 = not ] }
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
: rewrite-into-test? ( insn -- ? )
|
||||||
|
{
|
||||||
|
[ drop test-instruction? ]
|
||||||
|
[ cc>> { cc= cc/= } member-eq? ]
|
||||||
|
[ src2>> 0 = ]
|
||||||
|
} 1&& ;
|
||||||
|
|
||||||
: >compare< ( insn -- in1 in2 cc )
|
: >compare< ( insn -- in1 in2 cc )
|
||||||
[ src1>> ] [ src2>> ] [ cc>> ] tri ; inline
|
[ src1>> ] [ src2>> ] [ cc>> ] tri ; inline
|
||||||
|
|
||||||
|
@ -50,6 +70,8 @@ UNION: scalar-compare-insn
|
||||||
##compare-imm
|
##compare-imm
|
||||||
##compare-integer
|
##compare-integer
|
||||||
##compare-integer-imm
|
##compare-integer-imm
|
||||||
|
##test
|
||||||
|
##test-imm
|
||||||
##compare-float-unordered
|
##compare-float-unordered
|
||||||
##compare-float-ordered ;
|
##compare-float-ordered ;
|
||||||
|
|
||||||
|
@ -68,6 +90,8 @@ UNION: general-compare-insn scalar-compare-insn ##test-vector ;
|
||||||
{ [ dup ##compare-imm? ] [ >compare< \ ##compare-imm-branch new-insn ] }
|
{ [ dup ##compare-imm? ] [ >compare< \ ##compare-imm-branch new-insn ] }
|
||||||
{ [ dup ##compare-integer? ] [ >compare< \ ##compare-integer-branch new-insn ] }
|
{ [ dup ##compare-integer? ] [ >compare< \ ##compare-integer-branch new-insn ] }
|
||||||
{ [ dup ##compare-integer-imm? ] [ >compare< \ ##compare-integer-imm-branch new-insn ] }
|
{ [ dup ##compare-integer-imm? ] [ >compare< \ ##compare-integer-imm-branch new-insn ] }
|
||||||
|
{ [ dup ##test? ] [ >compare< \ ##test-branch new-insn ] }
|
||||||
|
{ [ dup ##test-imm? ] [ >compare< \ ##test-imm-branch new-insn ] }
|
||||||
{ [ dup ##compare-float-unordered? ] [ >compare< \ ##compare-float-unordered-branch new-insn ] }
|
{ [ dup ##compare-float-unordered? ] [ >compare< \ ##compare-float-unordered-branch new-insn ] }
|
||||||
{ [ dup ##compare-float-ordered? ] [ >compare< \ ##compare-float-ordered-branch new-insn ] }
|
{ [ dup ##compare-float-ordered? ] [ >compare< \ ##compare-float-ordered-branch new-insn ] }
|
||||||
{ [ dup ##test-vector? ] [ >test-vector< \ ##test-vector-branch new-insn ] }
|
{ [ dup ##test-vector? ] [ >test-vector< \ ##test-vector-branch new-insn ] }
|
||||||
|
@ -81,6 +105,9 @@ UNION: general-compare-insn scalar-compare-insn ##test-vector ;
|
||||||
: fold-compare-imm-branch ( insn -- insn/f )
|
: fold-compare-imm-branch ( insn -- insn/f )
|
||||||
evaluate-compare-imm fold-branch ;
|
evaluate-compare-imm fold-branch ;
|
||||||
|
|
||||||
|
: >test-branch ( insn -- insn )
|
||||||
|
[ src1>> ] [ src1>> ] [ cc>> ] tri \ ##test-branch new-insn ;
|
||||||
|
|
||||||
M: ##compare-imm-branch rewrite
|
M: ##compare-imm-branch rewrite
|
||||||
{
|
{
|
||||||
{ [ dup rewrite-boolean-comparison? ] [ rewrite-boolean-comparison ] }
|
{ [ dup rewrite-boolean-comparison? ] [ rewrite-boolean-comparison ] }
|
||||||
|
@ -94,6 +121,16 @@ M: ##compare-imm-branch rewrite
|
||||||
M: ##compare-integer-imm-branch rewrite
|
M: ##compare-integer-imm-branch rewrite
|
||||||
{
|
{
|
||||||
{ [ dup fold-compare-integer-imm? ] [ fold-compare-integer-imm-branch ] }
|
{ [ dup fold-compare-integer-imm? ] [ fold-compare-integer-imm-branch ] }
|
||||||
|
{ [ dup rewrite-into-test? ] [ >test-branch ] }
|
||||||
|
[ drop f ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
: fold-test-imm-branch ( insn -- insn/f )
|
||||||
|
evaluate-test-imm fold-branch ;
|
||||||
|
|
||||||
|
M: ##test-imm-branch rewrite
|
||||||
|
{
|
||||||
|
{ [ dup fold-test-imm? ] [ fold-test-imm-branch ] }
|
||||||
[ drop f ]
|
[ drop f ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
|
@ -184,6 +221,8 @@ M: ##compare-integer rewrite
|
||||||
{ [ dup ##compare-imm? ] [ >compare< next-vreg \ ##compare-imm new-insn ] }
|
{ [ dup ##compare-imm? ] [ >compare< next-vreg \ ##compare-imm new-insn ] }
|
||||||
{ [ dup ##compare-integer? ] [ >compare< next-vreg \ ##compare-integer new-insn ] }
|
{ [ dup ##compare-integer? ] [ >compare< next-vreg \ ##compare-integer new-insn ] }
|
||||||
{ [ dup ##compare-integer-imm? ] [ >compare< next-vreg \ ##compare-integer-imm new-insn ] }
|
{ [ dup ##compare-integer-imm? ] [ >compare< next-vreg \ ##compare-integer-imm new-insn ] }
|
||||||
|
{ [ dup ##test? ] [ >compare< next-vreg \ ##test new-insn ] }
|
||||||
|
{ [ dup ##test-imm? ] [ >compare< next-vreg \ ##test-imm new-insn ] }
|
||||||
{ [ dup ##compare-float-unordered? ] [ >compare< next-vreg \ ##compare-float-unordered new-insn ] }
|
{ [ dup ##compare-float-unordered? ] [ >compare< next-vreg \ ##compare-float-unordered new-insn ] }
|
||||||
{ [ dup ##compare-float-ordered? ] [ >compare< next-vreg \ ##compare-float-ordered new-insn ] }
|
{ [ dup ##compare-float-ordered? ] [ >compare< next-vreg \ ##compare-float-ordered new-insn ] }
|
||||||
} cond
|
} cond
|
||||||
|
@ -202,8 +241,68 @@ M: ##compare-imm rewrite
|
||||||
: fold-compare-integer-imm ( insn -- insn' )
|
: fold-compare-integer-imm ( insn -- insn' )
|
||||||
dup evaluate-compare-integer-imm >boolean-insn ;
|
dup evaluate-compare-integer-imm >boolean-insn ;
|
||||||
|
|
||||||
|
: >test ( insn -- insn' )
|
||||||
|
{ [ dst>> ] [ src1>> ] [ src1>> ] [ cc>> ] [ temp>> ] } cleave
|
||||||
|
\ ##test new-insn ;
|
||||||
|
|
||||||
M: ##compare-integer-imm rewrite
|
M: ##compare-integer-imm rewrite
|
||||||
{
|
{
|
||||||
{ [ dup fold-compare-integer-imm? ] [ fold-compare-integer-imm ] }
|
{ [ dup fold-compare-integer-imm? ] [ fold-compare-integer-imm ] }
|
||||||
|
{ [ dup rewrite-into-test? ] [ >test ] }
|
||||||
|
[ drop f ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
: (simplify-test) ( insn -- src1 src2 cc )
|
||||||
|
[ src1>> vreg>insn [ src1>> ] [ src2>> ] bi ] [ cc>> ] bi ; inline
|
||||||
|
|
||||||
|
: simplify-test ( insn -- insn )
|
||||||
|
dup (simplify-test) drop [ >>src1 ] [ >>src2 ] bi* ; inline
|
||||||
|
|
||||||
|
: simplify-test-branch ( insn -- insn )
|
||||||
|
dup (simplify-test) drop [ >>src1 ] [ >>src2 ] bi* ; inline
|
||||||
|
|
||||||
|
: (simplify-test-imm) ( insn -- src1 src2 cc )
|
||||||
|
[ src1>> vreg>insn [ src1>> ] [ src2>> ] bi ] [ cc>> ] bi ; inline
|
||||||
|
|
||||||
|
: simplify-test-imm ( insn -- insn )
|
||||||
|
[ dst>> ] [ (simplify-test-imm) ] [ temp>> ] tri \ ##test-imm new-insn ; inline
|
||||||
|
|
||||||
|
: simplify-test-imm-branch ( insn -- insn )
|
||||||
|
(simplify-test-imm) \ ##test-imm-branch new-insn ; inline
|
||||||
|
|
||||||
|
: >test-imm ( insn ? -- insn' )
|
||||||
|
(>compare-imm) [ vreg>integer ] dip next-vreg
|
||||||
|
\ ##test-imm new-insn ; inline
|
||||||
|
|
||||||
|
: >test-imm-branch ( insn ? -- insn' )
|
||||||
|
(>compare-imm-branch) [ vreg>integer ] dip
|
||||||
|
\ ##test-imm-branch new-insn ; inline
|
||||||
|
|
||||||
|
M: ##test rewrite
|
||||||
|
{
|
||||||
|
{ [ dup src1>> vreg>insn ##load-integer? ] [ t >test-imm ] }
|
||||||
|
{ [ dup src2>> vreg>insn ##load-integer? ] [ f >test-imm ] }
|
||||||
|
{ [ dup diagonal? not ] [ drop f ] }
|
||||||
|
{ [ dup src1>> vreg>insn ##and? ] [ simplify-test ] }
|
||||||
|
{ [ dup src1>> vreg>insn ##and-imm? ] [ simplify-test-imm ] }
|
||||||
|
[ drop f ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
M: ##test-branch rewrite
|
||||||
|
{
|
||||||
|
{ [ dup src1>> vreg>insn ##load-integer? ] [ t >test-imm-branch ] }
|
||||||
|
{ [ dup src2>> vreg>insn ##load-integer? ] [ f >test-imm-branch ] }
|
||||||
|
{ [ dup diagonal? not ] [ drop f ] }
|
||||||
|
{ [ dup src1>> vreg>insn ##and? ] [ simplify-test-branch ] }
|
||||||
|
{ [ dup src1>> vreg>insn ##and-imm? ] [ simplify-test-imm-branch ] }
|
||||||
|
[ drop f ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
|
: fold-test-imm ( insn -- insn' )
|
||||||
|
dup evaluate-test-imm >boolean-insn ;
|
||||||
|
|
||||||
|
M: ##test-imm rewrite
|
||||||
|
{
|
||||||
|
{ [ dup fold-test-imm? ] [ fold-test-imm ] }
|
||||||
[ drop f ]
|
[ drop f ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
|
@ -18,6 +18,8 @@ IN: compiler.cfg.value-numbering.tests
|
||||||
[ ##compare-integer-imm? ]
|
[ ##compare-integer-imm? ]
|
||||||
[ ##compare-float-unordered? ]
|
[ ##compare-float-unordered? ]
|
||||||
[ ##compare-float-ordered? ]
|
[ ##compare-float-ordered? ]
|
||||||
|
[ ##test? ]
|
||||||
|
[ ##test-imm? ]
|
||||||
[ ##test-vector? ]
|
[ ##test-vector? ]
|
||||||
[ ##test-vector-branch? ]
|
[ ##test-vector-branch? ]
|
||||||
} 1|| [ f >>temp ] when
|
} 1|| [ f >>temp ] when
|
||||||
|
@ -265,6 +267,36 @@ cpu x86.64? [
|
||||||
} value-numbering-step trim-temps
|
} value-numbering-step trim-temps
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 29 D -1 }
|
||||||
|
T{ ##peek f 30 D -2 }
|
||||||
|
T{ ##test f 33 29 30 cc= }
|
||||||
|
T{ ##test-branch f 29 30 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 29 D -1 }
|
||||||
|
T{ ##peek f 30 D -2 }
|
||||||
|
T{ ##test f 33 29 30 cc= }
|
||||||
|
T{ ##compare-imm-branch f 33 f cc/= }
|
||||||
|
} value-numbering-step trim-temps
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 29 D -1 }
|
||||||
|
T{ ##test-imm f 33 29 30 cc= }
|
||||||
|
T{ ##test-imm-branch f 29 30 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 29 D -1 }
|
||||||
|
T{ ##test-imm f 33 29 30 cc= }
|
||||||
|
T{ ##compare-imm-branch f 33 f cc/= }
|
||||||
|
} value-numbering-step trim-temps
|
||||||
|
] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
T{ ##peek f 1 D -1 }
|
T{ ##peek f 1 D -1 }
|
||||||
|
@ -995,6 +1027,217 @@ cpu x86.32? [
|
||||||
} value-numbering-step
|
} value-numbering-step
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##load-integer f 1 12 }
|
||||||
|
T{ ##load-reference f 3 t }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##load-integer f 1 12 }
|
||||||
|
T{ ##test-imm f 3 1 13 cc/= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##load-integer f 1 15 }
|
||||||
|
T{ ##load-reference f 3 f }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##load-integer f 1 15 }
|
||||||
|
T{ ##test-imm f 3 1 16 cc/= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##load-integer f 1 12 }
|
||||||
|
T{ ##load-reference f 3 f }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##load-integer f 1 12 }
|
||||||
|
T{ ##test-imm f 3 1 13 cc= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##load-integer f 1 15 }
|
||||||
|
T{ ##load-reference f 3 t }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##load-integer f 1 15 }
|
||||||
|
T{ ##test-imm f 3 1 16 cc= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
! Rewriting a ##test of an ##and into a ##test
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##peek f 1 D 1 }
|
||||||
|
T{ ##and f 2 0 1 }
|
||||||
|
T{ ##test f 3 0 1 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##peek f 1 D 1 }
|
||||||
|
T{ ##and f 2 0 1 }
|
||||||
|
T{ ##test f 3 2 2 cc= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##and-imm f 2 0 12 }
|
||||||
|
T{ ##test-imm f 3 0 12 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##and-imm f 2 0 12 }
|
||||||
|
T{ ##test f 3 2 2 cc= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
! Rewriting ##test into ##test-imm
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##load-integer f 1 10 }
|
||||||
|
T{ ##test-imm f 2 0 10 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##load-integer f 1 10 }
|
||||||
|
T{ ##test f 2 0 1 cc= }
|
||||||
|
} value-numbering-step trim-temps
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##load-integer f 1 10 }
|
||||||
|
T{ ##test-imm f 2 0 10 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##load-integer f 1 10 }
|
||||||
|
T{ ##test f 2 1 0 cc= }
|
||||||
|
} value-numbering-step trim-temps
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##load-integer f 1 10 }
|
||||||
|
T{ ##test-imm-branch f 0 10 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##load-integer f 1 10 }
|
||||||
|
T{ ##test-branch f 0 1 cc= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##load-integer f 1 10 }
|
||||||
|
T{ ##test-imm-branch f 0 10 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##load-integer f 1 10 }
|
||||||
|
T{ ##test-branch f 1 0 cc= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
! Rewriting ##compare into ##test
|
||||||
|
cpu x86? [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##test f 1 0 0 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##compare-integer-imm f 1 0 0 cc= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##test f 1 0 0 cc/= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##compare-integer-imm f 1 0 0 cc/= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##compare-integer-imm f 1 0 0 cc<= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##compare-integer-imm f 1 0 0 cc<= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##test-branch f 0 0 cc= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##compare-integer-imm-branch f 0 0 cc= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##test-branch f 0 0 cc/= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##compare-integer-imm-branch f 0 0 cc/= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##compare-integer-imm-branch f 0 0 cc<= }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##peek f 0 D 0 }
|
||||||
|
T{ ##compare-integer-imm-branch f 0 0 cc<= }
|
||||||
|
} value-numbering-step
|
||||||
|
] unit-test
|
||||||
|
] when
|
||||||
|
|
||||||
! Reassociation
|
! Reassociation
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
|
|
@ -242,6 +242,8 @@ CODEGEN: ##write-barrier %write-barrier
|
||||||
CODEGEN: ##write-barrier-imm %write-barrier-imm
|
CODEGEN: ##write-barrier-imm %write-barrier-imm
|
||||||
CODEGEN: ##compare %compare
|
CODEGEN: ##compare %compare
|
||||||
CODEGEN: ##compare-imm %compare-imm
|
CODEGEN: ##compare-imm %compare-imm
|
||||||
|
CODEGEN: ##test %test
|
||||||
|
CODEGEN: ##test-imm %test-imm
|
||||||
CODEGEN: ##compare-integer %compare
|
CODEGEN: ##compare-integer %compare
|
||||||
CODEGEN: ##compare-integer-imm %compare-integer-imm
|
CODEGEN: ##compare-integer-imm %compare-integer-imm
|
||||||
CODEGEN: ##compare-float-ordered %compare-float-ordered
|
CODEGEN: ##compare-float-ordered %compare-float-ordered
|
||||||
|
@ -268,6 +270,8 @@ CONDITIONAL: ##compare-branch %compare-branch
|
||||||
CONDITIONAL: ##compare-imm-branch %compare-imm-branch
|
CONDITIONAL: ##compare-imm-branch %compare-imm-branch
|
||||||
CONDITIONAL: ##compare-integer-branch %compare-branch
|
CONDITIONAL: ##compare-integer-branch %compare-branch
|
||||||
CONDITIONAL: ##compare-integer-imm-branch %compare-integer-imm-branch
|
CONDITIONAL: ##compare-integer-imm-branch %compare-integer-imm-branch
|
||||||
|
CONDITIONAL: ##test-branch %test-branch
|
||||||
|
CONDITIONAL: ##test-imm-branch %test-imm-branch
|
||||||
CONDITIONAL: ##compare-float-ordered-branch %compare-float-ordered-branch
|
CONDITIONAL: ##compare-float-ordered-branch %compare-float-ordered-branch
|
||||||
CONDITIONAL: ##compare-float-unordered-branch %compare-float-unordered-branch
|
CONDITIONAL: ##compare-float-unordered-branch %compare-float-unordered-branch
|
||||||
CONDITIONAL: ##test-vector-branch %test-vector-branch
|
CONDITIONAL: ##test-vector-branch %test-vector-branch
|
||||||
|
|
|
@ -475,15 +475,23 @@ HOOK: %call-gc cpu ( gc-roots -- )
|
||||||
HOOK: %prologue cpu ( n -- )
|
HOOK: %prologue cpu ( n -- )
|
||||||
HOOK: %epilogue cpu ( n -- )
|
HOOK: %epilogue cpu ( n -- )
|
||||||
|
|
||||||
HOOK: %compare cpu ( dst temp cc src1 src2 -- )
|
HOOK: test-instruction? cpu ( -- ? )
|
||||||
HOOK: %compare-imm cpu ( dst temp cc src1 src2 -- )
|
|
||||||
HOOK: %compare-integer-imm cpu ( dst temp cc src1 src2 -- )
|
M: object test-instruction? f ;
|
||||||
HOOK: %compare-float-ordered cpu ( dst temp cc src1 src2 -- )
|
|
||||||
HOOK: %compare-float-unordered cpu ( dst temp cc src1 src2 -- )
|
HOOK: %compare cpu ( dst src1 src2 cc temp -- )
|
||||||
|
HOOK: %compare-imm cpu ( dst src1 src2 cc temp -- )
|
||||||
|
HOOK: %compare-integer-imm cpu ( dst src1 src2 cc temp -- )
|
||||||
|
HOOK: %test cpu ( dst src1 src2 cc temp -- )
|
||||||
|
HOOK: %test-imm cpu ( dst src1 src2 cc temp -- )
|
||||||
|
HOOK: %compare-float-ordered cpu ( dst src1 src2 cc temp -- )
|
||||||
|
HOOK: %compare-float-unordered cpu ( dst src1 src2 cc temp -- )
|
||||||
|
|
||||||
HOOK: %compare-branch cpu ( label cc src1 src2 -- )
|
HOOK: %compare-branch cpu ( label cc src1 src2 -- )
|
||||||
HOOK: %compare-imm-branch cpu ( label cc src1 src2 -- )
|
HOOK: %compare-imm-branch cpu ( label cc src1 src2 -- )
|
||||||
HOOK: %compare-integer-imm-branch cpu ( label cc src1 src2 -- )
|
HOOK: %compare-integer-imm-branch cpu ( label cc src1 src2 -- )
|
||||||
|
HOOK: %test-branch cpu ( label cc src1 src2 -- )
|
||||||
|
HOOK: %test-imm-branch cpu ( label cc src1 src2 -- )
|
||||||
HOOK: %compare-float-ordered-branch cpu ( label cc src1 src2 -- )
|
HOOK: %compare-float-ordered-branch cpu ( label cc src1 src2 -- )
|
||||||
HOOK: %compare-float-unordered-branch cpu ( label cc src1 src2 -- )
|
HOOK: %compare-float-unordered-branch cpu ( label cc src1 src2 -- )
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,8 @@ M: x86 complex-addressing? t ;
|
||||||
|
|
||||||
M: x86 fused-unboxing? t ;
|
M: x86 fused-unboxing? t ;
|
||||||
|
|
||||||
|
M: x86 test-instruction? t ;
|
||||||
|
|
||||||
M: x86 immediate-store? immediate-comparand? ;
|
M: x86 immediate-store? immediate-comparand? ;
|
||||||
|
|
||||||
M: x86 %load-immediate dup 0 = [ drop dup XOR ] [ MOV ] if ;
|
M: x86 %load-immediate dup 0 = [ drop dup XOR ] [ MOV ] if ;
|
||||||
|
@ -525,28 +527,30 @@ M:: x86 %compare ( dst src1 src2 cc temp -- )
|
||||||
src1 src2 CMP
|
src1 src2 CMP
|
||||||
dst cc temp %boolean ;
|
dst cc temp %boolean ;
|
||||||
|
|
||||||
: use-test? ( src1 src2 cc -- ? )
|
M:: x86 %test ( dst src1 src2 cc temp -- )
|
||||||
[ register? ] [ 0 = ] [ { cc= cc/= } member? ] tri* and and ;
|
src1 src2 TEST
|
||||||
|
dst cc temp %boolean ;
|
||||||
|
|
||||||
: (%compare-tagged) ( src1 src2 -- )
|
: (%compare-tagged) ( src1 src2 -- )
|
||||||
[ HEX: ffffffff CMP ] dip rc-absolute rel-literal ;
|
[ HEX: ffffffff CMP ] dip rc-absolute rel-literal ;
|
||||||
|
|
||||||
: (%compare-integer-imm) ( src1 src2 cc -- )
|
|
||||||
3dup use-test? [ 2drop dup TEST ] [ drop CMP ] if ;
|
|
||||||
|
|
||||||
M:: x86 %compare-integer-imm ( dst src1 src2 cc temp -- )
|
M:: x86 %compare-integer-imm ( dst src1 src2 cc temp -- )
|
||||||
src1 src2 cc (%compare-integer-imm)
|
src1 src2 CMP
|
||||||
dst cc temp %boolean ;
|
dst cc temp %boolean ;
|
||||||
|
|
||||||
: (%compare-imm) ( src1 src2 cc -- )
|
M:: x86 %test-imm ( dst src1 src2 cc temp -- )
|
||||||
|
src1 src2 TEST
|
||||||
|
dst cc temp %boolean ;
|
||||||
|
|
||||||
|
: (%compare-imm) ( src1 src2 -- )
|
||||||
{
|
{
|
||||||
{ [ over fixnum? ] [ [ tag-fixnum ] dip (%compare-integer-imm) ] }
|
{ [ dup fixnum? ] [ tag-fixnum CMP ] }
|
||||||
{ [ over not ] [ 2drop \ f type-number CMP ] }
|
{ [ dup not ] [ drop \ f type-number CMP ] }
|
||||||
[ drop (%compare-tagged) ]
|
[ (%compare-tagged) ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
M:: x86 %compare-imm ( dst src1 src2 cc temp -- )
|
M:: x86 %compare-imm ( dst src1 src2 cc temp -- )
|
||||||
src1 src2 cc (%compare-imm)
|
src1 src2 (%compare-imm)
|
||||||
dst cc temp %boolean ;
|
dst cc temp %boolean ;
|
||||||
|
|
||||||
: %branch ( label cc -- )
|
: %branch ( label cc -- )
|
||||||
|
@ -564,11 +568,19 @@ M:: x86 %compare-branch ( label src1 src2 cc -- )
|
||||||
label cc %branch ;
|
label cc %branch ;
|
||||||
|
|
||||||
M:: x86 %compare-integer-imm-branch ( label src1 src2 cc -- )
|
M:: x86 %compare-integer-imm-branch ( label src1 src2 cc -- )
|
||||||
src1 src2 cc (%compare-integer-imm)
|
src1 src2 CMP
|
||||||
|
label cc %branch ;
|
||||||
|
|
||||||
|
M:: x86 %test-branch ( label src1 src2 cc -- )
|
||||||
|
src1 src2 TEST
|
||||||
|
label cc %branch ;
|
||||||
|
|
||||||
|
M:: x86 %test-imm-branch ( label src1 src2 cc -- )
|
||||||
|
src1 src2 TEST
|
||||||
label cc %branch ;
|
label cc %branch ;
|
||||||
|
|
||||||
M:: x86 %compare-imm-branch ( label src1 src2 cc -- )
|
M:: x86 %compare-imm-branch ( label src1 src2 cc -- )
|
||||||
src1 src2 cc (%compare-imm)
|
src1 src2 (%compare-imm)
|
||||||
label cc %branch ;
|
label cc %branch ;
|
||||||
|
|
||||||
M: x86 %add-float double-rep two-operand ADDSD ;
|
M: x86 %add-float double-rep two-operand ADDSD ;
|
||||||
|
|
Loading…
Reference in New Issue