182 lines
4.4 KiB
Factor
182 lines
4.4 KiB
Factor
! Copyright (C) 2008 Slava Pestov.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: parser prettyprint.backend kernel accessors math
|
|
math.order sequences namespaces arrays assocs ;
|
|
IN: compiler.vops
|
|
|
|
TUPLE: vreg n ;
|
|
|
|
: VREG: scan-word vreg boa parsed ; parsing
|
|
|
|
M: vreg pprint* \ VREG: pprint-word n>> pprint* ;
|
|
|
|
SYMBOL: vreg-counter
|
|
|
|
: init-counter ( -- )
|
|
{ 0 } clone vreg-counter set ;
|
|
|
|
: next-vreg ( -- n )
|
|
0 vreg-counter get [ dup 1+ ] change-nth vreg boa ;
|
|
|
|
: emit ( ... class -- ) boa , ; inline
|
|
|
|
! ! ! Instructions. Those prefixed with %% are high level
|
|
! ! ! instructions eliminated during the elaboration phase.
|
|
TUPLE: vop ;
|
|
|
|
! Instruction which does not touch vregs.
|
|
TUPLE: nullary-op < vop ;
|
|
|
|
! Does nothing
|
|
TUPLE: nop < nullary-op ;
|
|
|
|
: nop ( -- vop ) T{ nop } ;
|
|
|
|
: ?nop ( vop ? -- vop/nop ) [ drop nop ] unless ;
|
|
|
|
! Instruction with no side effects; if 'out' is never read, we
|
|
! can eliminate it.
|
|
TUPLE: flushable-op < vop out ;
|
|
|
|
! Instruction which is referentially transparent; we can replace
|
|
! repeated computation with a reference to a previous value
|
|
TUPLE: pure-op < flushable-op ;
|
|
|
|
! Instruction only used for its side effect, produces no values
|
|
TUPLE: effect-op < vop in ;
|
|
|
|
TUPLE: binary-op < pure-op in1 in2 ;
|
|
|
|
: inputs ( insn -- in1 in2 ) [ in1>> ] [ in2>> ] bi ; inline
|
|
|
|
: in/out ( insn -- in out ) [ in>> ] [ out>> ] bi ; inline
|
|
|
|
TUPLE: unary-op < pure-op in ;
|
|
|
|
! Merge point; out is a sequence of vregs in a sequence of
|
|
! sequences of vregs
|
|
TUPLE: %phi < pure-op in ;
|
|
|
|
! Integer, floating point, condition register copy
|
|
TUPLE: %copy < unary-op ;
|
|
|
|
! Constants
|
|
TUPLE: constant-op < pure-op value ;
|
|
|
|
TUPLE: %iconst < constant-op ; ! Integer
|
|
TUPLE: %fconst < constant-op ; ! Float
|
|
TUPLE: %cconst < constant-op ; ! Comparison result, +lt+ +eq+ +gt+
|
|
|
|
! Load address of literal table into out
|
|
TUPLE: %literal-table < pure-op ;
|
|
|
|
! Load object literal from table.
|
|
TUPLE: %literal < unary-op object ;
|
|
|
|
! Read/write ops: candidates for alias analysis
|
|
TUPLE: read-op < flushable-op ;
|
|
TUPLE: write-op < effect-op ;
|
|
|
|
! Stack shuffling
|
|
SINGLETON: %data
|
|
SINGLETON: %retain
|
|
|
|
TUPLE: %peek < read-op n stack ;
|
|
TUPLE: %replace < write-op n stack ;
|
|
TUPLE: %height < nullary-op n stack ;
|
|
|
|
: stack-loc ( insn -- pair ) [ n>> ] [ stack>> ] bi 2array ;
|
|
|
|
TUPLE: commutative-op < binary-op ;
|
|
|
|
! Integer arithmetic
|
|
TUPLE: %iadd < commutative-op ;
|
|
TUPLE: %isub < binary-op ;
|
|
TUPLE: %imul < commutative-op ;
|
|
TUPLE: %idiv < binary-op ;
|
|
TUPLE: %imod < binary-op ;
|
|
TUPLE: %icmp < binary-op ;
|
|
|
|
! Bitwise ops
|
|
TUPLE: %not < unary-op ;
|
|
TUPLE: %and < commutative-op ;
|
|
TUPLE: %or < commutative-op ;
|
|
TUPLE: %xor < commutative-op ;
|
|
TUPLE: %shl < binary-op ;
|
|
TUPLE: %shr < binary-op ;
|
|
TUPLE: %sar < binary-op ;
|
|
|
|
! Float arithmetic
|
|
TUPLE: %fadd < commutative-op ;
|
|
TUPLE: %fsub < binary-op ;
|
|
TUPLE: %fmul < commutative-op ;
|
|
TUPLE: %fdiv < binary-op ;
|
|
TUPLE: %fcmp < binary-op ;
|
|
|
|
! Float/integer conversion
|
|
TUPLE: %f>i < unary-op ;
|
|
TUPLE: %i>f < unary-op ;
|
|
|
|
! Float boxing/unboxing
|
|
TUPLE: %%box-float < unary-op ;
|
|
TUPLE: %%unbox-float < unary-op ;
|
|
|
|
! High level slot accessors for alias analysis
|
|
! tag is f; if its not f, we can generate a faster sequence
|
|
TUPLE: %%slot < read-op obj slot tag ;
|
|
TUPLE: %%set-slot < write-op obj slot tag ;
|
|
|
|
TUPLE: %write-barrier < effect-op ;
|
|
|
|
! Memory
|
|
TUPLE: %load < unary-op ;
|
|
TUPLE: %store < effect-op addr ;
|
|
|
|
! Control flow; they jump to either the first or second successor
|
|
! of the BB
|
|
|
|
! Unconditional transfer to first successor
|
|
TUPLE: %b < nullary-op ;
|
|
|
|
SYMBOL: cc<
|
|
SYMBOL: cc<=
|
|
SYMBOL: cc=
|
|
SYMBOL: cc>
|
|
SYMBOL: cc>=
|
|
SYMBOL: cc/=
|
|
|
|
: evaluate-cc ( result cc -- ? )
|
|
H{
|
|
{ cc< { +lt+ } }
|
|
{ cc<= { +lt+ +eq+ } }
|
|
{ cc= { +eq+ } }
|
|
{ cc>= { +eq+ +gt+ } }
|
|
{ cc> { +gt+ } }
|
|
{ cc/= { +lt+ +gt+ } }
|
|
} at memq? ;
|
|
|
|
TUPLE: cond-branch < effect-op code ;
|
|
|
|
TUPLE: %bi < cond-branch ;
|
|
TUPLE: %bf < cond-branch ;
|
|
|
|
! Convert condition register to a boolean
|
|
TUPLE: boolean-op < unary-op code ;
|
|
|
|
TUPLE: %%iboolean < boolean-op ;
|
|
TUPLE: %%fboolean < boolean-op ;
|
|
|
|
! Dispatch table, jumps to successor 0..n-1 depending value of
|
|
! in, which must be in the range [0,n)
|
|
TUPLE: %dispatch < effect-op ;
|
|
|
|
! Procedures
|
|
TUPLE: %return < nullary-op ;
|
|
TUPLE: %prolog < nullary-op ;
|
|
TUPLE: %epilog < nullary-op ;
|
|
TUPLE: %jump < nullary-op word ;
|
|
TUPLE: %call < nullary-op word ;
|
|
|
|
! Heap allocation
|
|
TUPLE: %%allot < flushable-op size tag type ;
|