! Copyright (C) 2008, 2011 Slava Pestov. ! See http://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## ;