factor/basis/compiler/cfg/instructions/instructions.factor

316 lines
8.5 KiB
Factor
Raw Normal View History

! Copyright (C) 2008, 2009 Slava Pestov.
2008-09-10 23:11:03 -04:00
! See http://factorcode.org/license.txt for BSD license.
2008-10-17 16:35:04 -04:00
USING: assocs accessors arrays kernel sequences namespaces words
2008-10-20 02:56:28 -04:00
math math.order layouts classes.algebra alien byte-arrays
compiler.constants combinators compiler.cfg.registers
2008-10-20 02:56:28 -04:00
compiler.cfg.instructions.syntax ;
2008-09-15 02:54:48 -04:00
IN: compiler.cfg.instructions
2008-09-10 23:11:03 -04:00
: new-insn ( ... class -- insn ) f swap boa ; inline
2008-09-10 23:11:03 -04:00
! Virtual CPU instructions, used by CFG and machine IRs
TUPLE: insn ;
2008-09-10 23:11:03 -04:00
2008-10-20 02:56:28 -04:00
! Instruction with no side effects; if 'out' is never read, we
! can eliminate it.
TUPLE: ##flushable < insn dst ;
2008-10-20 02:56:28 -04:00
! Instruction which is referentially transparent; we can replace
! repeated computation with a reference to a previous value
TUPLE: ##pure < ##flushable ;
TUPLE: ##unary < ##pure src ;
TUPLE: ##unary/temp < ##unary temp ;
TUPLE: ##binary < ##pure src1 src2 ;
TUPLE: ##binary-imm < ##pure src1 { src2 integer } ;
2008-10-20 02:56:28 -04:00
TUPLE: ##commutative < ##binary ;
2008-10-22 22:58:46 -04:00
TUPLE: ##commutative-imm < ##binary-imm ;
2008-10-20 02:56:28 -04:00
! Instruction only used for its side effect, produces no values
TUPLE: ##effect < insn src ;
2008-10-20 02:56:28 -04:00
! Read/write ops: candidates for alias analysis
TUPLE: ##read < ##flushable ;
TUPLE: ##write < ##effect ;
TUPLE: ##alien-getter < ##flushable src ;
TUPLE: ##alien-setter < ##effect value ;
2008-09-10 23:11:03 -04:00
! Stack operations
2008-10-20 02:56:28 -04:00
INSN: ##load-immediate < ##pure { val integer } ;
INSN: ##load-reference < ##pure obj ;
2008-10-20 02:56:28 -04:00
GENERIC: ##load-literal ( dst value -- )
M: fixnum ##load-literal tag-fixnum ##load-immediate ;
M: f ##load-literal drop \ f tag-number ##load-immediate ;
M: object ##load-literal ##load-reference ;
2008-10-20 02:56:28 -04:00
INSN: ##peek < ##flushable { loc loc } ;
INSN: ##replace < ##effect { loc loc } ;
2008-10-17 16:35:04 -04:00
INSN: ##inc-d { n integer } ;
INSN: ##inc-r { n integer } ;
2008-09-10 23:11:03 -04:00
! Subroutine calls
INSN: ##call word ;
2008-09-17 01:46:38 -04:00
INSN: ##jump word ;
2008-10-07 17:13:29 -04:00
INSN: ##return ;
! Dummy instruction that simply inhibits TCO
INSN: ##no-tco ;
2008-09-10 23:11:03 -04:00
! Jump tables
INSN: ##dispatch src temp ;
2008-09-10 23:11:03 -04:00
2008-10-20 02:56:28 -04:00
! Slot access
INSN: ##slot < ##read obj slot { tag integer } temp ;
INSN: ##slot-imm < ##read obj { slot integer } { tag integer } ;
INSN: ##set-slot < ##write obj slot { tag integer } temp ;
INSN: ##set-slot-imm < ##write obj { slot integer } { tag integer } ;
2008-10-20 02:56:28 -04:00
2008-11-06 02:11:28 -05:00
! String element access
INSN: ##string-nth < ##flushable obj index temp ;
INSN: ##set-string-nth-fast < ##effect obj index temp ;
2008-11-06 02:11:28 -05:00
2008-10-20 02:56:28 -04:00
! Integer arithmetic
INSN: ##add < ##commutative ;
2008-10-22 22:58:46 -04:00
INSN: ##add-imm < ##commutative-imm ;
2008-10-20 02:56:28 -04:00
INSN: ##sub < ##binary ;
INSN: ##sub-imm < ##binary-imm ;
INSN: ##mul < ##commutative ;
2008-10-22 22:58:46 -04:00
INSN: ##mul-imm < ##commutative-imm ;
2008-10-20 02:56:28 -04:00
INSN: ##and < ##commutative ;
2008-10-22 22:58:46 -04:00
INSN: ##and-imm < ##commutative-imm ;
2008-10-20 02:56:28 -04:00
INSN: ##or < ##commutative ;
2008-10-22 22:58:46 -04:00
INSN: ##or-imm < ##commutative-imm ;
2008-10-20 02:56:28 -04:00
INSN: ##xor < ##commutative ;
2008-10-22 22:58:46 -04:00
INSN: ##xor-imm < ##commutative-imm ;
INSN: ##shl < ##binary ;
2008-10-20 02:56:28 -04:00
INSN: ##shl-imm < ##binary-imm ;
INSN: ##shr < ##binary ;
2008-10-20 02:56:28 -04:00
INSN: ##shr-imm < ##binary-imm ;
INSN: ##sar < ##binary ;
2008-10-20 02:56:28 -04:00
INSN: ##sar-imm < ##binary-imm ;
INSN: ##min < ##binary ;
INSN: ##max < ##binary ;
2008-10-20 02:56:28 -04:00
INSN: ##not < ##unary ;
INSN: ##log2 < ##unary ;
2008-10-20 02:56:28 -04:00
: ##tag-fixnum ( dst src -- ) tag-bits get ##shl-imm ; inline
: ##untag-fixnum ( dst src -- ) tag-bits get ##sar-imm ; inline
2008-10-20 02:56:28 -04:00
! Bignum/integer conversion
INSN: ##integer>bignum < ##unary/temp ;
INSN: ##bignum>integer < ##unary/temp ;
2008-10-20 02:56:28 -04:00
! Float arithmetic
INSN: ##add-float < ##commutative ;
INSN: ##sub-float < ##binary ;
INSN: ##mul-float < ##commutative ;
INSN: ##div-float < ##binary ;
INSN: ##min-float < ##binary ;
INSN: ##max-float < ##binary ;
INSN: ##sqrt < ##unary ;
2008-10-20 02:56:28 -04:00
! libc intrinsics
INSN: ##unary-float-function < ##unary func ;
INSN: ##binary-float-function < ##binary func ;
2008-10-20 02:56:28 -04:00
! Float/integer conversion
INSN: ##float>integer < ##unary ;
INSN: ##integer>float < ##unary ;
2008-09-10 23:11:03 -04:00
! Boxing and unboxing
INSN: ##copy < ##unary rep ;
2008-09-17 01:46:38 -04:00
INSN: ##unbox-float < ##unary ;
INSN: ##unbox-any-c-ptr < ##unary/temp ;
INSN: ##box-float < ##unary/temp ;
INSN: ##box-alien < ##unary/temp ;
INSN: ##box-displaced-alien < ##binary temp1 temp2 base-class ;
: ##unbox-f ( dst src -- ) drop 0 ##load-immediate ;
: ##unbox-byte-array ( dst src -- ) byte-array-offset ##add-imm ;
: ##unbox-alien ( dst src -- ) 3 object tag-number ##slot-imm ;
: ##unbox-c-ptr ( dst src class temp -- )
2008-10-20 02:56:28 -04:00
{
{ [ over \ f class<= ] [ 2drop ##unbox-f ] }
{ [ over simple-alien class<= ] [ 2drop ##unbox-alien ] }
{ [ over byte-array class<= ] [ 2drop ##unbox-byte-array ] }
[ nip ##unbox-any-c-ptr ]
} cond ;
2008-10-20 02:56:28 -04:00
! Alien accessors
INSN: ##alien-unsigned-1 < ##alien-getter ;
INSN: ##alien-unsigned-2 < ##alien-getter ;
INSN: ##alien-unsigned-4 < ##alien-getter ;
INSN: ##alien-signed-1 < ##alien-getter ;
INSN: ##alien-signed-2 < ##alien-getter ;
INSN: ##alien-signed-4 < ##alien-getter ;
2008-10-20 02:56:28 -04:00
INSN: ##alien-cell < ##alien-getter ;
INSN: ##alien-float < ##alien-getter ;
INSN: ##alien-double < ##alien-getter ;
INSN: ##set-alien-integer-1 < ##alien-setter ;
INSN: ##set-alien-integer-2 < ##alien-setter ;
INSN: ##set-alien-integer-4 < ##alien-setter ;
2008-10-22 00:17:32 -04:00
INSN: ##set-alien-cell < ##alien-setter ;
2008-10-20 02:56:28 -04:00
INSN: ##set-alien-float < ##alien-setter ;
INSN: ##set-alien-double < ##alien-setter ;
2008-09-17 01:46:38 -04:00
2008-09-17 19:52:11 -04:00
! Memory allocation
INSN: ##allot < ##flushable size class temp ;
UNION: ##allocation
##allot
##box-float
##box-alien
##box-displaced-alien
##integer>bignum ;
2008-10-20 02:56:28 -04:00
INSN: ##write-barrier < ##effect card# table ;
2008-09-10 23:11:03 -04:00
INSN: ##alien-global < ##flushable symbol library ;
2008-09-10 23:11:03 -04:00
! FFI
INSN: ##alien-invoke params stack-frame ;
INSN: ##alien-indirect params stack-frame ;
INSN: ##alien-callback params stack-frame ;
2008-10-13 00:32:14 -04:00
INSN: ##callback-return params ;
2008-09-10 23:11:03 -04:00
2008-09-17 01:46:38 -04:00
! Instructions used by CFG IR only.
INSN: ##prologue ;
INSN: ##epilogue ;
2008-09-15 02:54:48 -04:00
2008-09-17 01:46:38 -04:00
INSN: ##branch ;
2008-09-15 02:54:48 -04:00
INSN: ##phi < ##pure inputs ;
! Conditionals
TUPLE: ##conditional-branch < insn src1 src2 cc ;
INSN: ##compare-branch < ##conditional-branch ;
INSN: ##compare-imm-branch src1 { src2 integer } cc ;
2008-10-20 02:56:28 -04:00
INSN: ##compare < ##binary cc temp ;
INSN: ##compare-imm < ##binary-imm cc temp ;
INSN: ##compare-float-branch < ##conditional-branch ;
INSN: ##compare-float < ##binary cc temp ;
2008-09-11 03:05:22 -04:00
! Overflowing arithmetic
TUPLE: ##fixnum-overflow < insn dst src1 src2 ;
INSN: ##fixnum-add < ##fixnum-overflow ;
INSN: ##fixnum-sub < ##fixnum-overflow ;
INSN: ##fixnum-mul < ##fixnum-overflow ;
INSN: ##gc temp1 temp2 data-values tagged-values uninitialized-locs ;
2009-05-31 19:21:11 -04:00
2008-09-11 03:05:22 -04:00
! Instructions used by machine IR only.
2008-10-07 17:13:29 -04:00
INSN: _prologue stack-frame ;
INSN: _epilogue stack-frame ;
2008-09-11 03:05:22 -04:00
2008-09-17 01:46:38 -04:00
INSN: _label id ;
2008-09-11 03:05:22 -04:00
INSN: _branch label ;
INSN: _loop-entry ;
2008-09-17 01:46:38 -04:00
INSN: _dispatch src temp ;
INSN: _dispatch-label label ;
TUPLE: _conditional-branch < insn label src1 src2 cc ;
INSN: _compare-branch < _conditional-branch ;
INSN: _compare-imm-branch label src1 { src2 integer } cc ;
INSN: _compare-float-branch < _conditional-branch ;
2008-09-15 03:59:24 -04:00
! Overflowing arithmetic
TUPLE: _fixnum-overflow < insn label dst src1 src2 ;
INSN: _fixnum-add < _fixnum-overflow ;
INSN: _fixnum-sub < _fixnum-overflow ;
INSN: _fixnum-mul < _fixnum-overflow ;
TUPLE: spill-slot n ; C: <spill-slot> spill-slot
INSN: _gc temp1 temp2 data-values tagged-values uninitialized-locs ;
2008-10-19 02:10:21 -04:00
! These instructions operate on machine registers and not
! virtual registers
INSN: _spill src rep n ;
INSN: _reload dst rep n ;
INSN: _spill-area-size n ;
! Instructions that use vregs
UNION: vreg-insn
##flushable
##write-barrier
##dispatch
##effect
##fixnum-overflow
##conditional-branch
##compare-imm-branch
##phi
##gc
_conditional-branch
_compare-imm-branch
_dispatch ;
! Instructions that kill all live vregs but cannot trigger GC
UNION: partial-sync-insn
##unary-float-function
##binary-float-function ;
! Instructions that kill all live vregs
UNION: kill-vreg-insn
##call
##prologue
##epilogue
##alien-invoke
##alien-indirect
##alien-callback ;
! Instructions that output floats
UNION: output-float-insn
##add-float
##sub-float
##mul-float
##div-float
##min-float
##max-float
##sqrt
##unary-float-function
##binary-float-function
##integer>float
##unbox-float
##alien-float
##alien-double ;
! Instructions that take floats as inputs
UNION: input-float-insn
##add-float
##sub-float
##mul-float
##div-float
##min-float
##max-float
##sqrt
##unary-float-function
##binary-float-function
##float>integer
##box-float
##set-alien-float
##set-alien-double
##compare-float
##compare-float-branch ;
! Smackdown
INTERSECTION: ##unary-float ##unary input-float-insn ;
INTERSECTION: ##binary-float ##binary input-float-insn ;
! Instructions that have complex expansions and require that the
! output registers are not equal to any of the input registers
UNION: def-is-use-insn
##integer>bignum
##bignum>integer
##unbox-any-c-ptr ;