diff --git a/basis/alien/arrays/arrays.factor b/basis/alien/arrays/arrays.factor index 94472e8261..727492edb1 100644 --- a/basis/alien/arrays/arrays.factor +++ b/basis/alien/arrays/arrays.factor @@ -8,6 +8,8 @@ UNION: value-type array struct-type ; M: array c-type ; +M: array c-type-class drop object ; + M: array heap-size unclip heap-size [ * ] reduce ; M: array c-type-align first c-type-align ; diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor index 543af8dee8..46d63c3375 100644 --- a/basis/alien/c-types/c-types.factor +++ b/basis/alien/c-types/c-types.factor @@ -13,13 +13,15 @@ DEFER: *char : little-endian? ( -- ? ) 1 *char 1 = ; foldable TUPLE: c-type +class boxer boxer-quot unboxer unboxer-quot getter setter reg-class size align stack-align? ; : new-c-type ( class -- type ) new - int-regs >>reg-class ; + int-regs >>reg-class + object >>class ; : ( -- type ) \ c-type new-c-type ; @@ -63,6 +65,12 @@ M: string c-type ( name -- type ) ] ?if ] if ; +GENERIC: c-type-class ( name -- class ) + +M: c-type c-type-class class>> ; + +M: string c-type-class c-type c-type-class ; + GENERIC: c-type-boxer ( name -- boxer ) M: c-type c-type-boxer boxer>> ; @@ -306,6 +314,7 @@ M: long-long-type box-return ( type -- ) [ + c-ptr >>class [ alien-cell ] >>getter [ set-alien-cell ] >>setter bootstrap-cell >>size @@ -315,6 +324,7 @@ M: long-long-type box-return ( type -- ) "void*" define-primitive-type + integer >>class [ alien-signed-8 ] >>getter [ set-alien-signed-8 ] >>setter 8 >>size @@ -324,6 +334,7 @@ M: long-long-type box-return ( type -- ) "longlong" define-primitive-type + integer >>class [ alien-unsigned-8 ] >>getter [ set-alien-unsigned-8 ] >>setter 8 >>size @@ -333,6 +344,7 @@ M: long-long-type box-return ( type -- ) "ulonglong" define-primitive-type + integer >>class [ alien-signed-cell ] >>getter [ set-alien-signed-cell ] >>setter bootstrap-cell >>size @@ -342,6 +354,7 @@ M: long-long-type box-return ( type -- ) "long" define-primitive-type + integer >>class [ alien-unsigned-cell ] >>getter [ set-alien-unsigned-cell ] >>setter bootstrap-cell >>size @@ -351,6 +364,7 @@ M: long-long-type box-return ( type -- ) "ulong" define-primitive-type + integer >>class [ alien-signed-4 ] >>getter [ set-alien-signed-4 ] >>setter 4 >>size @@ -360,6 +374,7 @@ M: long-long-type box-return ( type -- ) "int" define-primitive-type + integer >>class [ alien-unsigned-4 ] >>getter [ set-alien-unsigned-4 ] >>setter 4 >>size @@ -369,6 +384,7 @@ M: long-long-type box-return ( type -- ) "uint" define-primitive-type + fixnum >>class [ alien-signed-2 ] >>getter [ set-alien-signed-2 ] >>setter 2 >>size @@ -378,6 +394,7 @@ M: long-long-type box-return ( type -- ) "short" define-primitive-type + fixnum >>class [ alien-unsigned-2 ] >>getter [ set-alien-unsigned-2 ] >>setter 2 >>size @@ -387,6 +404,7 @@ M: long-long-type box-return ( type -- ) "ushort" define-primitive-type + fixnum >>class [ alien-signed-1 ] >>getter [ set-alien-signed-1 ] >>setter 1 >>size @@ -396,6 +414,7 @@ M: long-long-type box-return ( type -- ) "char" define-primitive-type + fixnum >>class [ alien-unsigned-1 ] >>getter [ set-alien-unsigned-1 ] >>setter 1 >>size @@ -414,6 +433,7 @@ M: long-long-type box-return ( type -- ) "bool" define-primitive-type + float >>class [ alien-float ] >>getter [ [ >float ] 2dip set-alien-float ] >>setter 4 >>size @@ -425,6 +445,7 @@ M: long-long-type box-return ( type -- ) "float" define-primitive-type + float >>class [ alien-double ] >>getter [ [ >float ] 2dip set-alien-double ] >>setter 8 >>size diff --git a/basis/alien/strings/strings.factor b/basis/alien/strings/strings.factor index 70bbe773ee..b0faadb7fc 100644 --- a/basis/alien/strings/strings.factor +++ b/basis/alien/strings/strings.factor @@ -40,6 +40,9 @@ PREDICATE: string-type < pair M: string-type c-type ; +M: string-type c-type-class + drop object ; + M: string-type heap-size drop "void*" heap-size ; diff --git a/basis/alien/structs/structs.factor b/basis/alien/structs/structs.factor index adb25aa977..1131b1eecd 100644 --- a/basis/alien/structs/structs.factor +++ b/basis/alien/structs/structs.factor @@ -9,6 +9,8 @@ TUPLE: struct-type size align fields ; M: struct-type heap-size size>> ; +M: struct-type c-type-class drop object ; + M: struct-type c-type-align align>> ; M: struct-type c-type-stack-align? drop f ; diff --git a/basis/compiler/cfg/builder/builder.factor b/basis/compiler/cfg/builder/builder.factor index 7bad44f7a6..9ffe4a6aa0 100755 --- a/basis/compiler/cfg/builder/builder.factor +++ b/basis/compiler/cfg/builder/builder.factor @@ -21,8 +21,6 @@ IN: compiler.cfg.builder ! Convert tree SSA IR to CFG SSA IR. -: stop-iterating ( -- next ) end-basic-block f ; - SYMBOL: procedures SYMBOL: current-word SYMBOL: current-label @@ -211,7 +209,7 @@ M: #dispatch emit-node ! #call M: #call emit-node dup word>> dup "intrinsic" word-prop - [ emit-intrinsic iterate-next ] [ nip emit-call ] if ; + [ emit-intrinsic ] [ nip emit-call ] if ; ! #call-recursive M: #call-recursive emit-node label>> id>> emit-call ; @@ -262,7 +260,7 @@ M: #terminate emit-node drop stop-iterating ; : emit-alien-node ( node quot -- next ) [ params>> ] dip [ drop alien-stack-frame ] [ call ] 2bi - begin-basic-block iterate-next ; inline + ##branch begin-basic-block iterate-next ; inline M: #alien-invoke emit-node [ ##alien-invoke ] emit-alien-node ; diff --git a/basis/compiler/cfg/def-use/def-use.factor b/basis/compiler/cfg/def-use/def-use.factor index 7584931cf7..7e97961eb3 100644 --- a/basis/compiler/cfg/def-use/def-use.factor +++ b/basis/compiler/cfg/def-use/def-use.factor @@ -34,6 +34,7 @@ M: ##compare-imm-branch uses-vregs src1>> 1array ; M: ##dispatch uses-vregs src>> 1array ; M: ##alien-getter uses-vregs src>> 1array ; M: ##alien-setter uses-vregs [ src>> ] [ value>> ] bi 2array ; +M: ##fixnum-overflow uses-vregs [ src1>> ] [ src2>> ] bi 2array ; M: _conditional-branch uses-vregs [ src1>> ] [ src2>> ] bi 2array ; M: _compare-imm-branch uses-vregs src1>> 1array ; M: insn uses-vregs drop f ; @@ -43,6 +44,7 @@ UNION: vreg-insn ##write-barrier ##dispatch ##effect +##fixnum-overflow ##conditional-branch ##compare-imm-branch _conditional-branch diff --git a/basis/compiler/cfg/instructions/instructions.factor b/basis/compiler/cfg/instructions/instructions.factor index ce1f6b7e85..9e82851c12 100644 --- a/basis/compiler/cfg/instructions/instructions.factor +++ b/basis/compiler/cfg/instructions/instructions.factor @@ -92,6 +92,15 @@ INSN: ##shr-imm < ##binary-imm ; INSN: ##sar-imm < ##binary-imm ; INSN: ##not < ##unary ; +! Overflowing arithmetic +TUPLE: ##fixnum-overflow < insn src1 src2 ; +INSN: ##fixnum-add < ##fixnum-overflow ; +INSN: ##fixnum-add-tail < ##fixnum-overflow ; +INSN: ##fixnum-sub < ##fixnum-overflow ; +INSN: ##fixnum-sub-tail < ##fixnum-overflow ; +INSN: ##fixnum-mul < ##fixnum-overflow ; +INSN: ##fixnum-mul-tail < ##fixnum-overflow ; + : ##tag-fixnum ( dst src -- ) tag-bits get ##shl-imm ; inline : ##untag-fixnum ( dst src -- ) tag-bits get ##sar-imm ; inline diff --git a/basis/compiler/cfg/intrinsics/fixnum/fixnum.factor b/basis/compiler/cfg/intrinsics/fixnum/fixnum.factor index 04c9097725..68ee7489f8 100644 --- a/basis/compiler/cfg/intrinsics/fixnum/fixnum.factor +++ b/basis/compiler/cfg/intrinsics/fixnum/fixnum.factor @@ -3,10 +3,22 @@ USING: sequences accessors layouts kernel math namespaces combinators fry locals compiler.tree.propagation.info -compiler.cfg.stacks compiler.cfg.hats compiler.cfg.instructions -compiler.cfg.utilities ; +compiler.cfg.hats +compiler.cfg.stacks +compiler.cfg.iterator +compiler.cfg.instructions +compiler.cfg.utilities +compiler.cfg.registers ; IN: compiler.cfg.intrinsics.fixnum +: emit-both-fixnums? ( -- ) + D 0 ^^peek + D 1 ^^peek + ^^or + tag-mask get ^^and-imm + 0 cc= ^^compare-imm + ds-push ; + : (emit-fixnum-imm-op) ( infos insn -- dst ) ds-drop [ ds-pop ] @@ -64,3 +76,16 @@ IN: compiler.cfg.intrinsics.fixnum : emit-fixnum>bignum ( -- ) ds-pop ^^untag-fixnum ^^integer>bignum ds-push ; + +: emit-fixnum-overflow-op ( quot quot-tail -- next ) + [ 2inputs 1 ##inc-d ] 2dip + tail-call? [ + ##epilogue + nip call + stop-iterating + ] [ + drop call + ##branch + begin-basic-block + iterate-next + ] if ; inline diff --git a/basis/compiler/cfg/intrinsics/intrinsics.factor b/basis/compiler/cfg/intrinsics/intrinsics.factor index ef1cde337a..6c6c2955c9 100644 --- a/basis/compiler/cfg/intrinsics/intrinsics.factor +++ b/basis/compiler/cfg/intrinsics/intrinsics.factor @@ -8,7 +8,8 @@ compiler.cfg.intrinsics.alien compiler.cfg.intrinsics.allot compiler.cfg.intrinsics.fixnum compiler.cfg.intrinsics.float -compiler.cfg.intrinsics.slots ; +compiler.cfg.intrinsics.slots +compiler.cfg.iterator ; QUALIFIED: kernel QUALIFIED: arrays QUALIFIED: byte-arrays @@ -22,6 +23,9 @@ IN: compiler.cfg.intrinsics { kernel.private:tag + math.private:both-fixnums? + math.private:fixnum+ + math.private:fixnum- math.private:fixnum+fast math.private:fixnum-fast math.private:fixnum-bitand @@ -85,60 +89,67 @@ IN: compiler.cfg.intrinsics alien.accessors:set-alien-double } [ t "intrinsic" set-word-prop ] each ; -: emit-intrinsic ( node word -- ) +: enable-fixnum*-intrinsic ( -- ) + \ math.private:fixnum* t "intrinsic" set-word-prop ; + +: emit-intrinsic ( node word -- node/f ) { - { \ kernel.private:tag [ drop emit-tag ] } - { \ math.private:fixnum+fast [ [ ^^add ] [ ^^add-imm ] emit-fixnum-op ] } - { \ math.private:fixnum-fast [ [ ^^sub ] [ ^^sub-imm ] emit-fixnum-op ] } - { \ math.private:fixnum-bitand [ [ ^^and ] [ ^^and-imm ] emit-fixnum-op ] } - { \ math.private:fixnum-bitor [ [ ^^or ] [ ^^or-imm ] emit-fixnum-op ] } - { \ math.private:fixnum-bitxor [ [ ^^xor ] [ ^^xor-imm ] emit-fixnum-op ] } - { \ math.private:fixnum-shift-fast [ emit-fixnum-shift-fast ] } - { \ math.private:fixnum-bitnot [ drop emit-fixnum-bitnot ] } - { \ math.private:fixnum*fast [ emit-fixnum*fast ] } - { \ math.private:fixnum< [ cc< emit-fixnum-comparison ] } - { \ math.private:fixnum<= [ cc<= emit-fixnum-comparison ] } - { \ math.private:fixnum>= [ cc>= emit-fixnum-comparison ] } - { \ math.private:fixnum> [ cc> emit-fixnum-comparison ] } - { \ kernel:eq? [ cc= emit-fixnum-comparison ] } - { \ math.private:bignum>fixnum [ drop emit-bignum>fixnum ] } - { \ math.private:fixnum>bignum [ drop emit-fixnum>bignum ] } - { \ math.private:float+ [ drop [ ^^add-float ] emit-float-op ] } - { \ math.private:float- [ drop [ ^^sub-float ] emit-float-op ] } - { \ math.private:float* [ drop [ ^^mul-float ] emit-float-op ] } - { \ math.private:float/f [ drop [ ^^div-float ] emit-float-op ] } - { \ math.private:float< [ drop cc< emit-float-comparison ] } - { \ math.private:float<= [ drop cc<= emit-float-comparison ] } - { \ math.private:float>= [ drop cc>= emit-float-comparison ] } - { \ math.private:float> [ drop cc> emit-float-comparison ] } - { \ math.private:float= [ drop cc= emit-float-comparison ] } - { \ math.private:float>fixnum [ drop emit-float>fixnum ] } - { \ math.private:fixnum>float [ drop emit-fixnum>float ] } - { \ slots.private:slot [ emit-slot ] } - { \ slots.private:set-slot [ emit-set-slot ] } - { \ strings.private:string-nth [ drop emit-string-nth ] } - { \ classes.tuple.private: [ emit- ] } - { \ arrays: [ emit- ] } - { \ byte-arrays: [ emit- ] } - { \ math.private: [ emit-simple-allot ] } - { \ math.private: [ emit-simple-allot ] } - { \ kernel: [ emit-simple-allot ] } - { \ alien.accessors:alien-unsigned-1 [ 1 emit-alien-unsigned-getter ] } - { \ alien.accessors:set-alien-unsigned-1 [ 1 emit-alien-integer-setter ] } - { \ alien.accessors:alien-signed-1 [ 1 emit-alien-signed-getter ] } - { \ alien.accessors:set-alien-signed-1 [ 1 emit-alien-integer-setter ] } - { \ alien.accessors:alien-unsigned-2 [ 2 emit-alien-unsigned-getter ] } - { \ alien.accessors:set-alien-unsigned-2 [ 2 emit-alien-integer-setter ] } - { \ alien.accessors:alien-signed-2 [ 2 emit-alien-signed-getter ] } - { \ alien.accessors:set-alien-signed-2 [ 2 emit-alien-integer-setter ] } - { \ alien.accessors:alien-unsigned-4 [ 4 emit-alien-unsigned-getter ] } - { \ alien.accessors:set-alien-unsigned-4 [ 4 emit-alien-integer-setter ] } - { \ alien.accessors:alien-signed-4 [ 4 emit-alien-signed-getter ] } - { \ alien.accessors:set-alien-signed-4 [ 4 emit-alien-integer-setter ] } - { \ alien.accessors:alien-cell [ emit-alien-cell-getter ] } - { \ alien.accessors:set-alien-cell [ emit-alien-cell-setter ] } - { \ alien.accessors:alien-float [ single-float-regs emit-alien-float-getter ] } - { \ alien.accessors:set-alien-float [ single-float-regs emit-alien-float-setter ] } - { \ alien.accessors:alien-double [ double-float-regs emit-alien-float-getter ] } - { \ alien.accessors:set-alien-double [ double-float-regs emit-alien-float-setter ] } + { \ kernel.private:tag [ drop emit-tag iterate-next ] } + { \ math.private:both-fixnums? [ drop emit-both-fixnums? iterate-next ] } + { \ math.private:fixnum+ [ drop [ ##fixnum-add ] [ ##fixnum-add-tail ] emit-fixnum-overflow-op ] } + { \ math.private:fixnum- [ drop [ ##fixnum-sub ] [ ##fixnum-sub-tail ] emit-fixnum-overflow-op ] } + { \ math.private:fixnum* [ drop [ ##fixnum-mul ] [ ##fixnum-mul-tail ] emit-fixnum-overflow-op ] } + { \ math.private:fixnum+fast [ [ ^^add ] [ ^^add-imm ] emit-fixnum-op iterate-next ] } + { \ math.private:fixnum-fast [ [ ^^sub ] [ ^^sub-imm ] emit-fixnum-op iterate-next ] } + { \ math.private:fixnum-bitand [ [ ^^and ] [ ^^and-imm ] emit-fixnum-op iterate-next ] } + { \ math.private:fixnum-bitor [ [ ^^or ] [ ^^or-imm ] emit-fixnum-op iterate-next ] } + { \ math.private:fixnum-bitxor [ [ ^^xor ] [ ^^xor-imm ] emit-fixnum-op iterate-next ] } + { \ math.private:fixnum-shift-fast [ emit-fixnum-shift-fast iterate-next ] } + { \ math.private:fixnum-bitnot [ drop emit-fixnum-bitnot iterate-next ] } + { \ math.private:fixnum*fast [ emit-fixnum*fast iterate-next ] } + { \ math.private:fixnum< [ cc< emit-fixnum-comparison iterate-next ] } + { \ math.private:fixnum<= [ cc<= emit-fixnum-comparison iterate-next ] } + { \ math.private:fixnum>= [ cc>= emit-fixnum-comparison iterate-next ] } + { \ math.private:fixnum> [ cc> emit-fixnum-comparison iterate-next ] } + { \ kernel:eq? [ cc= emit-fixnum-comparison iterate-next ] } + { \ math.private:bignum>fixnum [ drop emit-bignum>fixnum iterate-next ] } + { \ math.private:fixnum>bignum [ drop emit-fixnum>bignum iterate-next ] } + { \ math.private:float+ [ drop [ ^^add-float ] emit-float-op iterate-next ] } + { \ math.private:float- [ drop [ ^^sub-float ] emit-float-op iterate-next ] } + { \ math.private:float* [ drop [ ^^mul-float ] emit-float-op iterate-next ] } + { \ math.private:float/f [ drop [ ^^div-float ] emit-float-op iterate-next ] } + { \ math.private:float< [ drop cc< emit-float-comparison iterate-next ] } + { \ math.private:float<= [ drop cc<= emit-float-comparison iterate-next ] } + { \ math.private:float>= [ drop cc>= emit-float-comparison iterate-next ] } + { \ math.private:float> [ drop cc> emit-float-comparison iterate-next ] } + { \ math.private:float= [ drop cc= emit-float-comparison iterate-next ] } + { \ math.private:float>fixnum [ drop emit-float>fixnum iterate-next ] } + { \ math.private:fixnum>float [ drop emit-fixnum>float iterate-next ] } + { \ slots.private:slot [ emit-slot iterate-next ] } + { \ slots.private:set-slot [ emit-set-slot iterate-next ] } + { \ strings.private:string-nth [ drop emit-string-nth iterate-next ] } + { \ classes.tuple.private: [ emit- iterate-next ] } + { \ arrays: [ emit- iterate-next ] } + { \ byte-arrays: [ emit- iterate-next ] } + { \ math.private: [ emit-simple-allot iterate-next ] } + { \ math.private: [ emit-simple-allot iterate-next ] } + { \ kernel: [ emit-simple-allot iterate-next ] } + { \ alien.accessors:alien-unsigned-1 [ 1 emit-alien-unsigned-getter iterate-next ] } + { \ alien.accessors:set-alien-unsigned-1 [ 1 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-signed-1 [ 1 emit-alien-signed-getter iterate-next ] } + { \ alien.accessors:set-alien-signed-1 [ 1 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-unsigned-2 [ 2 emit-alien-unsigned-getter iterate-next ] } + { \ alien.accessors:set-alien-unsigned-2 [ 2 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-signed-2 [ 2 emit-alien-signed-getter iterate-next ] } + { \ alien.accessors:set-alien-signed-2 [ 2 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-unsigned-4 [ 4 emit-alien-unsigned-getter iterate-next ] } + { \ alien.accessors:set-alien-unsigned-4 [ 4 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-signed-4 [ 4 emit-alien-signed-getter iterate-next ] } + { \ alien.accessors:set-alien-signed-4 [ 4 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-cell [ emit-alien-cell-getter iterate-next ] } + { \ alien.accessors:set-alien-cell [ emit-alien-cell-setter iterate-next ] } + { \ alien.accessors:alien-float [ single-float-regs emit-alien-float-getter iterate-next ] } + { \ alien.accessors:set-alien-float [ single-float-regs emit-alien-float-setter iterate-next ] } + { \ alien.accessors:alien-double [ double-float-regs emit-alien-float-getter iterate-next ] } + { \ alien.accessors:set-alien-double [ double-float-regs emit-alien-float-setter iterate-next ] } } case ; diff --git a/basis/compiler/cfg/stack-frame/stack-frame.factor b/basis/compiler/cfg/stack-frame/stack-frame.factor index ec9ffaba49..d545b6d15c 100644 --- a/basis/compiler/cfg/stack-frame/stack-frame.factor +++ b/basis/compiler/cfg/stack-frame/stack-frame.factor @@ -34,6 +34,12 @@ M: insn compute-stack-frame* \ _gc t frame-required? set-word-prop \ _spill t frame-required? set-word-prop +\ ##fixnum-add t frame-required? set-word-prop +\ ##fixnum-sub t frame-required? set-word-prop +\ ##fixnum-mul t frame-required? set-word-prop +\ ##fixnum-add-tail f frame-required? set-word-prop +\ ##fixnum-sub-tail f frame-required? set-word-prop +\ ##fixnum-mul-tail f frame-required? set-word-prop : compute-stack-frame ( insns -- ) frame-required? off diff --git a/basis/compiler/cfg/utilities/utilities.factor b/basis/compiler/cfg/utilities/utilities.factor index cef14d06e4..99a138a763 100644 --- a/basis/compiler/cfg/utilities/utilities.factor +++ b/basis/compiler/cfg/utilities/utilities.factor @@ -33,5 +33,7 @@ IN: compiler.cfg.utilities building off basic-block off ; +: stop-iterating ( -- next ) end-basic-block f ; + : emit-primitive ( node -- ) word>> ##call ##branch begin-basic-block ; diff --git a/basis/compiler/cfg/value-numbering/propagate/propagate.factor b/basis/compiler/cfg/value-numbering/propagate/propagate.factor index a3c9725838..d5c9830c0b 100644 --- a/basis/compiler/cfg/value-numbering/propagate/propagate.factor +++ b/basis/compiler/cfg/value-numbering/propagate/propagate.factor @@ -62,4 +62,8 @@ M: ##compare-imm-branch propagate M: ##dispatch propagate [ resolve ] change-src ; +M: ##fixnum-overflow propagate + [ resolve ] change-src1 + [ resolve ] change-src2 ; + M: insn propagate ; diff --git a/basis/compiler/codegen/codegen.factor b/basis/compiler/codegen/codegen.factor index bfb47ba330..b66b6a11c7 100644 --- a/basis/compiler/codegen/codegen.factor +++ b/basis/compiler/codegen/codegen.factor @@ -156,6 +156,16 @@ M: ##shr-imm generate-insn dst/src1/src2 %shr-imm ; M: ##sar-imm generate-insn dst/src1/src2 %sar-imm ; M: ##not generate-insn dst/src %not ; +: src1/src2 ( insn -- src1 src2 ) + [ src1>> register ] [ src2>> register ] bi ; inline + +M: ##fixnum-add generate-insn src1/src2 %fixnum-add ; +M: ##fixnum-add-tail generate-insn src1/src2 %fixnum-add-tail ; +M: ##fixnum-sub generate-insn src1/src2 %fixnum-sub ; +M: ##fixnum-sub-tail generate-insn src1/src2 %fixnum-sub-tail ; +M: ##fixnum-mul generate-insn src1/src2 %fixnum-mul ; +M: ##fixnum-mul-tail generate-insn src1/src2 %fixnum-mul-tail ; + : dst/src/temp ( insn -- dst src temp ) [ dst/src ] [ temp>> register ] bi ; inline diff --git a/basis/compiler/tests/codegen.factor b/basis/compiler/tests/codegen.factor index dd6f99ead1..59434b6dc5 100644 --- a/basis/compiler/tests/codegen.factor +++ b/basis/compiler/tests/codegen.factor @@ -254,3 +254,25 @@ TUPLE: id obj ; { 1 2 3 4 } [ { array } declare 2 length ] compile-call ] unit-test + +! Oops with new intrinsics +: fixnum-overflow-control-flow-test ( a b -- c ) + [ 1 fixnum- ] [ 2 fixnum- ] if 3 fixnum+fast ; + +[ 3 ] [ 1 t fixnum-overflow-control-flow-test ] unit-test +[ 2 ] [ 1 f fixnum-overflow-control-flow-test ] unit-test + +! LOL +: blah ( a -- b ) + { float } declare dup 0 = + [ drop 1 ] [ + dup 0 >= + [ 2 "double" "libm" "pow" { "double" "double" } alien-invoke ] + [ -0.5 "double" "libm" "pow" { "double" "double" } alien-invoke ] + if + ] if ; + +[ 4.0 ] [ 2.0 blah ] unit-test + +[ 4 ] [ 2 [ dup fixnum* ] compile-call ] unit-test +[ 7 ] [ 2 [ dup fixnum* 3 fixnum+fast ] compile-call ] unit-test diff --git a/basis/compiler/tree/debugger/debugger.factor b/basis/compiler/tree/debugger/debugger.factor index a1d8773484..e9bf77b188 100644 --- a/basis/compiler/tree/debugger/debugger.factor +++ b/basis/compiler/tree/debugger/debugger.factor @@ -93,7 +93,7 @@ M: #shuffle node>quot [ drop "COMPLEX SHUFFLE" , ] } cond ; -M: #push node>quot literal>> , ; +M: #push node>quot literal>> literalize , ; M: #call node>quot word>> , ; diff --git a/basis/compiler/tree/propagation/known-words/known-words.factor b/basis/compiler/tree/propagation/known-words/known-words.factor index f6e2bc0940..163b17094a 100644 --- a/basis/compiler/tree/propagation/known-words/known-words.factor +++ b/basis/compiler/tree/propagation/known-words/known-words.factor @@ -37,31 +37,6 @@ most-negative-fixnum most-positive-fixnum [a,b] \ bitnot { integer } "input-classes" set-word-prop -{ - fcosh - flog - fsinh - fexp - fasin - facosh - fasinh - ftanh - fatanh - facos - fpow - fatan - fatan2 - fcos - ftan - fsin - fsqrt -} [ - dup stack-effect - [ in>> length real "input-classes" set-word-prop ] - [ out>> length float "default-output-classes" set-word-prop ] - 2bi -] each - : ?change-interval ( info quot -- quot' ) over interval>> [ [ clone ] dip change-interval ] [ 2drop ] if ; inline @@ -222,8 +197,15 @@ generic-comparison-ops [ { { >fixnum fixnum } + { bignum>fixnum fixnum } + { >bignum bignum } + { fixnum>bignum bignum } + { float>bignum bignum } + { >float float } + { fixnum>float float } + { bignum>float float } } [ '[ _ diff --git a/basis/compiler/tree/propagation/propagation-tests.factor b/basis/compiler/tree/propagation/propagation-tests.factor index 760ff167aa..5a7b096039 100644 --- a/basis/compiler/tree/propagation/propagation-tests.factor +++ b/basis/compiler/tree/propagation/propagation-tests.factor @@ -8,7 +8,7 @@ math.functions math.private strings layouts compiler.tree.propagation.info compiler.tree.def-use compiler.tree.debugger compiler.tree.checker slots.private words hashtables classes assocs locals -float-arrays system sorting ; +float-arrays system sorting math.libm ; IN: compiler.tree.propagation.tests \ propagate must-infer @@ -594,6 +594,10 @@ MIXIN: empty-mixin [ V{ array } ] [ [ [ <=> ] sort [ <=> ] sort ] final-classes ] unit-test +[ V{ float } ] [ [ fsqrt ] final-classes ] unit-test + +[ V{ t } ] [ [ { fixnum } declare 10 mod >float -20 > ] final-literals ] unit-test + ! [ V{ string } ] [ ! [ dup string? t xor [ "A" throw ] [ ] if ] final-classes ! ] unit-test diff --git a/basis/compiler/tree/propagation/simple/simple.factor b/basis/compiler/tree/propagation/simple/simple.factor index d586ff398f..9937c6b9c4 100644 --- a/basis/compiler/tree/propagation/simple/simple.factor +++ b/basis/compiler/tree/propagation/simple/simple.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: fry accessors kernel sequences sequences.private assocs words namespaces classes.algebra combinators classes classes.tuple -classes.tuple.private continuations arrays +classes.tuple.private continuations arrays alien.c-types math math.private slots generic definitions stack-checker.state compiler.tree @@ -137,11 +137,12 @@ M: #call propagate-after dup word>> "input-classes" word-prop dup [ propagate-input-classes ] [ 2drop ] if ; -M: #alien-invoke propagate-before - out-d>> [ object-info swap set-value-info ] each ; +: propagate-alien-invoke ( node -- ) + [ out-d>> ] [ params>> return>> ] bi + [ drop ] [ c-type-class swap first set-value-info ] if-void ; -M: #alien-indirect propagate-before - out-d>> [ object-info swap set-value-info ] each ; +M: #alien-invoke propagate-before propagate-alien-invoke ; -M: #return annotate-node - dup in-d>> (annotate-node) ; +M: #alien-indirect propagate-before propagate-alien-invoke ; + +M: #return annotate-node dup in-d>> (annotate-node) ; diff --git a/basis/cpu/architecture/architecture.factor b/basis/cpu/architecture/architecture.factor index 3d6195d9eb..2fdad0132a 100644 --- a/basis/cpu/architecture/architecture.factor +++ b/basis/cpu/architecture/architecture.factor @@ -77,6 +77,13 @@ HOOK: %shr-imm cpu ( dst src1 src2 -- ) HOOK: %sar-imm cpu ( dst src1 src2 -- ) HOOK: %not cpu ( dst src -- ) +HOOK: %fixnum-add cpu ( src1 src2 -- ) +HOOK: %fixnum-add-tail cpu ( src1 src2 -- ) +HOOK: %fixnum-sub cpu ( src1 src2 -- ) +HOOK: %fixnum-sub-tail cpu ( src1 src2 -- ) +HOOK: %fixnum-mul cpu ( src1 src2 -- ) +HOOK: %fixnum-mul-tail cpu ( src1 src2 -- ) + HOOK: %integer>bignum cpu ( dst src temp -- ) HOOK: %bignum>integer cpu ( dst src temp -- ) diff --git a/basis/cpu/ppc/bootstrap.factor b/basis/cpu/ppc/bootstrap.factor index 047d27c5f4..d22ff4d615 100644 --- a/basis/cpu/ppc/bootstrap.factor +++ b/basis/cpu/ppc/bootstrap.factor @@ -327,6 +327,18 @@ big-endian on \ BLT \ fixnum< define-jit-compare ! Math +[ + 3 ds-reg 0 LWZ + 4 ds-reg -4 LWZ + 3 3 4 OR + 3 3 tag-mask get ANDI + \ f tag-number 4 LI + 0 3 0 CMPI + 2 BNE + 1 tag-fixnum 4 LI + 4 ds-reg 4 STWU +] f f f \ both-fixnums? define-sub-primitive + : jit-math ( insn -- ) 3 ds-reg 0 LWZ 4 ds-reg -4 LWZU @@ -406,9 +418,7 @@ big-endian on [ 3 ds-reg 0 LWZ 3 3 1 SRAWI - 4 4 LI - 4 3 4 SUBF - rs-reg 3 4 LWZX + rs-reg 3 3 LWZX 3 ds-reg 0 STW ] f f f \ get-local define-sub-primitive diff --git a/basis/cpu/ppc/ppc.factor b/basis/cpu/ppc/ppc.factor index 6a42ffdf77..8632d236cc 100644 --- a/basis/cpu/ppc/ppc.factor +++ b/basis/cpu/ppc/ppc.factor @@ -17,6 +17,7 @@ IN: cpu.ppc ! f30, f31: float scratch enable-float-intrinsics +enable-fixnum*-intrinsic << \ ##integer>float t frame-required? set-word-prop \ ##float>integer t frame-required? set-word-prop >> @@ -37,6 +38,9 @@ M: ppc %load-immediate ( reg n -- ) swap LOAD ; M: ppc %load-indirect ( reg obj -- ) [ 0 swap LOAD32 ] [ rc-absolute-ppc-2/2 rel-immediate ] bi* ; +: %load-dlsym ( symbol dll register -- ) + 0 swap LOAD32 rc-absolute-ppc-2/2 rel-dlsym ; + : ds-reg 29 ; inline : rs-reg 30 ; inline @@ -164,6 +168,91 @@ M: ppc %shr-imm swapd SRWI ; M: ppc %sar-imm SRAWI ; M: ppc %not NOT ; +: %alien-invoke-tail ( func dll -- ) + scratch-reg %load-dlsym scratch-reg MTCTR BCTR ; + +:: exchange-regs ( r1 r2 -- ) + scratch-reg r1 MR + r1 r2 MR + r2 scratch-reg MR ; + +: ?MR ( r1 r2 -- ) 2dup = [ 2drop ] [ MR ] if ; + +:: move>args ( src1 src2 -- ) + { + { [ src1 4 = ] [ 3 src2 ?MR 3 4 exchange-regs ] } + { [ src1 3 = ] [ 4 src2 ?MR ] } + { [ src2 3 = ] [ 4 src1 ?MR 3 4 exchange-regs ] } + { [ src2 4 = ] [ 3 src1 ?MR ] } + [ 3 src1 MR 4 src2 MR ] + } cond ; + +:: overflow-template ( src1 src2 insn func -- ) + "no-overflow" define-label + 0 0 LI + 0 MTXER + scratch-reg src2 src1 insn call + scratch-reg ds-reg 0 STW + "no-overflow" get BNO + src2 src1 move>args + %prepare-alien-invoke + func f %alien-invoke + "no-overflow" resolve-label ; inline + +:: overflow-template-tail ( src1 src2 insn func -- ) + "overflow" define-label + 0 0 LI + 0 MTXER + scratch-reg src2 src1 insn call + "overflow" get BO + scratch-reg ds-reg 0 STW + BLR + "overflow" resolve-label + src2 src1 move>args + %prepare-alien-invoke + func f %alien-invoke-tail ; + +M: ppc %fixnum-add ( src1 src2 -- ) + [ ADDO. ] "overflow_fixnum_add" overflow-template ; + +M: ppc %fixnum-add-tail ( src1 src2 -- ) + [ ADDO. ] "overflow_fixnum_add" overflow-template-tail ; + +M: ppc %fixnum-sub ( src1 src2 -- ) + [ SUBFO. ] "overflow_fixnum_subtract" overflow-template ; + +M: ppc %fixnum-sub-tail ( src1 src2 -- ) + [ SUBFO. ] "overflow_fixnum_subtract" overflow-template-tail ; + +M:: ppc %fixnum-mul ( src1 src2 -- ) + "no-overflow" define-label + 0 0 LI + 0 MTXER + scratch-reg src1 tag-bits get SRAWI + scratch-reg scratch-reg src2 MULLWO. + scratch-reg ds-reg 0 STW + "no-overflow" get BNO + src2 src2 tag-bits get SRAWI + scratch-reg src2 move>args + %prepare-alien-invoke + "overflow_fixnum_multiply" f %alien-invoke + "no-overflow" resolve-label ; + +M:: ppc %fixnum-mul-tail ( src1 src2 -- ) + "overflow" define-label + 0 0 LI + 0 MTXER + scratch-reg src1 tag-bits get SRAWI + scratch-reg scratch-reg src2 MULLWO. + "overflow" get BO + scratch-reg ds-reg 0 STW + BLR + "overflow" resolve-label + src2 src2 tag-bits get SRAWI + scratch-reg src2 move>args + %prepare-alien-invoke + "overflow_fixnum_multiply" f %alien-invoke-tail ; + : bignum@ ( n -- offset ) cells bignum tag-number - ; inline M:: ppc %integer>bignum ( dst src temp -- ) @@ -318,9 +407,6 @@ M: ppc %set-alien-cell swap 0 STW ; M: ppc %set-alien-float swap 0 STFS ; M: ppc %set-alien-double swap 0 STFD ; -: %load-dlsym ( symbol dll register -- ) - 0 swap LOAD32 rc-absolute-ppc-2/2 rel-dlsym ; - : load-zone-ptr ( reg -- ) [ "nursery" f ] dip %load-dlsym ; @@ -538,11 +624,11 @@ M: ppc %prepare-alien-invoke #! Save Factor stack pointers in case the C code calls a #! callback which does a GC, which must reliably trace #! all roots. - "stack_chain" f 11 %load-dlsym - 11 11 0 LWZ - 1 11 0 STW - ds-reg 11 8 STW - rs-reg 11 12 STW ; + "stack_chain" f scratch-reg %load-dlsym + scratch-reg scratch-reg 0 LWZ + 1 scratch-reg 0 STW + ds-reg scratch-reg 8 STW + rs-reg scratch-reg 12 STW ; M: ppc %alien-invoke ( symbol dll -- ) 11 %load-dlsym 11 MTLR BLRL ; diff --git a/basis/cpu/x86/32/32.factor b/basis/cpu/x86/32/32.factor old mode 100644 new mode 100755 index 217047e4b6..9fd1330757 --- a/basis/cpu/x86/32/32.factor +++ b/basis/cpu/x86/32/32.factor @@ -23,8 +23,8 @@ M: x86.32 machine-registers M: x86.32 ds-reg ESI ; M: x86.32 rs-reg EDI ; M: x86.32 stack-reg ESP ; -M: x86.32 temp-reg-1 EAX ; -M: x86.32 temp-reg-2 ECX ; +M: x86.32 temp-reg-1 ECX ; +M: x86.32 temp-reg-2 EDX ; M:: x86.32 %dispatch ( src temp offset -- ) ! Load jump table base. @@ -38,12 +38,18 @@ M:: x86.32 %dispatch ( src temp offset -- ) [ align-code ] bi ; +! Registers for fastcall +M: x86.32 param-reg-1 EAX ; +M: x86.32 param-reg-2 EDX ; + M: x86.32 reserved-area-size 0 ; M: x86.32 %alien-global 0 [] MOV rc-absolute-cell rel-dlsym ; M: x86.32 %alien-invoke (CALL) rel-dlsym ; +M: x86.32 %alien-invoke-tail (JMP) rel-dlsym ; + M: x86.32 struct-small-enough? ( size -- ? ) heap-size { 1 2 4 8 } member? os { linux netbsd solaris } member? not and ; diff --git a/basis/cpu/x86/64/64.factor b/basis/cpu/x86/64/64.factor index 9ddad23004..b6c76a78fd 100644 --- a/basis/cpu/x86/64/64.factor +++ b/basis/cpu/x86/64/64.factor @@ -21,8 +21,8 @@ M: x86.64 machine-registers M: x86.64 ds-reg R14 ; M: x86.64 rs-reg R15 ; M: x86.64 stack-reg RSP ; -M: x86.64 temp-reg-1 RAX ; -M: x86.64 temp-reg-2 RCX ; +M: x86.64 temp-reg-1 R8 ; +M: x86.64 temp-reg-2 R9 ; M:: x86.64 %dispatch ( src temp offset -- ) ! Load jump table base. @@ -37,8 +37,8 @@ M:: x86.64 %dispatch ( src temp offset -- ) [ align-code ] bi ; -: param-reg-1 int-regs param-regs first ; inline -: param-reg-2 int-regs param-regs second ; inline +M: x86.64 param-reg-1 int-regs param-regs first ; +M: x86.64 param-reg-2 int-regs param-regs second ; : param-reg-3 int-regs param-regs third ; inline M: int-regs return-reg drop RAX ; @@ -168,6 +168,11 @@ M: x86.64 %alien-invoke rc-absolute-cell rel-dlsym R11 CALL ; +M: x86.64 %alien-invoke-tail + R11 0 MOV + rc-absolute-cell rel-dlsym + R11 JMP ; + M: x86.64 %prepare-alien-indirect ( -- ) "unbox_alien" f %alien-invoke RBP RAX MOV ; diff --git a/basis/cpu/x86/bootstrap.factor b/basis/cpu/x86/bootstrap.factor index d5fc64de00..42df1c8437 100644 --- a/basis/cpu/x86/bootstrap.factor +++ b/basis/cpu/x86/bootstrap.factor @@ -379,12 +379,21 @@ big-endian off ds-reg bootstrap-cell neg [+] div-arg MOV ] f f f \ fixnum/mod-fast define-sub-primitive +[ + arg0 ds-reg [] MOV + arg0 ds-reg bootstrap-cell neg [+] OR + ds-reg bootstrap-cell ADD + arg0 tag-mask get AND + arg0 \ f tag-number MOV + arg1 1 tag-fixnum MOV + arg0 arg1 CMOVE + ds-reg [] arg0 MOV +] f f f \ both-fixnums? define-sub-primitive + [ arg0 ds-reg [] MOV ! load local number fixnum>slot@ ! turn local number into offset - arg1 bootstrap-cell MOV ! load base - arg1 arg0 SUB ! turn it into a stack offset - arg0 rs-reg arg1 [+] MOV ! load local value + arg0 rs-reg arg0 [+] MOV ! load local value ds-reg [] arg0 MOV ! push to stack ] f f f \ get-local define-sub-primitive diff --git a/basis/cpu/x86/x86.factor b/basis/cpu/x86/x86.factor index f0f156a57d..104a1f155b 100644 --- a/basis/cpu/x86/x86.factor +++ b/basis/cpu/x86/x86.factor @@ -14,6 +14,9 @@ M: x86 two-operand? t ; HOOK: temp-reg-1 cpu ( -- reg ) HOOK: temp-reg-2 cpu ( -- reg ) +HOOK: param-reg-1 cpu ( -- reg ) +HOOK: param-reg-2 cpu ( -- reg ) + M: x86 %load-immediate MOV ; M: x86 %load-indirect swap 0 MOV rc-absolute-cell rel-immediate ; @@ -90,6 +93,58 @@ M: x86 %shr-imm nip SHR ; M: x86 %sar-imm nip SAR ; M: x86 %not drop NOT ; +: ?MOV ( dst src -- ) + 2dup = [ 2drop ] [ MOV ] if ; inline + +:: move>args ( src1 src2 -- ) + { + { [ src1 param-reg-2 = ] [ param-reg-1 src2 ?MOV param-reg-1 param-reg-2 XCHG ] } + { [ src1 param-reg-1 = ] [ param-reg-2 src2 ?MOV ] } + { [ src2 param-reg-1 = ] [ param-reg-2 src1 ?MOV param-reg-1 param-reg-2 XCHG ] } + { [ src2 param-reg-2 = ] [ param-reg-1 src1 ?MOV ] } + [ + param-reg-1 src1 MOV + param-reg-2 src2 MOV + ] + } cond ; + +HOOK: %alien-invoke-tail cpu ( func dll -- ) + +:: overflow-template ( src1 src2 insn inverse func -- ) +