cc/< cc/<= cc/= cc/> cc/>= cc/<> cc/<>= ;
SYMBOLS:
- vcc-all vcc-any vcc-none ;
+ vcc-all vcc-notall vcc-any vcc-none ;
: negate-cc ( cc -- cc' )
H{
{ cc/<>= cc<>= }
} at ;
+: negate-vcc ( cc -- cc' )
+ H{
+ { vcc-all vcc-notall }
+ { vcc-any vcc-none }
+ { vcc-none vcc-any }
+ { vcc-notall vcc-all }
+ } at ;
+
: swap-cc ( cc -- cc' )
H{
{ cc< cc> }
PURE-INSN: ##test-vector
def: dst/int-rep
-use: src
+use: src1
+temp: temp/int-rep
+literal: rep vcc ;
+
+INSN: ##test-vector-branch
+use: src1
+temp: temp/int-rep
+literal: rep vcc ;
+
+INSN: _test-vector-branch
+literal: label
+use: src1
temp: temp/int-rep
literal: rep vcc ;
! See http://factorcode.org/license.txt for BSD license.
USING: kernel math accessors sequences namespaces make
combinators assocs arrays locals layouts hashtables
-cpu.architecture
+cpu.architecture generalizations
compiler.cfg
compiler.cfg.comparisons
compiler.cfg.stack-frame
: successors ( bb -- first second ) successors>> first2 ; inline
+:: conditional ( bb insn n conditional-quot negate-cc-quot -- bb successor label ... )
+ bb insn
+ conditional-quot
+ [ drop dup successors>> second useless-branch? ] 2bi
+ [ [ swap block-number ] n ndip ]
+ [ [ block-number ] n ndip negate-cc-quot call ] if ; inline
+
: (binary-conditional) ( bb insn -- bb successor1 successor2 src1 src2 cc )
[ dup successors ]
[ [ src1>> ] [ src2>> ] [ cc>> ] tri ] bi* ; inline
: binary-conditional ( bb insn -- bb successor label2 src1 src2 cc )
- [ (binary-conditional) ]
- [ drop dup successors>> second useless-branch? ] 2bi
- [ [ swap block-number ] 3dip ] [ [ block-number ] 3dip negate-cc ] if ;
+ 3 [ (binary-conditional) ] [ negate-cc ] conditional ;
+
+: (test-vector-conditional) ( bb insn -- bb successor1 successor2 src1 temp rep vcc )
+ [ dup successors ]
+ [ { [ src1>> ] [ temp>> ] [ rep>> ] [ vcc>> ] } cleave ] bi* ; inline
+
+: test-vector-conditional ( bb insn -- bb successor label src1 temp rep vcc )
+ 4 [ (test-vector-conditional) ] [ negate-vcc ] conditional ;
M: ##compare-branch linearize-insn
binary-conditional _compare-branch emit-branch ;
M: ##compare-float-unordered-branch linearize-insn
binary-conditional _compare-float-unordered-branch emit-branch ;
+M: ##test-vector-branch linearize-insn
+ test-vector-conditional _test-vector-branch emit-branch ;
+
: overflow-conditional ( bb insn -- bb successor label2 dst src1 src2 )
[ dup successors block-number ]
[ [ dst>> ] [ src1>> ] [ src2>> ] tri ] bi* ; inline
[ compare-imm-expr? ]
[ compare-float-unordered-expr? ]
[ compare-float-ordered-expr? ]
+ [ test-vector-expr? ]
} 1|| ;
: rewrite-boolean-comparison? ( insn -- ? )
: >compare-imm-expr< ( expr -- in1 in2 cc )
[ src1>> vn>vreg ] [ src2>> vn>constant ] [ cc>> ] tri ; inline
+: >test-vector-expr< ( expr -- src1 temp rep vcc )
+ {
+ [ src1>> vn>vreg ]
+ [ drop next-vreg ]
+ [ rep>> ]
+ [ vcc>> ]
+ } cleave ; inline
+
: rewrite-boolean-comparison ( expr -- insn )
src1>> vreg>expr {
{ [ dup compare-expr? ] [ >compare-expr< \ ##compare-branch new-insn ] }
{ [ dup compare-imm-expr? ] [ >compare-imm-expr< \ ##compare-imm-branch new-insn ] }
{ [ dup compare-float-unordered-expr? ] [ >compare-expr< \ ##compare-float-unordered-branch new-insn ] }
{ [ dup compare-float-ordered-expr? ] [ >compare-expr< \ ##compare-float-ordered-branch new-insn ] }
+ { [ dup test-vector-expr? ] [ >test-vector-expr< \ ##test-vector-branch new-insn ] }
} cond ;
: tag-fixnum-expr? ( expr -- ? )
[ ##compare-imm? ]
[ ##compare-float-unordered? ]
[ ##compare-float-ordered? ]
+ [ ##test-vector? ]
+ [ ##test-vector-branch? ]
} 1|| [ f >>temp ] when
] map ;
} value-numbering-step trim-temps
] unit-test
+[
+ {
+ T{ ##peek f 1 D -1 }
+ T{ ##unbox-vector f 1111 1 float-4-rep }
+ T{ ##test-vector f 1 1111 f float-4-rep vcc-any }
+ T{ ##test-vector-branch f 1111 f float-4-rep vcc-any }
+ }
+] [
+ {
+ T{ ##peek f 1 D -1 }
+ T{ ##unbox-vector f 1111 1 float-4-rep }
+ T{ ##test-vector f 1 1111 2 float-4-rep vcc-any }
+ T{ ##compare-imm-branch f 1 5 cc/= }
+ } value-numbering-step trim-temps
+] unit-test
+
! Immediate operand conversion
[
{
CODEGEN: _compare-imm-branch %compare-imm-branch
CODEGEN: _compare-float-ordered-branch %compare-float-ordered-branch
CODEGEN: _compare-float-unordered-branch %compare-float-unordered-branch
+CODEGEN: _test-vector-branch %test-vector-branch
CODEGEN: _dispatch %dispatch
CODEGEN: _spill %spill
CODEGEN: _reload %reload
HOOK: %gather-vector-4 cpu ( dst src1 src2 src3 src4 rep -- )
HOOK: %shuffle-vector cpu ( dst src shuffle rep -- )
HOOK: %compare-vector cpu ( dst src1 src2 rep cc -- )
-HOOK: %test-vector cpu ( dst src temp rep vcc -- )
+HOOK: %test-vector cpu ( dst src1 temp rep vcc -- )
+HOOK: %test-vector-branch cpu ( label src1 temp rep vcc -- )
HOOK: %add-vector cpu ( dst src1 src2 rep -- )
HOOK: %saturated-add-vector cpu ( dst src1 src2 rep -- )
HOOK: %add-sub-vector cpu ( dst src1 src2 rep -- )
{ sse4.1? { longlong-2-rep ulonglong-2-rep } }
} available-reps ;
-:: (%test-vector) ( dst temp mask vcc -- )
+:: %test-vector-mask ( dst temp mask vcc -- )
vcc {
- { vcc-any [ dst dst TEST dst temp \ CMOVNE %boolean ] }
- { vcc-none [ dst dst TEST dst temp \ CMOVE %boolean ] }
- { vcc-all [ dst mask CMP dst temp \ CMOVE %boolean ] }
+ { vcc-any [ dst dst TEST dst temp \ CMOVNE %boolean ] }
+ { vcc-none [ dst dst TEST dst temp \ CMOVE %boolean ] }
+ { vcc-all [ dst mask CMP dst temp \ CMOVE %boolean ] }
+ { vcc-notall [ dst mask CMP dst temp \ CMOVNE %boolean ] }
} case ;
-M:: x86 %test-vector ( dst src temp rep vcc -- )
- dst src rep {
+: %move-vector-mask ( dst src rep -- mask )
+ {
{ double-2-rep [ MOVMSKPD HEX: 3 ] }
{ float-4-rep [ MOVMSKPS HEX: f ] }
[ drop PMOVMSKB HEX: ffff ]
- } case :> mask
- dst temp mask vcc (%test-vector) ;
+ } case ;
+
+M:: x86 %test-vector ( dst src temp rep vcc -- )
+ dst src rep %move-vector-mask :> mask
+ dst temp mask vcc %test-vector-mask ;
+
+:: %test-vector-mask-branch ( label temp mask vcc -- )
+ vcc {
+ { vcc-any [ temp temp TEST label JNE ] }
+ { vcc-none [ temp temp TEST label JE ] }
+ { vcc-all [ temp mask CMP label JE ] }
+ { vcc-notall [ temp mask CMP label JNE ] }
+ } case ;
+
+M:: x86 %test-vector-branch ( label src temp rep vcc -- )
+ temp src rep %move-vector-mask :> mask
+ label temp mask vcc %test-vector-mask-branch ;
M: x86 %test-vector-reps
{