! Copyright (C) 2008, 2011 Slava Pestov. ! See https://factorcode.org/license.txt for BSD license. USING: accessors compiler.cfg.instructions.syntax kernel math namespaces ; IN: compiler.cfg.instructions << SYMBOL: insn-classes V{ } clone insn-classes set-global >> : new-insn ( ... class -- insn ) f swap boa ; inline TUPLE: insn ; TUPLE: vreg-insn < insn ; TUPLE: flushable-insn < vreg-insn ; TUPLE: foldable-insn < flushable-insn ; ! Constants FOLDABLE-INSN: ##load-integer def: dst/int-rep literal: val ; FOLDABLE-INSN: ##load-reference def: dst/tagged-rep literal: obj ; ! These four are inserted by representation selection FLUSHABLE-INSN: ##load-tagged def: dst/tagged-rep literal: val ; FLUSHABLE-INSN: ##load-float def: dst/float-rep literal: val ; FLUSHABLE-INSN: ##load-double def: dst/double-rep literal: val ; FLUSHABLE-INSN: ##load-vector def: dst literal: val rep ; ! Stack operations FLUSHABLE-INSN: ##peek def: dst/tagged-rep literal: loc ; VREG-INSN: ##replace use: src/tagged-rep literal: loc ; INSN: ##replace-imm literal: src loc ; INSN: ##clear literal: loc ; INSN: ##inc literal: loc ; ! Subroutine calls INSN: ##call literal: word ; INSN: ##jump literal: word ; INSN: ##prologue ; INSN: ##epilogue ; INSN: ##return ; INSN: ##safepoint ; INSN: ##no-tco ; ! Jump tables VREG-INSN: ##dispatch use: src/int-rep temp: temp/int-rep ; ! Slot access FLUSHABLE-INSN: ##slot def: dst/tagged-rep use: obj/tagged-rep slot/int-rep literal: scale tag ; FLUSHABLE-INSN: ##slot-imm def: dst/tagged-rep use: obj/tagged-rep literal: slot tag ; VREG-INSN: ##set-slot use: src/tagged-rep obj/tagged-rep slot/int-rep literal: scale tag ; VREG-INSN: ##set-slot-imm use: src/tagged-rep obj/tagged-rep literal: slot tag ; ! Register transfers FOLDABLE-INSN: ##copy def: dst use: src literal: rep ; ! Only used by compiler.cfg.cssa FLUSHABLE-INSN: ##parallel-copy literal: values ; FOLDABLE-INSN: ##tagged>integer def: dst/int-rep use: src/tagged-rep ; ! Integer arithmetic FOLDABLE-INSN: ##add def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##add-imm def: dst/int-rep use: src1/int-rep literal: src2 ; FOLDABLE-INSN: ##sub def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##sub-imm def: dst/int-rep use: src1/int-rep literal: src2 ; FOLDABLE-INSN: ##mul def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##mul-imm def: dst/int-rep use: src1/int-rep literal: src2 ; FOLDABLE-INSN: ##and def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##and-imm def: dst/int-rep use: src1/int-rep literal: src2 ; FOLDABLE-INSN: ##or def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##or-imm def: dst/int-rep use: src1/int-rep literal: src2 ; FOLDABLE-INSN: ##xor def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##xor-imm def: dst/int-rep use: src1/int-rep literal: src2 ; FOLDABLE-INSN: ##shl def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##shl-imm def: dst/int-rep use: src1/int-rep literal: src2 ; FOLDABLE-INSN: ##shr def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##shr-imm def: dst/int-rep use: src1/int-rep literal: src2 ; FOLDABLE-INSN: ##sar def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##sar-imm def: dst/int-rep use: src1/int-rep literal: src2 ; FOLDABLE-INSN: ##min def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##max def: dst/int-rep use: src1/int-rep src2/int-rep ; FOLDABLE-INSN: ##not def: dst/int-rep use: src/int-rep ; FOLDABLE-INSN: ##neg def: dst/int-rep use: src/int-rep ; FOLDABLE-INSN: ##log2 def: dst/int-rep use: src/int-rep ; FOLDABLE-INSN: ##bit-count def: dst/int-rep use: src/int-rep ; FOLDABLE-INSN: ##bit-test def: dst/tagged-rep use: src1/int-rep src2/int-rep temp: temp/int-rep ; ! Float arithmetic FOLDABLE-INSN: ##add-float def: dst/double-rep use: src1/double-rep src2/double-rep ; FOLDABLE-INSN: ##sub-float def: dst/double-rep use: src1/double-rep src2/double-rep ; FOLDABLE-INSN: ##mul-float def: dst/double-rep use: src1/double-rep src2/double-rep ; FOLDABLE-INSN: ##div-float def: dst/double-rep use: src1/double-rep src2/double-rep ; FOLDABLE-INSN: ##min-float def: dst/double-rep use: src1/double-rep src2/double-rep ; FOLDABLE-INSN: ##max-float def: dst/double-rep use: src1/double-rep src2/double-rep ; FOLDABLE-INSN: ##sqrt def: dst/double-rep use: src/double-rep ; ! Single/double float conversion FOLDABLE-INSN: ##single>double-float def: dst/double-rep use: src/float-rep ; FOLDABLE-INSN: ##double>single-float def: dst/float-rep use: src/double-rep ; ! Float/integer conversion FOLDABLE-INSN: ##float>integer def: dst/int-rep use: src/double-rep ; FOLDABLE-INSN: ##integer>float def: dst/double-rep use: src/int-rep ; ! SIMD operations FOLDABLE-INSN: ##zero-vector def: dst literal: rep ; FOLDABLE-INSN: ##fill-vector def: dst literal: rep ; FOLDABLE-INSN: ##gather-vector-2 def: dst use: src1/scalar-rep src2/scalar-rep literal: rep ; FOLDABLE-INSN: ##gather-int-vector-2 def: dst use: src1/int-rep src2/int-rep literal: rep ; FOLDABLE-INSN: ##gather-vector-4 def: dst use: src1/scalar-rep src2/scalar-rep src3/scalar-rep src4/scalar-rep literal: rep ; FOLDABLE-INSN: ##gather-int-vector-4 def: dst use: src1/int-rep src2/int-rep src3/int-rep src4/int-rep literal: rep ; FOLDABLE-INSN: ##select-vector def: dst/int-rep use: src literal: n rep ; FOLDABLE-INSN: ##shuffle-vector def: dst use: src shuffle literal: rep ; FOLDABLE-INSN: ##shuffle-vector-halves-imm def: dst use: src1 src2 literal: shuffle rep ; FOLDABLE-INSN: ##shuffle-vector-imm def: dst use: src literal: shuffle rep ; FOLDABLE-INSN: ##tail>head-vector def: dst use: src literal: rep ; FOLDABLE-INSN: ##merge-vector-head def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##merge-vector-tail def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##float-pack-vector def: dst use: src literal: rep ; FOLDABLE-INSN: ##signed-pack-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##unsigned-pack-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##unpack-vector-head def: dst use: src literal: rep ; FOLDABLE-INSN: ##unpack-vector-tail def: dst use: src literal: rep ; FOLDABLE-INSN: ##integer>float-vector def: dst use: src literal: rep ; FOLDABLE-INSN: ##float>integer-vector def: dst use: src literal: rep ; FOLDABLE-INSN: ##compare-vector def: dst use: src1 src2 literal: rep cc ; FOLDABLE-INSN: ##move-vector-mask def: dst/int-rep use: src literal: rep ; FOLDABLE-INSN: ##test-vector def: dst/tagged-rep use: src1 temp: temp/int-rep literal: rep vcc ; VREG-INSN: ##test-vector-branch use: src1 temp: temp/int-rep literal: rep vcc ; FOLDABLE-INSN: ##add-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##saturated-add-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##add-sub-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##sub-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##saturated-sub-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##mul-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##mul-high-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##mul-horizontal-add-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##saturated-mul-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##div-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##min-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##max-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##avg-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##dot-vector def: dst/scalar-rep use: src1 src2 literal: rep ; FOLDABLE-INSN: ##sad-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##horizontal-add-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##horizontal-sub-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##horizontal-shl-vector-imm def: dst use: src1 literal: src2 rep ; FOLDABLE-INSN: ##horizontal-shr-vector-imm def: dst use: src1 literal: src2 rep ; FOLDABLE-INSN: ##abs-vector def: dst use: src literal: rep ; FOLDABLE-INSN: ##sqrt-vector def: dst use: src literal: rep ; FOLDABLE-INSN: ##and-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##andn-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##or-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##xor-vector def: dst use: src1 src2 literal: rep ; FOLDABLE-INSN: ##not-vector def: dst use: src literal: rep ; FOLDABLE-INSN: ##shl-vector-imm def: dst use: src1 literal: src2 rep ; FOLDABLE-INSN: ##shr-vector-imm def: dst use: src1 literal: src2 rep ; FOLDABLE-INSN: ##shl-vector def: dst use: src1 src2/int-scalar-rep literal: rep ; FOLDABLE-INSN: ##shr-vector def: dst use: src1 src2/int-scalar-rep literal: rep ; ! Scalar/vector conversion FOLDABLE-INSN: ##scalar>integer def: dst/int-rep use: src literal: rep ; FOLDABLE-INSN: ##integer>scalar def: dst use: src/int-rep literal: rep ; FOLDABLE-INSN: ##vector>scalar def: dst/scalar-rep use: src literal: rep ; FOLDABLE-INSN: ##scalar>vector def: dst use: src/scalar-rep literal: rep ; ! Boxing and unboxing aliens FOLDABLE-INSN: ##box-alien def: dst/tagged-rep use: src/int-rep temp: temp/int-rep ; FOLDABLE-INSN: ##box-displaced-alien def: dst/tagged-rep use: displacement/int-rep base/tagged-rep temp: temp/int-rep literal: base-class ; FOLDABLE-INSN: ##unbox-any-c-ptr def: dst/int-rep use: src/tagged-rep ; FOLDABLE-INSN: ##unbox-alien def: dst/int-rep use: src/tagged-rep ; ! Zero-extending and sign-extending integers FOLDABLE-INSN: ##convert-integer def: dst/int-rep use: src/int-rep literal: c-type ; ! Raw memory accessors FLUSHABLE-INSN: ##load-memory def: dst use: base/int-rep displacement/int-rep literal: scale offset rep c-type ; FLUSHABLE-INSN: ##load-memory-imm def: dst use: base/int-rep literal: offset rep c-type ; VREG-INSN: ##store-memory use: src base/int-rep displacement/int-rep literal: scale offset rep c-type ; VREG-INSN: ##store-memory-imm use: src base/int-rep literal: offset rep c-type ; ! Memory allocation FLUSHABLE-INSN: ##allot def: dst/tagged-rep literal: size class-of temp: temp/int-rep ; VREG-INSN: ##write-barrier use: src/tagged-rep slot/int-rep literal: scale tag temp: temp1/int-rep temp2/int-rep ; VREG-INSN: ##write-barrier-imm use: src/tagged-rep literal: slot tag temp: temp1/int-rep temp2/int-rep ; FLUSHABLE-INSN: ##alien-global def: dst/int-rep literal: symbol library ; FLUSHABLE-INSN: ##vm-field def: dst/tagged-rep literal: offset ; VREG-INSN: ##set-vm-field use: src/tagged-rep literal: offset ; ! FFI FOLDABLE-INSN: ##unbox def: dst use: src/tagged-rep literal: unboxer rep ; FOLDABLE-INSN: ##unbox-long-long def: dst1/int-rep dst2/int-rep use: src/tagged-rep literal: unboxer ; FLUSHABLE-INSN: ##local-allot def: dst/int-rep literal: size align offset ; FOLDABLE-INSN: ##box def: dst/tagged-rep use: src literal: boxer rep gc-map ; FOLDABLE-INSN: ##box-long-long def: dst/tagged-rep use: src1/int-rep src2/int-rep literal: boxer gc-map ; ! Alien call inputs and outputs are arrays of triples with shape ! { vreg rep stack#/reg } VREG-INSN: ##alien-invoke literal: varargs? reg-inputs stack-inputs reg-outputs dead-outputs cleanup stack-size symbols dll gc-map ; VREG-INSN: ##alien-indirect use: src/int-rep literal: varargs? reg-inputs stack-inputs reg-outputs dead-outputs cleanup stack-size gc-map ; VREG-INSN: ##alien-assembly literal: varargs? reg-inputs stack-inputs reg-outputs dead-outputs cleanup stack-size quot ; VREG-INSN: ##callback-inputs literal: reg-outputs stack-outputs ; VREG-INSN: ##callback-outputs literal: reg-inputs ; ! Control flow FLUSHABLE-INSN: ##phi def: dst literal: inputs ; INSN: ##branch ; ! Tagged conditionals VREG-INSN: ##compare-branch use: src1/tagged-rep src2/tagged-rep literal: cc ; VREG-INSN: ##compare-imm-branch use: src1/tagged-rep literal: src2 cc ; FOLDABLE-INSN: ##compare def: dst/tagged-rep use: src1/tagged-rep src2/tagged-rep literal: cc temp: temp/int-rep ; FOLDABLE-INSN: ##compare-imm def: dst/tagged-rep use: src1/tagged-rep literal: src2 cc temp: temp/int-rep ; ! Integer conditionals VREG-INSN: ##compare-integer-branch use: src1/int-rep src2/int-rep literal: cc ; VREG-INSN: ##compare-integer-imm-branch use: src1/int-rep literal: src2 cc ; VREG-INSN: ##test-branch use: src1/int-rep src2/int-rep literal: cc ; VREG-INSN: ##test-imm-branch use: src1/int-rep literal: src2 cc ; FOLDABLE-INSN: ##compare-integer def: dst/tagged-rep use: src1/int-rep src2/int-rep literal: cc temp: temp/int-rep ; FOLDABLE-INSN: ##compare-integer-imm def: dst/tagged-rep use: src1/int-rep literal: src2 cc temp: temp/int-rep ; FOLDABLE-INSN: ##test def: dst/tagged-rep use: src1/int-rep src2/int-rep literal: cc temp: temp/int-rep ; FOLDABLE-INSN: ##test-imm def: dst/tagged-rep use: src1/int-rep literal: src2 cc temp: temp/int-rep ; ! Float conditionals VREG-INSN: ##compare-float-ordered-branch use: src1/double-rep src2/double-rep literal: cc ; VREG-INSN: ##compare-float-unordered-branch use: src1/double-rep src2/double-rep literal: cc ; FOLDABLE-INSN: ##compare-float-ordered def: dst/tagged-rep use: src1/double-rep src2/double-rep literal: cc temp: temp/int-rep ; FOLDABLE-INSN: ##compare-float-unordered def: dst/tagged-rep use: src1/double-rep src2/double-rep literal: cc temp: temp/int-rep ; ! Overflowing arithmetic VREG-INSN: ##fixnum-add def: dst/tagged-rep use: src1/tagged-rep src2/tagged-rep literal: cc ; VREG-INSN: ##fixnum-sub def: dst/tagged-rep use: src1/tagged-rep src2/tagged-rep literal: cc ; VREG-INSN: ##fixnum-mul def: dst/tagged-rep use: src1/tagged-rep src2/int-rep literal: cc ; VREG-INSN: ##save-context temp: temp1/int-rep temp2/int-rep ; ! GC checks VREG-INSN: ##check-nursery-branch literal: size cc temp: temp1/int-rep temp2/int-rep ; INSN: ##call-gc literal: gc-map ; ! Spills and reloads, inserted by register allocator TUPLE: spill-slot { n integer } ; C: spill-slot VREG-INSN: ##spill use: src literal: rep dst ; VREG-INSN: ##reload def: dst literal: rep src ; UNION: allocation-insn ##allot ##box-alien ##box-displaced-alien ; UNION: conditional-branch-insn ##compare-branch ##compare-imm-branch ##compare-integer-branch ##compare-integer-imm-branch ##test-branch ##test-imm-branch ##compare-float-ordered-branch ##compare-float-unordered-branch ##test-vector-branch ##check-nursery-branch ##fixnum-add ##fixnum-sub ##fixnum-mul ; ! For alias analysis UNION: read-insn ##slot ##slot-imm ##vm-field ##alien-global ; UNION: write-insn ##set-slot ##set-slot-imm ##set-vm-field ; UNION: alien-call-insn ##alien-assembly ##alien-indirect ##alien-invoke ; UNION: gc-map-insn ##call-gc ##box ##box-long-long ##alien-indirect ##alien-invoke ; M: gc-map-insn clone call-next-method [ clone ] change-gc-map ; TUPLE: gc-map gc-roots derived-roots ; : ( -- gc-map ) gc-map new ; UNION: def-is-use-insn ##box-alien ##box-displaced-alien ##unbox-any-c-ptr ;