diff --git a/basis/compiler/cfg/def-use/def-use.factor b/basis/compiler/cfg/def-use/def-use.factor index 7584931cf7..177f172a76 100644 --- a/basis/compiler/cfg/def-use/def-use.factor +++ b/basis/compiler/cfg/def-use/def-use.factor @@ -18,6 +18,7 @@ M: ##string-nth defs-vregs dst/tmp-vregs ; M: ##compare defs-vregs dst/tmp-vregs ; M: ##compare-imm defs-vregs dst/tmp-vregs ; M: ##compare-float defs-vregs dst/tmp-vregs ; +M: ##fixnum-overflow defs-vregs temp>> 1array ; M: insn defs-vregs drop f ; M: ##unary uses-vregs src>> 1array ; @@ -34,6 +35,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 +45,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..4c050a3495 100644 --- a/basis/compiler/cfg/instructions/instructions.factor +++ b/basis/compiler/cfg/instructions/instructions.factor @@ -92,6 +92,12 @@ INSN: ##shr-imm < ##binary-imm ; INSN: ##sar-imm < ##binary-imm ; INSN: ##not < ##unary ; +! Overflowing arithmetic +TUPLE: ##fixnum-overflow < insn src1 src2 temp ; +INSN: ##fixnum-add < ##fixnum-overflow ; +INSN: ##fixnum-sub < ##fixnum-overflow ; +INSN: ##fixnum-mul < ##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..f22623650a 100644 --- a/basis/compiler/cfg/intrinsics/fixnum/fixnum.factor +++ b/basis/compiler/cfg/intrinsics/fixnum/fixnum.factor @@ -64,3 +64,6 @@ IN: compiler.cfg.intrinsics.fixnum : emit-fixnum>bignum ( -- ) ds-pop ^^untag-fixnum ^^integer>bignum ds-push ; + +: emit-fixnum-overflow-op ( quot -- ) + [ 2inputs i 1 ##inc-d ] dip call begin-basic-block ; inline diff --git a/basis/compiler/cfg/intrinsics/intrinsics.factor b/basis/compiler/cfg/intrinsics/intrinsics.factor index ef1cde337a..7a073f56b0 100644 --- a/basis/compiler/cfg/intrinsics/intrinsics.factor +++ b/basis/compiler/cfg/intrinsics/intrinsics.factor @@ -22,6 +22,8 @@ IN: compiler.cfg.intrinsics { kernel.private:tag + math.private:fixnum+ + math.private:fixnum- math.private:fixnum+fast math.private:fixnum-fast math.private:fixnum-bitand @@ -88,6 +90,9 @@ IN: compiler.cfg.intrinsics : emit-intrinsic ( node word -- ) { { \ kernel.private:tag [ drop emit-tag ] } + { \ math.private:fixnum+ [ drop [ ##fixnum-add ] emit-fixnum-overflow-op ] } + { \ math.private:fixnum- [ drop [ ##fixnum-sub ] emit-fixnum-overflow-op ] } + { \ math.private:fixnum* [ drop [ ##fixnum-mul ] emit-fixnum-overflow-op ] } { \ 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 ] } diff --git a/basis/compiler/cfg/stack-frame/stack-frame.factor b/basis/compiler/cfg/stack-frame/stack-frame.factor index ec9ffaba49..ade2e8ac5e 100644 --- a/basis/compiler/cfg/stack-frame/stack-frame.factor +++ b/basis/compiler/cfg/stack-frame/stack-frame.factor @@ -34,6 +34,9 @@ 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 : compute-stack-frame ( insns -- ) frame-required? off 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..f26c034e9f 100644 --- a/basis/compiler/codegen/codegen.factor +++ b/basis/compiler/codegen/codegen.factor @@ -156,6 +156,15 @@ 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/temp ( insn -- src1 src2 temp ) + [ src1>> register ] + [ src2>> register ] + [ temp>> register ] tri ; inline + +M: ##fixnum-add generate-insn src1/src2/temp %fixnum-add ; +M: ##fixnum-sub generate-insn src1/src2/temp %fixnum-sub ; +M: ##fixnum-mul generate-insn src1/src2/temp %fixnum-mul ; + : dst/src/temp ( insn -- dst src temp ) [ dst/src ] [ temp>> register ] bi ; inline diff --git a/basis/cpu/architecture/architecture.factor b/basis/cpu/architecture/architecture.factor index 3d6195d9eb..0f867e9027 100644 --- a/basis/cpu/architecture/architecture.factor +++ b/basis/cpu/architecture/architecture.factor @@ -77,6 +77,10 @@ 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 temp -- ) +HOOK: %fixnum-sub cpu ( src1 src2 temp -- ) +HOOK: %fixnum-mul cpu ( src1 src2 temp -- ) + HOOK: %integer>bignum cpu ( dst src temp -- ) HOOK: %bignum>integer cpu ( dst src temp -- ) diff --git a/basis/cpu/x86/32/32.factor b/basis/cpu/x86/32/32.factor index 217047e4b6..0972ff5592 100644 --- 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,6 +38,10 @@ M:: x86.32 %dispatch ( src temp offset -- ) [ align-code ] bi ; +! Registers for fastcall +M: x86.32 param-reg-1 drop EAX ; +M: x86.32 param-reg-2 drop EDX ; + M: x86.32 reserved-area-size 0 ; M: x86.32 %alien-global 0 [] MOV rc-absolute-cell rel-dlsym ; diff --git a/basis/cpu/x86/64/64.factor b/basis/cpu/x86/64/64.factor index 9ddad23004..9233af2a93 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 ; diff --git a/basis/cpu/x86/x86.factor b/basis/cpu/x86/x86.factor index f0f156a57d..0feab43545 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,38 @@ 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 ; + +:: overflow-template ( src1 src2 temp insn func -- ) +