diff --git a/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor b/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor index be151b2002..5ac733114b 100644 --- a/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor +++ b/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor @@ -31,8 +31,11 @@ M: live-interval clone SYMBOL: live-intervals : new-live-interval ( n vreg live-intervals -- ) - 2dup key? [ "Multiple defs" throw ] when - [ [ ] keep ] dip set-at ; + 2dup key? [ + at add-use + ] [ + [ [ ] keep ] dip set-at + ] if ; : compute-live-intervals* ( insn n -- ) live-intervals get diff --git a/basis/compiler/cfg/two-operand/two-operand.factor b/basis/compiler/cfg/two-operand/two-operand.factor new file mode 100644 index 0000000000..e943fb4828 --- /dev/null +++ b/basis/compiler/cfg/two-operand/two-operand.factor @@ -0,0 +1,60 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors arrays kernel sequences sequences.deep +compiler.cfg.instructions cpu.architecture ; +IN: compiler.cfg.two-operand + +! On x86, instructions take the form x = x op y +! Our SSA IR is x = y op z + +! We don't bother with ##add, ##add-imm or ##sub-imm since x86 +! has a LEA instruction which is effectively a three-operand +! addition + +: make-copy ( dst src -- insn ) f \ ##copy boa ; inline + +: make-copy/float ( dst src -- insn ) f \ ##copy-float boa ; inline + +: convert-two-operand/integer ( insn -- insns ) + [ [ dst>> ] [ src1>> ] bi make-copy ] + [ dup dst>> >>src1 ] + bi 2array ; inline + +: convert-two-operand/float ( insn -- insns ) + [ [ dst>> ] [ src1>> ] bi make-copy/float ] + [ dup dst>> >>src1 ] + bi 2array ; inline + +GENERIC: convert-two-operand* ( insn -- insns ) + +M: ##not convert-two-operand* + [ [ dst>> ] [ src>> ] bi make-copy ] + [ dup dst>> >>src ] + bi 2array ; + +M: ##sub convert-two-operand* convert-two-operand/integer ; +M: ##mul convert-two-operand* convert-two-operand/integer ; +M: ##mul-imm convert-two-operand* convert-two-operand/integer ; +M: ##and convert-two-operand* convert-two-operand/integer ; +M: ##and-imm convert-two-operand* convert-two-operand/integer ; +M: ##or convert-two-operand* convert-two-operand/integer ; +M: ##or-imm convert-two-operand* convert-two-operand/integer ; +M: ##xor convert-two-operand* convert-two-operand/integer ; +M: ##xor-imm convert-two-operand* convert-two-operand/integer ; +M: ##shl-imm convert-two-operand* convert-two-operand/integer ; +M: ##shr-imm convert-two-operand* convert-two-operand/integer ; +M: ##sar-imm convert-two-operand* convert-two-operand/integer ; + +M: ##add-float convert-two-operand* convert-two-operand/float ; +M: ##sub-float convert-two-operand* convert-two-operand/float ; +M: ##mul-float convert-two-operand* convert-two-operand/float ; +M: ##div-float convert-two-operand* convert-two-operand/float ; + +M: insn convert-two-operand* ; + +: convert-two-operand ( mr -- mr' ) + [ + two-operand? [ + [ convert-two-operand* ] map flatten + ] when + ] change-instructions ; diff --git a/basis/compiler/compiler.factor b/basis/compiler/compiler.factor index f3767ec688..0a21749d84 100644 --- a/basis/compiler/compiler.factor +++ b/basis/compiler/compiler.factor @@ -7,8 +7,8 @@ stack-checker stack-checker.state stack-checker.inlining compiler.errors compiler.units compiler.tree.builder compiler.tree.optimizer compiler.cfg.builder compiler.cfg.optimizer compiler.cfg.linearization -compiler.cfg.linear-scan compiler.cfg.stack-frame -compiler.codegen ; +compiler.cfg.two-operand compiler.cfg.linear-scan +compiler.cfg.stack-frame compiler.codegen ; IN: compiler SYMBOL: compile-queue @@ -76,6 +76,7 @@ t compile-dependencies? set-global build-cfg [ optimize-cfg build-mr + convert-two-operand linear-scan build-stack-frame generate diff --git a/basis/cpu/architecture/architecture.factor b/basis/cpu/architecture/architecture.factor index e90f58fd49..f7cce8e70a 100644 --- a/basis/cpu/architecture/architecture.factor +++ b/basis/cpu/architecture/architecture.factor @@ -35,6 +35,8 @@ GENERIC: param-reg ( n register-class -- reg ) M: object param-reg param-regs nth ; +HOOK: two-operand? cpu ( -- ? ) + HOOK: %load-immediate cpu ( reg obj -- ) HOOK: %load-indirect cpu ( reg obj -- ) diff --git a/basis/cpu/x86/architecture/architecture.factor b/basis/cpu/x86/architecture/architecture.factor index 65067740d9..615550587c 100644 --- a/basis/cpu/x86/architecture/architecture.factor +++ b/basis/cpu/x86/architecture/architecture.factor @@ -9,6 +9,8 @@ compiler.cfg.instructions compiler.codegen compiler.codegen.fixup ; IN: cpu.x86.architecture +M: x86 two-operand? t ; + HOOK: temp-reg-1 cpu ( -- reg ) HOOK: temp-reg-2 cpu ( -- reg ) @@ -83,31 +85,22 @@ M: x86 %slot-imm ( dst obj slot tag -- ) (%slot-imm) MOV ; M: x86 %set-slot ( src obj slot tag temp -- ) (%slot) swap MOV ; M: x86 %set-slot-imm ( src obj slot tag -- ) (%slot-imm) swap MOV ; -: ?MOV ( dst src -- ) - 2dup = [ 2drop ] [ MOV ] if ; inline - -: 1operand ( dst src -- dst' ) - dupd ?MOV ; inline - -: 2operand ( dst src1 src2 -- dst src ) - [ 1operand ] dip ; inline - M: x86 %add [+] LEA ; M: x86 %add-imm [+] LEA ; -M: x86 %sub 2operand SUB ; +M: x86 %sub nip SUB ; M: x86 %sub-imm neg [+] LEA ; -M: x86 %mul 2operand swap IMUL2 ; -M: x86 %mul-imm 2operand IMUL2 ; -M: x86 %and 2operand AND ; -M: x86 %and-imm 2operand AND ; -M: x86 %or 2operand OR ; -M: x86 %or-imm 2operand OR ; -M: x86 %xor 2operand XOR ; -M: x86 %xor-imm 2operand XOR ; -M: x86 %shl-imm 2operand SHL ; -M: x86 %shr-imm 2operand SHR ; -M: x86 %sar-imm 2operand SAR ; -M: x86 %not 1operand NOT ; +M: x86 %mul nip swap IMUL2 ; +M: x86 %mul-imm nip IMUL2 ; +M: x86 %and nip AND ; +M: x86 %and-imm nip AND ; +M: x86 %or nip OR ; +M: x86 %or-imm nip OR ; +M: x86 %xor nip XOR ; +M: x86 %xor-imm nip XOR ; +M: x86 %shl-imm nip SHL ; +M: x86 %shr-imm nip SHR ; +M: x86 %sar-imm nip SAR ; +M: x86 %not drop NOT ; : bignum@ ( reg n -- op ) cells bignum tag-number - [+] ; inline @@ -164,26 +157,21 @@ M:: x86 %bignum>integer ( dst src -- ) "end" resolve-label ] with-scope ; -: ?MOVSD ( dst src -- ) - 2dup = [ 2drop ] [ MOVSD ] if ; inline - -: 1operand-fp ( dst src -- dst' ) - dupd ?MOVSD ; inline - -: 2operand-fp ( dst src1 src2 -- dst src ) - [ 1operand-fp ] dip ; inline - -M: x86 %add-float 2operand-fp ADDSD ; -M: x86 %sub-float 2operand-fp SUBSD ; -M: x86 %mul-float 2operand-fp MULSD ; -M: x86 %div-float 2operand-fp DIVSD ; +M: x86 %add-float nip ADDSD ; +M: x86 %sub-float nip SUBSD ; +M: x86 %mul-float nip MULSD ; +M: x86 %div-float nip DIVSD ; M: x86 %integer>float CVTSI2SD ; M: x86 %float>integer CVTTSD2SI ; -M: x86 %copy ( dst src -- ) MOV ; +: ?MOV ( dst src -- ) + 2dup = [ 2drop ] [ MOV ] if ; inline -M: x86 %copy-float MOVSD ; +M: x86 %copy ( dst src -- ) ?MOV ; + +M: x86 %copy-float ( dst src -- ) + 2dup = [ 2drop ] [ MOVSD ] if ; M: x86 %unbox-float ( dst src -- ) float-offset [+] MOVSD ;