namespaces sequences words ;
\ slot [
- { { any-reg "obj" } { any-reg "n" } } { "obj" } [
+ H{
+ { +input-d { { f "obj" } { f "n" } } }
+ { +output-d { "obj" } }
+ } [
"obj" get %untag ,
"n" get "obj" get %slot ,
] with-template
] "intrinsic" set-word-prop
\ set-slot [
- { { any-reg "val" } { any-reg "obj" } { any-reg "slot" } }
- { } [
+ H{
+ { +input-d { { f "val" } { f "obj" } { f "slot" } } }
+ { +clobber { "obj" } }
+ } [
"obj" get %untag ,
"val" get "obj" get "slot" get %set-slot ,
finalize-contents
] "intrinsic" set-word-prop
\ char-slot [
- { { any-reg "n" } { any-reg "str" } } { "str" } [
+ H{
+ { +input-d { { f "n" } { f "str" } } }
+ { +output-d { "str" } }
+ } [
"n" get "str" get %char-slot ,
] with-template
] "intrinsic" set-word-prop
\ set-char-slot [
- { { any-reg "ch" } { any-reg "n" } { any-reg "str" } } { } [
+ H{
+ { +input-d { { f "ch" } { f "n" } { f "str" } } }
+ } [
"ch" get "str" get "n" get %set-char-slot ,
] with-template
] "intrinsic" set-word-prop
\ type [
- { { any-reg "in" } } { "in" }
- [ finalize-contents "in" get %type , ] with-template
+ H{
+ { +input-d { { f "in" } } }
+ { +output-d { "in" } }
+ } [ finalize-contents "in" get %type , ] with-template
] "intrinsic" set-word-prop
\ tag [
- { { any-reg "in" } } { "in" }
- [ "in" get %tag , ] with-template
+ H{
+ { +input-d { { f "in" } } }
+ { +output-d { "in" } }
+ } [ "in" get %tag , ] with-template
] "intrinsic" set-word-prop
: binary-op ( op -- )
- { { 0 "x" } { 1 "y" } } { "x" } [
+ H{
+ { +input-d { { 0 "x" } { 1 "y" } } }
+ { +output-d { "x" } }
+ } [
finalize-contents >r "y" get "x" get dup r> execute ,
] with-template ; inline
] each
: binary-jump ( label op -- )
- { { any-reg "x" } { any-reg "y" } } { } [
+ H{
+ { +input-d { { f "x" } { f "y" } } }
+ } [
end-basic-block >r >r "y" get "x" get r> r> execute ,
] with-template ; inline
! This is not clever. Because of x86, %fixnum-mod is
! hard-coded to put its output in vreg 2, which happends to
! be EDX there.
- { { 0 "x" } { 1 "y" } } { "out" } [
+ H{
+ { +input-d { { 0 "x" } { 1 "y" } } }
+ { +output-d { "out" } }
+ } [
finalize-contents
T{ vreg f 2 } "out" set
"y" get "x" get "out" get %fixnum-mod ,
\ fixnum/mod [
! See the remark on fixnum-mod for vreg usage
- { { 0 "x" } { 1 "y" } } { "quo" "rem" } [
+ H{
+ { +input-d { { 0 "x" } { 1 "y" } } }
+ { +output-d { "quo" "rem" } }
+ } [
finalize-contents
T{ vreg f 0 } "quo" set
T{ vreg f 2 } "rem" set
] "intrinsic" set-word-prop
\ fixnum-bitnot [
- { { any-reg "x" } } { "x" } [
- "x" get dup %fixnum-bitnot ,
- ] with-template
+ H{
+ { +input-d { { f "x" } } }
+ { +output-d { "x" } }
+ } [ "x" get dup %fixnum-bitnot , ] with-template
] "intrinsic" set-word-prop
node-param renamed-label linearize-call ;
M: #if linearize* ( node -- next )
- { { 0 "flag" } } { } [
+ H{
+ { +input-d { { 0 "flag" } } }
+ } [
end-basic-block
<label> dup "flag" get %jump-t ,
] with-template linearize-if ;
: dispatch-head ( node -- label/node )
#! Output the jump table insn and return a list of
#! label/branch pairs.
- { { 0 "n" } } { }
- [ end-basic-block "n" get %dispatch , ] with-template
+ H{
+ { +input-d { { 0 "n" } } }
+ } [ end-basic-block "n" get %dispatch , ] with-template
node-children [ <label> dup %target-label , 2array ] map ;
: dispatch-body ( label/node -- )
: end-basic-block ( -- )
finalize-contents finalize-heights ;
-SYMBOL: any-reg
-
: used-vregs ( -- seq )
phantoms append [ vreg? ] subset [ vreg-n ] map ;
>vector free-vregs set ;
: requested-vregs ( template -- n )
- [ any-reg eq? ] subset length ;
+ 0 [ [ 1+ ] unless ] reduce ;
: template-vreg# ( template template -- n )
[ requested-vregs ] 2apply + ;
: alloc-regs ( template -- template )
- [ dup any-reg eq? [ drop alloc-reg ] when ] map ;
+ [ [ alloc-reg ] unless* ] map ;
: alloc-reg# ( n -- regs )
free-vregs [ cut ] change ;
: compatible-values? ( value template -- ? )
{
- { [ over ds-loc? ] [ 2drop t ] }
- { [ over cs-loc? ] [ 2drop t ] }
+ { [ over loc? ] [ 2drop t ] }
{ [ dup not ] [ 2drop t ] }
{ [ over not ] [ 2drop f ] }
- { [ dup any-reg eq? ] [ 2drop t ] }
{ [ dup integer? ] [ swap vreg-n = ] }
} cond ;
swap phantom-vregs ;
: fast-input ( template template -- )
- phantom-r get (fast-input)
- phantom-d get (fast-input) ;
+ phantoms swapd (fast-input) (fast-input) ;
: (slow-input) ( template phantom -- )
swap [ stack>vregs ] keep phantom-vregs ;
-: slow-input ( template template -- )
- phantom-r get (slow-input)
- phantom-d get (slow-input) ;
+: phantom-append ( seq stack -- )
+ over length over adjust-phantom swap nappend ;
+
+: (template-outputs) ( seq stack -- )
+ phantoms swapd phantom-append phantom-append ;
+
+SYMBOL: +input-d
+SYMBOL: +input-r
+SYMBOL: +output-d
+SYMBOL: +output-r
+SYMBOL: +scratch
+SYMBOL: +clobber
+
+: fix-spec ( spec -- spec )
+ H{
+ { +input-d { } }
+ { +input-r { } }
+ { +output-d { } }
+ { +output-r { } }
+ { +scratch { } }
+ { +clobber { } }
+ } swap hash-union ;
: adjust-free-vregs ( -- )
used-vregs free-vregs [ diff ] change ;
-: template-inputs ( template template -- )
+: output-vregs ( -- seq )
+ { +output-d +output-r +clobber }
+ [ get [ get ] map ] map concat ;
+
+: finalize-contents? ( -- ? )
+ output-vregs phantoms append
+ [ swap member? ] contains-with? ;
+
+: slow-input ( template template -- )
+ 2dup [ empty? not ] 2apply or finalize-contents? or
+ [ finalize-contents ] when
+ phantoms swapd (slow-input) (slow-input) ;
+
+: template-inputs ( -- )
+ +input-d get +input-r get
2dup additional-vregs# ensure-vregs
match-templates fast-input
adjust-free-vregs
- finalize-contents
slow-input ;
-: phantom-append ( seq stack -- )
- over length over adjust-phantom swap nappend ;
-
-: (template-outputs) ( seq stack -- )
- phantom-r get phantom-append phantom-d get phantom-append ;
-
-: template-outputs ( stack stack -- )
- [ [ get ] map ] 2apply (template-outputs) ;
+: template-outputs ( -- )
+ +output-d get +output-r get [ [ get ] map ] 2apply
+ (template-outputs) ;
-: with-template ( in out quot -- )
- swap >r >r { } template-inputs
- r> call r> { } template-outputs ; inline
+: with-template ( spec quot -- )
+ swap fix-spec [
+ template-inputs call template-outputs
+ ] bind ; inline
C: %label make-vop ;
: %label label-vop <%label> ;
-! Return vops take a label that is ignored, to have the
-! same stack effect as jumps. This is needed for the
-! simplifier.
TUPLE: %return ;
C: %return make-vop ;
: %return empty-vop <%return> ;