Split off the notion of a register representation from a register class
parent
ef97fdf0c5
commit
725280d424
|
@ -31,7 +31,7 @@ M: array c-type-boxer-quot drop [ ] ;
|
||||||
|
|
||||||
M: array c-type-unboxer-quot drop [ >c-ptr ] ;
|
M: array c-type-unboxer-quot drop [ >c-ptr ] ;
|
||||||
|
|
||||||
M: value-type c-type-reg-class drop int-regs ;
|
M: value-type c-type-rep drop int-rep ;
|
||||||
|
|
||||||
M: value-type c-type-getter
|
M: value-type c-type-getter
|
||||||
drop [ swap <displaced-alien> ] ;
|
drop [ swap <displaced-alien> ] ;
|
||||||
|
@ -72,8 +72,8 @@ M: string-type box-return
|
||||||
M: string-type stack-size
|
M: string-type stack-size
|
||||||
drop "void*" stack-size ;
|
drop "void*" stack-size ;
|
||||||
|
|
||||||
M: string-type c-type-reg-class
|
M: string-type c-type-rep
|
||||||
drop int-regs ;
|
drop int-rep ;
|
||||||
|
|
||||||
M: string-type c-type-boxer
|
M: string-type c-type-boxer
|
||||||
drop "void*" c-type-boxer ;
|
drop "void*" c-type-boxer ;
|
||||||
|
|
|
@ -21,7 +21,7 @@ unboxer
|
||||||
{ unboxer-quot callable }
|
{ unboxer-quot callable }
|
||||||
{ getter callable }
|
{ getter callable }
|
||||||
{ setter callable }
|
{ setter callable }
|
||||||
{ reg-class initial: int-regs }
|
{ rep initial: int-rep }
|
||||||
size
|
size
|
||||||
align
|
align
|
||||||
stack-align? ;
|
stack-align? ;
|
||||||
|
@ -98,11 +98,11 @@ M: c-type c-type-unboxer-quot unboxer-quot>> ;
|
||||||
|
|
||||||
M: string c-type-unboxer-quot c-type c-type-unboxer-quot ;
|
M: string c-type-unboxer-quot c-type c-type-unboxer-quot ;
|
||||||
|
|
||||||
GENERIC: c-type-reg-class ( name -- reg-class )
|
GENERIC: c-type-rep ( name -- rep )
|
||||||
|
|
||||||
M: c-type c-type-reg-class reg-class>> ;
|
M: c-type c-type-rep rep>> ;
|
||||||
|
|
||||||
M: string c-type-reg-class c-type c-type-reg-class ;
|
M: string c-type-rep c-type c-type-rep ;
|
||||||
|
|
||||||
GENERIC: c-type-getter ( name -- quot )
|
GENERIC: c-type-getter ( name -- quot )
|
||||||
|
|
||||||
|
@ -129,13 +129,11 @@ M: c-type c-type-stack-align? stack-align?>> ;
|
||||||
M: string c-type-stack-align? c-type c-type-stack-align? ;
|
M: string c-type-stack-align? c-type c-type-stack-align? ;
|
||||||
|
|
||||||
: c-type-box ( n type -- )
|
: c-type-box ( n type -- )
|
||||||
dup c-type-reg-class
|
[ c-type-rep ] [ c-type-boxer [ "No boxer" throw ] unless* ] bi
|
||||||
swap c-type-boxer [ "No boxer" throw ] unless*
|
|
||||||
%box ;
|
%box ;
|
||||||
|
|
||||||
: c-type-unbox ( n ctype -- )
|
: c-type-unbox ( n ctype -- )
|
||||||
dup c-type-reg-class
|
[ c-type-rep ] [ c-type-unboxer [ "No unboxer" throw ] unless* ] bi
|
||||||
swap c-type-unboxer [ "No unboxer" throw ] unless*
|
|
||||||
%unbox ;
|
%unbox ;
|
||||||
|
|
||||||
GENERIC: box-parameter ( n ctype -- )
|
GENERIC: box-parameter ( n ctype -- )
|
||||||
|
@ -426,7 +424,7 @@ CONSTANT: primitive-types
|
||||||
4 >>align
|
4 >>align
|
||||||
"box_float" >>boxer
|
"box_float" >>boxer
|
||||||
"to_float" >>unboxer
|
"to_float" >>unboxer
|
||||||
single-float-regs >>reg-class
|
single-float-rep >>rep
|
||||||
[ >float ] >>unboxer-quot
|
[ >float ] >>unboxer-quot
|
||||||
"float" define-primitive-type
|
"float" define-primitive-type
|
||||||
|
|
||||||
|
@ -438,7 +436,7 @@ CONSTANT: primitive-types
|
||||||
8 >>align
|
8 >>align
|
||||||
"box_double" >>boxer
|
"box_double" >>boxer
|
||||||
"to_double" >>unboxer
|
"to_double" >>unboxer
|
||||||
double-float-regs >>reg-class
|
double-float-rep >>rep
|
||||||
[ >float ] >>unboxer-quot
|
[ >float ] >>unboxer-quot
|
||||||
"double" define-primitive-type
|
"double" define-primitive-type
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2008, 2009 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel math namespaces assocs hashtables sequences arrays
|
USING: kernel math namespaces assocs hashtables sequences arrays
|
||||||
accessors vectors combinators sets classes compiler.cfg
|
accessors vectors combinators sets classes cpu.architecture compiler.cfg
|
||||||
compiler.cfg.registers compiler.cfg.instructions
|
compiler.cfg.registers compiler.cfg.instructions
|
||||||
compiler.cfg.copy-prop compiler.cfg.rpo compiler.cfg.liveness ;
|
compiler.cfg.copy-prop compiler.cfg.rpo compiler.cfg.liveness ;
|
||||||
IN: compiler.cfg.alias-analysis
|
IN: compiler.cfg.alias-analysis
|
||||||
|
@ -226,7 +226,7 @@ M: ##read analyze-aliases*
|
||||||
call-next-method
|
call-next-method
|
||||||
dup [ dst>> ] [ insn-slot# ] [ insn-object ] tri
|
dup [ dst>> ] [ insn-slot# ] [ insn-object ] tri
|
||||||
2dup live-slot dup [
|
2dup live-slot dup [
|
||||||
2nip \ ##copy new-insn analyze-aliases* nip
|
2nip int-rep \ ##copy new-insn analyze-aliases* nip
|
||||||
] [
|
] [
|
||||||
drop remember-slot
|
drop remember-slot
|
||||||
] if ;
|
] if ;
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
! Copyright (C) 2008, 2009 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: namespaces accessors math.order assocs kernel sequences
|
USING: namespaces accessors math.order assocs kernel sequences
|
||||||
combinators make classes words cpu.architecture
|
combinators make classes words cpu.architecture layouts
|
||||||
compiler.cfg.instructions compiler.cfg.registers
|
compiler.cfg.instructions compiler.cfg.registers
|
||||||
compiler.cfg.stack-frame ;
|
compiler.cfg.stack-frame ;
|
||||||
IN: compiler.cfg.build-stack-frame
|
IN: compiler.cfg.build-stack-frame
|
||||||
|
|
||||||
SYMBOL: frame-required?
|
SYMBOL: frame-required?
|
||||||
|
|
||||||
SYMBOL: spill-counts
|
|
||||||
|
|
||||||
GENERIC: compute-stack-frame* ( insn -- )
|
GENERIC: compute-stack-frame* ( insn -- )
|
||||||
|
|
||||||
: request-stack-frame ( stack-frame -- )
|
: request-stack-frame ( stack-frame -- )
|
||||||
|
@ -30,11 +28,11 @@ M: ##call compute-stack-frame*
|
||||||
|
|
||||||
M: _gc compute-stack-frame*
|
M: _gc compute-stack-frame*
|
||||||
frame-required? on
|
frame-required? on
|
||||||
stack-frame new swap gc-root-size>> >>gc-root-size
|
stack-frame new swap gc-root-size>> cells >>gc-root-size
|
||||||
request-stack-frame ;
|
request-stack-frame ;
|
||||||
|
|
||||||
M: _spill-counts compute-stack-frame*
|
M: _spill-area-size compute-stack-frame*
|
||||||
counts>> stack-frame get (>>spill-counts) ;
|
n>> stack-frame get (>>spill-area-size) ;
|
||||||
|
|
||||||
M: insn compute-stack-frame*
|
M: insn compute-stack-frame*
|
||||||
class frame-required? word-prop [
|
class frame-required? word-prop [
|
||||||
|
@ -45,7 +43,7 @@ M: insn compute-stack-frame*
|
||||||
|
|
||||||
: compute-stack-frame ( insns -- )
|
: compute-stack-frame ( insns -- )
|
||||||
frame-required? off
|
frame-required? off
|
||||||
T{ stack-frame } clone stack-frame set
|
stack-frame new stack-frame set
|
||||||
[ compute-stack-frame* ] each
|
[ compute-stack-frame* ] each
|
||||||
stack-frame get dup stack-frame-size >>total-size drop ;
|
stack-frame get dup stack-frame-size >>total-size drop ;
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,13 @@ M: basic-block hashcode* nip id>> ;
|
||||||
V{ } clone >>predecessors
|
V{ } clone >>predecessors
|
||||||
\ basic-block counter >>id ;
|
\ basic-block counter >>id ;
|
||||||
|
|
||||||
TUPLE: cfg { entry basic-block } word label spill-counts post-order ;
|
TUPLE: cfg { entry basic-block } word label spill-area-size post-order ;
|
||||||
|
|
||||||
: <cfg> ( entry word label -- cfg ) f f cfg boa ;
|
: <cfg> ( entry word label -- cfg )
|
||||||
|
cfg new
|
||||||
|
swap >>label
|
||||||
|
swap >>word
|
||||||
|
swap >>entry ;
|
||||||
|
|
||||||
: cfg-changed ( cfg -- cfg ) f >>post-order ; inline
|
: cfg-changed ( cfg -- cfg ) f >>post-order ; inline
|
||||||
|
|
||||||
|
|
|
@ -11,62 +11,62 @@ IN: compiler.cfg.dce.tests
|
||||||
entry>> instructions>> ;
|
entry>> instructions>> ;
|
||||||
|
|
||||||
[ V{
|
[ V{
|
||||||
T{ ##load-immediate { dst V int-regs 1 } { val 8 } }
|
T{ ##load-immediate { dst V int-rep 1 } { val 8 } }
|
||||||
T{ ##load-immediate { dst V int-regs 2 } { val 16 } }
|
T{ ##load-immediate { dst V int-rep 2 } { val 16 } }
|
||||||
T{ ##add { dst V int-regs 3 } { src1 V int-regs 1 } { src2 V int-regs 2 } }
|
T{ ##add { dst V int-rep 3 } { src1 V int-rep 1 } { src2 V int-rep 2 } }
|
||||||
T{ ##replace { src V int-regs 3 } { loc D 0 } }
|
T{ ##replace { src V int-rep 3 } { loc D 0 } }
|
||||||
} ] [ V{
|
} ] [ V{
|
||||||
T{ ##load-immediate { dst V int-regs 1 } { val 8 } }
|
T{ ##load-immediate { dst V int-rep 1 } { val 8 } }
|
||||||
T{ ##load-immediate { dst V int-regs 2 } { val 16 } }
|
T{ ##load-immediate { dst V int-rep 2 } { val 16 } }
|
||||||
T{ ##add { dst V int-regs 3 } { src1 V int-regs 1 } { src2 V int-regs 2 } }
|
T{ ##add { dst V int-rep 3 } { src1 V int-rep 1 } { src2 V int-rep 2 } }
|
||||||
T{ ##replace { src V int-regs 3 } { loc D 0 } }
|
T{ ##replace { src V int-rep 3 } { loc D 0 } }
|
||||||
} test-dce ] unit-test
|
} test-dce ] unit-test
|
||||||
|
|
||||||
[ V{ } ] [ V{
|
[ V{ } ] [ V{
|
||||||
T{ ##load-immediate { dst V int-regs 1 } { val 8 } }
|
T{ ##load-immediate { dst V int-rep 1 } { val 8 } }
|
||||||
T{ ##load-immediate { dst V int-regs 2 } { val 16 } }
|
T{ ##load-immediate { dst V int-rep 2 } { val 16 } }
|
||||||
T{ ##add { dst V int-regs 3 } { src1 V int-regs 1 } { src2 V int-regs 2 } }
|
T{ ##add { dst V int-rep 3 } { src1 V int-rep 1 } { src2 V int-rep 2 } }
|
||||||
} test-dce ] unit-test
|
} test-dce ] unit-test
|
||||||
|
|
||||||
[ V{ } ] [ V{
|
[ V{ } ] [ V{
|
||||||
T{ ##load-immediate { dst V int-regs 3 } { val 8 } }
|
T{ ##load-immediate { dst V int-rep 3 } { val 8 } }
|
||||||
T{ ##allot { dst V int-regs 1 } { temp V int-regs 2 } }
|
T{ ##allot { dst V int-rep 1 } { temp V int-rep 2 } }
|
||||||
} test-dce ] unit-test
|
} test-dce ] unit-test
|
||||||
|
|
||||||
[ V{ } ] [ V{
|
[ V{ } ] [ V{
|
||||||
T{ ##load-immediate { dst V int-regs 3 } { val 8 } }
|
T{ ##load-immediate { dst V int-rep 3 } { val 8 } }
|
||||||
T{ ##allot { dst V int-regs 1 } { temp V int-regs 2 } }
|
T{ ##allot { dst V int-rep 1 } { temp V int-rep 2 } }
|
||||||
T{ ##set-slot-imm { obj V int-regs 1 } { src V int-regs 3 } }
|
T{ ##set-slot-imm { obj V int-rep 1 } { src V int-rep 3 } }
|
||||||
} test-dce ] unit-test
|
} test-dce ] unit-test
|
||||||
|
|
||||||
[ V{
|
[ V{
|
||||||
T{ ##load-immediate { dst V int-regs 3 } { val 8 } }
|
T{ ##load-immediate { dst V int-rep 3 } { val 8 } }
|
||||||
T{ ##allot { dst V int-regs 1 } { temp V int-regs 2 } }
|
T{ ##allot { dst V int-rep 1 } { temp V int-rep 2 } }
|
||||||
T{ ##set-slot-imm { obj V int-regs 1 } { src V int-regs 3 } }
|
T{ ##set-slot-imm { obj V int-rep 1 } { src V int-rep 3 } }
|
||||||
T{ ##replace { src V int-regs 1 } { loc D 0 } }
|
T{ ##replace { src V int-rep 1 } { loc D 0 } }
|
||||||
} ] [ V{
|
} ] [ V{
|
||||||
T{ ##load-immediate { dst V int-regs 3 } { val 8 } }
|
T{ ##load-immediate { dst V int-rep 3 } { val 8 } }
|
||||||
T{ ##allot { dst V int-regs 1 } { temp V int-regs 2 } }
|
T{ ##allot { dst V int-rep 1 } { temp V int-rep 2 } }
|
||||||
T{ ##set-slot-imm { obj V int-regs 1 } { src V int-regs 3 } }
|
T{ ##set-slot-imm { obj V int-rep 1 } { src V int-rep 3 } }
|
||||||
T{ ##replace { src V int-regs 1 } { loc D 0 } }
|
T{ ##replace { src V int-rep 1 } { loc D 0 } }
|
||||||
} test-dce ] unit-test
|
} test-dce ] unit-test
|
||||||
|
|
||||||
[ V{
|
[ V{
|
||||||
T{ ##allot { dst V int-regs 1 } { temp V int-regs 2 } }
|
T{ ##allot { dst V int-rep 1 } { temp V int-rep 2 } }
|
||||||
T{ ##replace { src V int-regs 1 } { loc D 0 } }
|
T{ ##replace { src V int-rep 1 } { loc D 0 } }
|
||||||
} ] [ V{
|
} ] [ V{
|
||||||
T{ ##allot { dst V int-regs 1 } { temp V int-regs 2 } }
|
T{ ##allot { dst V int-rep 1 } { temp V int-rep 2 } }
|
||||||
T{ ##replace { src V int-regs 1 } { loc D 0 } }
|
T{ ##replace { src V int-rep 1 } { loc D 0 } }
|
||||||
} test-dce ] unit-test
|
} test-dce ] unit-test
|
||||||
|
|
||||||
[ V{
|
[ V{
|
||||||
T{ ##allot { dst V int-regs 1 } { temp V int-regs 2 } }
|
T{ ##allot { dst V int-rep 1 } { temp V int-rep 2 } }
|
||||||
T{ ##replace { src V int-regs 1 } { loc D 0 } }
|
T{ ##replace { src V int-rep 1 } { loc D 0 } }
|
||||||
T{ ##load-immediate { dst V int-regs 3 } { val 8 } }
|
T{ ##load-immediate { dst V int-rep 3 } { val 8 } }
|
||||||
T{ ##set-slot-imm { obj V int-regs 1 } { src V int-regs 3 } }
|
T{ ##set-slot-imm { obj V int-rep 1 } { src V int-rep 3 } }
|
||||||
} ] [ V{
|
} ] [ V{
|
||||||
T{ ##allot { dst V int-regs 1 } { temp V int-regs 2 } }
|
T{ ##allot { dst V int-rep 1 } { temp V int-rep 2 } }
|
||||||
T{ ##replace { src V int-regs 1 } { loc D 0 } }
|
T{ ##replace { src V int-rep 1 } { loc D 0 } }
|
||||||
T{ ##load-immediate { dst V int-regs 3 } { val 8 } }
|
T{ ##load-immediate { dst V int-rep 3 } { val 8 } }
|
||||||
T{ ##set-slot-imm { obj V int-regs 1 } { src V int-regs 3 } }
|
T{ ##set-slot-imm { obj V int-rep 1 } { src V int-rep 3 } }
|
||||||
} test-dce ] unit-test
|
} test-dce ] unit-test
|
||||||
|
|
|
@ -43,7 +43,7 @@ M: word test-cfg
|
||||||
! Prettyprinting
|
! Prettyprinting
|
||||||
M: vreg pprint*
|
M: vreg pprint*
|
||||||
<block
|
<block
|
||||||
\ V pprint-word [ reg-class>> pprint* ] [ n>> pprint* ] bi
|
\ V pprint-word [ rep>> pprint* ] [ n>> pprint* ] bi
|
||||||
block> ;
|
block> ;
|
||||||
|
|
||||||
: pprint-loc ( loc word -- ) <block pprint-word n>> pprint* block> ;
|
: pprint-loc ( loc word -- ) <block pprint-word n>> pprint* block> ;
|
||||||
|
|
|
@ -10,23 +10,23 @@ compiler.cfg.instructions
|
||||||
compiler.cfg.registers ;
|
compiler.cfg.registers ;
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##peek f V int-regs 0 D 0 }
|
T{ ##peek f V int-rep 0 D 0 }
|
||||||
T{ ##peek f V int-regs 1 D 0 }
|
T{ ##peek f V int-rep 1 D 0 }
|
||||||
T{ ##peek f V int-regs 2 D 0 }
|
T{ ##peek f V int-rep 2 D 0 }
|
||||||
} 1 test-bb
|
} 1 test-bb
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 2 D 0 }
|
T{ ##replace f V int-rep 2 D 0 }
|
||||||
} 2 test-bb
|
} 2 test-bb
|
||||||
1 2 edge
|
1 2 edge
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 0 D 0 }
|
T{ ##replace f V int-rep 0 D 0 }
|
||||||
} 3 test-bb
|
} 3 test-bb
|
||||||
2 3 edge
|
2 3 edge
|
||||||
V{ } 4 test-bb
|
V{ } 4 test-bb
|
||||||
V{ } 5 test-bb
|
V{ } 5 test-bb
|
||||||
3 { 4 5 } edges
|
3 { 4 5 } edges
|
||||||
V{
|
V{
|
||||||
T{ ##phi f V int-regs 2 H{ { 2 V int-regs 0 } { 3 V int-regs 1 } } }
|
T{ ##phi f V int-rep 2 H{ { 2 V int-rep 0 } { 3 V int-rep 1 } } }
|
||||||
} 6 test-bb
|
} 6 test-bb
|
||||||
4 6 edge
|
4 6 edge
|
||||||
5 6 edge
|
5 6 edge
|
||||||
|
|
|
@ -12,11 +12,11 @@ namespaces accessors sequences ;
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##inc-d f 3 }
|
T{ ##inc-d f 3 }
|
||||||
T{ ##replace f V int-regs 0 D 1 }
|
T{ ##replace f V int-rep 0 D 1 }
|
||||||
} 0 test-bb
|
} 0 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##box-float f V int-regs 0 V int-regs 1 }
|
T{ ##box-float f V int-rep 0 V int-rep 1 }
|
||||||
} 1 test-bb
|
} 1 test-bb
|
||||||
|
|
||||||
0 1 edge
|
0 1 edge
|
||||||
|
|
|
@ -16,7 +16,7 @@ IN: compiler.cfg.gc-checks
|
||||||
|
|
||||||
: insert-gc-check ( bb -- )
|
: insert-gc-check ( bb -- )
|
||||||
dup '[
|
dup '[
|
||||||
i i f _ uninitialized-locs \ ##gc new-insn
|
i i f f _ uninitialized-locs \ ##gc new-insn
|
||||||
prefix
|
prefix
|
||||||
] change-instructions drop ;
|
] change-instructions drop ;
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: arrays byte-arrays kernel layouts math namespaces
|
USING: accessors arrays byte-arrays kernel layouts math namespaces
|
||||||
sequences classes.tuple cpu.architecture compiler.cfg.registers
|
sequences classes.tuple cpu.architecture compiler.cfg.registers
|
||||||
compiler.cfg.instructions ;
|
compiler.cfg.instructions ;
|
||||||
IN: compiler.cfg.hats
|
IN: compiler.cfg.hats
|
||||||
|
|
||||||
: i ( -- vreg ) int-regs next-vreg ; inline
|
: i ( -- vreg ) int-rep next-vreg ; inline
|
||||||
: ^^i ( -- vreg vreg ) i dup ; inline
|
: ^^i ( -- vreg vreg ) i dup ; inline
|
||||||
: ^^i1 ( obj -- vreg vreg obj ) [ ^^i ] dip ; inline
|
: ^^i1 ( obj -- vreg vreg obj ) [ ^^i ] dip ; inline
|
||||||
: ^^i2 ( obj obj -- vreg vreg obj obj ) [ ^^i ] 2dip ; inline
|
: ^^i2 ( obj obj -- vreg vreg obj obj ) [ ^^i ] 2dip ; inline
|
||||||
: ^^i3 ( obj obj obj -- vreg vreg obj obj obj ) [ ^^i ] 3dip ; inline
|
: ^^i3 ( obj obj obj -- vreg vreg obj obj obj ) [ ^^i ] 3dip ; inline
|
||||||
|
|
||||||
: d ( -- vreg ) double-float-regs next-vreg ; inline
|
: d ( -- vreg ) double-float-rep next-vreg ; inline
|
||||||
: ^^d ( -- vreg vreg ) d dup ; inline
|
: ^^d ( -- vreg vreg ) d dup ; inline
|
||||||
: ^^d1 ( obj -- vreg vreg obj ) [ ^^d ] dip ; inline
|
: ^^d1 ( obj -- vreg vreg obj ) [ ^^d ] dip ; inline
|
||||||
: ^^d2 ( obj obj -- vreg vreg obj obj ) [ ^^d ] 2dip ; inline
|
: ^^d2 ( obj obj -- vreg vreg obj obj ) [ ^^d ] 2dip ; inline
|
||||||
: ^^d3 ( obj obj obj -- vreg vreg obj obj obj ) [ ^^d ] 3dip ; inline
|
: ^^d3 ( obj obj obj -- vreg vreg obj obj obj ) [ ^^d ] 3dip ; inline
|
||||||
|
|
||||||
: ^^load-literal ( obj -- dst ) ^^i1 ##load-literal ; inline
|
: ^^load-literal ( obj -- dst ) ^^i1 ##load-literal ; inline
|
||||||
: ^^copy ( src -- dst ) ^^i1 ##copy ; inline
|
: ^^copy ( src -- dst ) ^^i1 dup rep>> ##copy ; inline
|
||||||
: ^^slot ( obj slot tag -- dst ) ^^i3 i ##slot ; inline
|
: ^^slot ( obj slot tag -- dst ) ^^i3 i ##slot ; inline
|
||||||
: ^^slot-imm ( obj slot tag -- dst ) ^^i3 ##slot-imm ; inline
|
: ^^slot-imm ( obj slot tag -- dst ) ^^i3 ##slot-imm ; inline
|
||||||
: ^^set-slot ( src obj slot tag -- ) i ##set-slot ; inline
|
: ^^set-slot ( src obj slot tag -- ) i ##set-slot ; inline
|
||||||
|
|
|
@ -112,8 +112,7 @@ INSN: ##float>integer < ##unary ;
|
||||||
INSN: ##integer>float < ##unary ;
|
INSN: ##integer>float < ##unary ;
|
||||||
|
|
||||||
! Boxing and unboxing
|
! Boxing and unboxing
|
||||||
INSN: ##copy < ##unary ;
|
INSN: ##copy < ##unary rep ;
|
||||||
INSN: ##copy-float < ##unary ;
|
|
||||||
INSN: ##unbox-float < ##unary ;
|
INSN: ##unbox-float < ##unary ;
|
||||||
INSN: ##unbox-any-c-ptr < ##unary/temp ;
|
INSN: ##unbox-any-c-ptr < ##unary/temp ;
|
||||||
INSN: ##box-float < ##unary/temp ;
|
INSN: ##box-float < ##unary/temp ;
|
||||||
|
@ -190,7 +189,7 @@ INSN: ##fixnum-add < ##fixnum-overflow ;
|
||||||
INSN: ##fixnum-sub < ##fixnum-overflow ;
|
INSN: ##fixnum-sub < ##fixnum-overflow ;
|
||||||
INSN: ##fixnum-mul < ##fixnum-overflow ;
|
INSN: ##fixnum-mul < ##fixnum-overflow ;
|
||||||
|
|
||||||
INSN: ##gc temp1 temp2 live-values uninitialized-locs ;
|
INSN: ##gc temp1 temp2 data-values tagged-values uninitialized-locs ;
|
||||||
|
|
||||||
! Instructions used by machine IR only.
|
! Instructions used by machine IR only.
|
||||||
INSN: _prologue stack-frame ;
|
INSN: _prologue stack-frame ;
|
||||||
|
@ -219,14 +218,13 @@ INSN: _fixnum-mul < _fixnum-overflow ;
|
||||||
|
|
||||||
TUPLE: spill-slot n ; C: <spill-slot> spill-slot
|
TUPLE: spill-slot n ; C: <spill-slot> spill-slot
|
||||||
|
|
||||||
INSN: _gc temp1 temp2 gc-roots gc-root-count gc-root-size uninitialized-locs ;
|
INSN: _gc temp1 temp2 data-values tagged-values gc-root-size uninitialized-locs ;
|
||||||
|
|
||||||
! These instructions operate on machine registers and not
|
! These instructions operate on machine registers and not
|
||||||
! virtual registers
|
! virtual registers
|
||||||
INSN: _spill src class n ;
|
INSN: _spill src rep n ;
|
||||||
INSN: _reload dst class n ;
|
INSN: _reload dst rep n ;
|
||||||
INSN: _copy dst src class ;
|
INSN: _spill-area-size n ;
|
||||||
INSN: _spill-counts counts ;
|
|
||||||
|
|
||||||
! Instructions that use vregs
|
! Instructions that use vregs
|
||||||
UNION: vreg-insn
|
UNION: vreg-insn
|
||||||
|
|
|
@ -90,18 +90,18 @@ IN: compiler.cfg.intrinsics.alien
|
||||||
: emit-alien-cell-setter ( node -- )
|
: emit-alien-cell-setter ( node -- )
|
||||||
[ ##set-alien-cell ] inline-alien-cell-setter ;
|
[ ##set-alien-cell ] inline-alien-cell-setter ;
|
||||||
|
|
||||||
: emit-alien-float-getter ( node reg-class -- )
|
: emit-alien-float-getter ( node rep -- )
|
||||||
'[
|
'[
|
||||||
_ {
|
_ {
|
||||||
{ single-float-regs [ ^^alien-float ] }
|
{ single-float-rep [ ^^alien-float ] }
|
||||||
{ double-float-regs [ ^^alien-double ] }
|
{ double-float-rep [ ^^alien-double ] }
|
||||||
} case ^^box-float
|
} case ^^box-float
|
||||||
] inline-alien-getter ;
|
] inline-alien-getter ;
|
||||||
|
|
||||||
: emit-alien-float-setter ( node reg-class -- )
|
: emit-alien-float-setter ( node rep -- )
|
||||||
'[
|
'[
|
||||||
_ {
|
_ {
|
||||||
{ single-float-regs [ ##set-alien-float ] }
|
{ single-float-rep [ ##set-alien-float ] }
|
||||||
{ double-float-regs [ ##set-alien-double ] }
|
{ double-float-rep [ ##set-alien-double ] }
|
||||||
} case
|
} case
|
||||||
] inline-alien-float-setter ;
|
] inline-alien-float-setter ;
|
||||||
|
|
|
@ -153,8 +153,8 @@ IN: compiler.cfg.intrinsics
|
||||||
{ \ alien.accessors:set-alien-signed-4 [ 4 emit-alien-integer-setter ] }
|
{ \ alien.accessors:set-alien-signed-4 [ 4 emit-alien-integer-setter ] }
|
||||||
{ \ alien.accessors:alien-cell [ emit-alien-cell-getter ] }
|
{ \ alien.accessors:alien-cell [ emit-alien-cell-getter ] }
|
||||||
{ \ alien.accessors:set-alien-cell [ emit-alien-cell-setter ] }
|
{ \ alien.accessors:set-alien-cell [ emit-alien-cell-setter ] }
|
||||||
{ \ alien.accessors:alien-float [ single-float-regs emit-alien-float-getter ] }
|
{ \ alien.accessors:alien-float [ single-float-rep emit-alien-float-getter ] }
|
||||||
{ \ alien.accessors:set-alien-float [ single-float-regs emit-alien-float-setter ] }
|
{ \ alien.accessors:set-alien-float [ single-float-rep emit-alien-float-setter ] }
|
||||||
{ \ alien.accessors:alien-double [ double-float-regs emit-alien-float-getter ] }
|
{ \ alien.accessors:alien-double [ double-float-rep emit-alien-float-getter ] }
|
||||||
{ \ alien.accessors:set-alien-double [ double-float-regs emit-alien-float-setter ] }
|
{ \ alien.accessors:set-alien-double [ double-float-rep emit-alien-float-setter ] }
|
||||||
} case ;
|
} case ;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors assocs combinators cpu.architecture fry heaps
|
USING: accessors assocs combinators cpu.architecture fry heaps
|
||||||
kernel math math.order namespaces sequences vectors
|
kernel math math.order namespaces sequences vectors
|
||||||
compiler.cfg.linear-scan.live-intervals ;
|
compiler.cfg compiler.cfg.linear-scan.live-intervals ;
|
||||||
IN: compiler.cfg.linear-scan.allocation.state
|
IN: compiler.cfg.linear-scan.allocation.state
|
||||||
|
|
||||||
! Start index of current live interval. We ensure that all
|
! Start index of current live interval. We ensure that all
|
||||||
|
@ -26,7 +26,7 @@ SYMBOL: registers
|
||||||
SYMBOL: active-intervals
|
SYMBOL: active-intervals
|
||||||
|
|
||||||
: active-intervals-for ( vreg -- seq )
|
: active-intervals-for ( vreg -- seq )
|
||||||
reg-class>> active-intervals get at ;
|
rep>> reg-class-of active-intervals get at ;
|
||||||
|
|
||||||
: add-active ( live-interval -- )
|
: add-active ( live-interval -- )
|
||||||
dup vreg>> active-intervals-for push ;
|
dup vreg>> active-intervals-for push ;
|
||||||
|
@ -41,7 +41,7 @@ SYMBOL: active-intervals
|
||||||
SYMBOL: inactive-intervals
|
SYMBOL: inactive-intervals
|
||||||
|
|
||||||
: inactive-intervals-for ( vreg -- seq )
|
: inactive-intervals-for ( vreg -- seq )
|
||||||
reg-class>> inactive-intervals get at ;
|
rep>> reg-class-of inactive-intervals get at ;
|
||||||
|
|
||||||
: add-inactive ( live-interval -- )
|
: add-inactive ( live-interval -- )
|
||||||
dup vreg>> inactive-intervals-for push ;
|
dup vreg>> inactive-intervals-for push ;
|
||||||
|
@ -112,22 +112,18 @@ SYMBOL: unhandled-intervals
|
||||||
[ dup start>> unhandled-intervals get heap-push ]
|
[ dup start>> unhandled-intervals get heap-push ]
|
||||||
bi ;
|
bi ;
|
||||||
|
|
||||||
CONSTANT: reg-classes { int-regs double-float-regs }
|
|
||||||
|
|
||||||
: reg-class-assoc ( quot -- assoc )
|
: reg-class-assoc ( quot -- assoc )
|
||||||
[ reg-classes ] dip { } map>assoc ; inline
|
[ reg-classes ] dip { } map>assoc ; inline
|
||||||
|
|
||||||
! Mapping from register classes to spill counts
|
: next-spill-slot ( rep -- n )
|
||||||
SYMBOL: spill-counts
|
rep-size cfg get
|
||||||
|
[ swap [ align dup ] [ + ] bi ] change-spill-area-size drop ;
|
||||||
: next-spill-slot ( reg-class -- n )
|
|
||||||
spill-counts get [ dup 1 + ] change-at ;
|
|
||||||
|
|
||||||
! Mapping from vregs to spill slots
|
! Mapping from vregs to spill slots
|
||||||
SYMBOL: spill-slots
|
SYMBOL: spill-slots
|
||||||
|
|
||||||
: assign-spill-slot ( vreg -- n )
|
: assign-spill-slot ( vreg -- n )
|
||||||
spill-slots get [ reg-class>> next-spill-slot ] cache ;
|
spill-slots get [ rep>> next-spill-slot ] cache ;
|
||||||
|
|
||||||
: init-allocator ( registers -- )
|
: init-allocator ( registers -- )
|
||||||
registers set
|
registers set
|
||||||
|
@ -135,7 +131,7 @@ SYMBOL: spill-slots
|
||||||
[ V{ } clone ] reg-class-assoc active-intervals set
|
[ V{ } clone ] reg-class-assoc active-intervals set
|
||||||
[ V{ } clone ] reg-class-assoc inactive-intervals set
|
[ V{ } clone ] reg-class-assoc inactive-intervals set
|
||||||
V{ } clone handled-intervals set
|
V{ } clone handled-intervals set
|
||||||
[ 0 ] reg-class-assoc spill-counts set
|
cfg get 0 >>spill-area-size drop
|
||||||
H{ } clone spill-slots set
|
H{ } clone spill-slots set
|
||||||
-1 progress set ;
|
-1 progress set ;
|
||||||
|
|
||||||
|
@ -145,7 +141,7 @@ SYMBOL: spill-slots
|
||||||
|
|
||||||
! A utility used by register-status and spill-status words
|
! A utility used by register-status and spill-status words
|
||||||
: free-positions ( new -- assoc )
|
: free-positions ( new -- assoc )
|
||||||
vreg>> reg-class>> registers get at [ 1/0. ] H{ } map>assoc ;
|
vreg>> rep>> reg-class-of registers get at [ 1/0. ] H{ } map>assoc ;
|
||||||
|
|
||||||
: add-use-position ( n reg assoc -- ) [ [ min ] when* ] change-at ;
|
: add-use-position ( n reg assoc -- ) [ [ min ] when* ] change-at ;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2008, 2009 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors kernel math assocs namespaces sequences heaps
|
USING: accessors kernel math assocs namespaces sequences heaps
|
||||||
fry make combinators sets locals
|
fry make combinators sets locals arrays
|
||||||
cpu.architecture
|
cpu.architecture
|
||||||
compiler.cfg
|
compiler.cfg
|
||||||
compiler.cfg.rpo
|
compiler.cfg.rpo
|
||||||
|
@ -52,7 +52,7 @@ SYMBOL: register-live-outs
|
||||||
init-unhandled ;
|
init-unhandled ;
|
||||||
|
|
||||||
: insert-spill ( live-interval -- )
|
: insert-spill ( live-interval -- )
|
||||||
[ reg>> ] [ vreg>> reg-class>> ] [ spill-to>> ] tri _spill ;
|
[ reg>> ] [ vreg>> rep>> ] [ spill-to>> ] tri _spill ;
|
||||||
|
|
||||||
: handle-spill ( live-interval -- )
|
: handle-spill ( live-interval -- )
|
||||||
dup spill-to>> [ insert-spill ] [ drop ] if ;
|
dup spill-to>> [ insert-spill ] [ drop ] if ;
|
||||||
|
@ -72,7 +72,7 @@ SYMBOL: register-live-outs
|
||||||
pending-interval-heap get (expire-old-intervals) ;
|
pending-interval-heap get (expire-old-intervals) ;
|
||||||
|
|
||||||
: insert-reload ( live-interval -- )
|
: insert-reload ( live-interval -- )
|
||||||
[ reg>> ] [ vreg>> reg-class>> ] [ reload-from>> ] tri _reload ;
|
[ reg>> ] [ vreg>> rep>> ] [ reload-from>> ] tri _reload ;
|
||||||
|
|
||||||
: handle-reload ( live-interval -- )
|
: handle-reload ( live-interval -- )
|
||||||
dup reload-from>> [ insert-reload ] [ drop ] if ;
|
dup reload-from>> [ insert-reload ] [ drop ] if ;
|
||||||
|
@ -103,11 +103,36 @@ RENAMING: assign [ vreg>reg ] [ vreg>reg ] [ vreg>reg ]
|
||||||
M: vreg-insn assign-registers-in-insn
|
M: vreg-insn assign-registers-in-insn
|
||||||
[ assign-insn-defs ] [ assign-insn-uses ] [ assign-insn-temps ] tri ;
|
[ assign-insn-defs ] [ assign-insn-uses ] [ assign-insn-temps ] tri ;
|
||||||
|
|
||||||
|
! TODO: needs tagged-rep
|
||||||
|
|
||||||
|
: trace-on-gc ( assoc -- assoc' )
|
||||||
|
! When a GC occurs, virtual registers which contain tagged data
|
||||||
|
! are traced by the GC. Outputs a sequence physical registers.
|
||||||
|
[ drop rep>> int-rep eq? ] { } assoc-filter-as values ;
|
||||||
|
|
||||||
|
: spill-on-gc? ( vreg reg -- ? )
|
||||||
|
[ rep>> int-rep? not ] [ spill-slot? not ] bi* and ;
|
||||||
|
|
||||||
|
: spill-on-gc ( assoc -- assoc' )
|
||||||
|
! When a GC occurs, virtual registers which contain untagged data,
|
||||||
|
! and are stored in physical registers, are saved to their spill
|
||||||
|
! slots. Outputs sequence of triples:
|
||||||
|
! - physical register
|
||||||
|
! - spill slot
|
||||||
|
! - representation
|
||||||
|
[
|
||||||
|
[
|
||||||
|
2dup spill-on-gc?
|
||||||
|
[ swap [ assign-spill-slot ] [ rep>> ] bi 3array , ] [ 2drop ] if
|
||||||
|
] assoc-each
|
||||||
|
] { } make ;
|
||||||
|
|
||||||
M: ##gc assign-registers-in-insn
|
M: ##gc assign-registers-in-insn
|
||||||
! This works because ##gc is always the first instruction
|
! Since ##gc is always the first instruction in a block, the set of
|
||||||
! in a block.
|
! values live at the ##gc is just live-in.
|
||||||
dup call-next-method
|
dup call-next-method
|
||||||
basic-block get register-live-ins get at >>live-values
|
basic-block get register-live-ins get at
|
||||||
|
[ trace-on-gc >>tagged-values ] [ spill-on-gc >>data-values ] bi
|
||||||
drop ;
|
drop ;
|
||||||
|
|
||||||
M: insn assign-registers-in-insn drop ;
|
M: insn assign-registers-in-insn drop ;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,6 +39,5 @@ IN: compiler.cfg.linear-scan
|
||||||
: linear-scan ( cfg -- cfg' )
|
: linear-scan ( cfg -- cfg' )
|
||||||
[
|
[
|
||||||
dup machine-registers (linear-scan)
|
dup machine-registers (linear-scan)
|
||||||
spill-counts get >>spill-counts
|
|
||||||
cfg-changed
|
cfg-changed
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
|
@ -1,65 +1,67 @@
|
||||||
IN: compiler.cfg.linear-scan.resolve.tests
|
IN: compiler.cfg.linear-scan.resolve.tests
|
||||||
USING: compiler.cfg.linear-scan.resolve tools.test kernel namespaces
|
USING: compiler.cfg.linear-scan.resolve tools.test kernel namespaces
|
||||||
|
accessors
|
||||||
|
compiler.cfg
|
||||||
compiler.cfg.instructions cpu.architecture make sequences
|
compiler.cfg.instructions cpu.architecture make sequences
|
||||||
compiler.cfg.linear-scan.allocation.state ;
|
compiler.cfg.linear-scan.allocation.state ;
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
{ { T{ spill-slot f 0 } int-regs } { 1 int-regs } }
|
{ { T{ spill-slot f 0 } int-rep } { 1 int-rep } }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
[
|
[
|
||||||
0 <spill-slot> 1 int-regs add-mapping
|
0 <spill-slot> 1 int-rep add-mapping
|
||||||
] { } make
|
] { } make
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
T{ _reload { dst 1 } { class int-regs } { n 0 } }
|
T{ _reload { dst 1 } { rep int-rep } { n 0 } }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
[
|
[
|
||||||
{ T{ spill-slot f 0 } int-regs } { 1 int-regs } >insn
|
{ T{ spill-slot f 0 } int-rep } { 1 int-rep } >insn
|
||||||
] { } make
|
] { } make
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
T{ _spill { src 1 } { class int-regs } { n 0 } }
|
T{ _spill { src 1 } { rep int-rep } { n 0 } }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
[
|
[
|
||||||
{ 1 int-regs } { T{ spill-slot f 0 } int-regs } >insn
|
{ 1 int-rep } { T{ spill-slot f 0 } int-rep } >insn
|
||||||
] { } make
|
] { } make
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
T{ _copy { src 1 } { dst 2 } { class int-regs } }
|
T{ ##copy { src 1 } { dst 2 } { rep int-rep } }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
[
|
[
|
||||||
{ 1 int-regs } { 2 int-regs } >insn
|
{ 1 int-rep } { 2 int-rep } >insn
|
||||||
] { } make
|
] { } make
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
H{ { int-regs 10 } { float-regs 20 } } clone spill-counts set
|
cfg new 8 >>spill-area-size cfg set
|
||||||
H{ } clone spill-temps set
|
H{ } clone spill-temps set
|
||||||
|
|
||||||
[
|
[
|
||||||
t
|
t
|
||||||
] [
|
] [
|
||||||
{ { { 0 int-regs } { 1 int-regs } } { { 1 int-regs } { 0 int-regs } } }
|
{ { { 0 int-rep } { 1 int-rep } } { { 1 int-rep } { 0 int-rep } } }
|
||||||
mapping-instructions {
|
mapping-instructions {
|
||||||
{
|
{
|
||||||
T{ _spill { src 0 } { class int-regs } { n 10 } }
|
T{ _spill { src 0 } { rep int-rep } { n 8 } }
|
||||||
T{ _copy { dst 0 } { src 1 } { class int-regs } }
|
T{ ##copy { dst 0 } { src 1 } { rep int-rep } }
|
||||||
T{ _reload { dst 1 } { class int-regs } { n 10 } }
|
T{ _reload { dst 1 } { rep int-rep } { n 8 } }
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
T{ _spill { src 1 } { class int-regs } { n 10 } }
|
T{ _spill { src 1 } { rep int-rep } { n 8 } }
|
||||||
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
T{ ##copy { dst 1 } { src 0 } { rep int-rep } }
|
||||||
T{ _reload { dst 0 } { class int-regs } { n 10 } }
|
T{ _reload { dst 0 } { rep int-rep } { n 8 } }
|
||||||
}
|
}
|
||||||
} member?
|
} member?
|
||||||
] unit-test
|
] unit-test
|
|
@ -14,16 +14,16 @@ IN: compiler.cfg.linear-scan.resolve
|
||||||
|
|
||||||
SYMBOL: spill-temps
|
SYMBOL: spill-temps
|
||||||
|
|
||||||
: spill-temp ( reg-class -- n )
|
: spill-temp ( rep -- n )
|
||||||
spill-temps get [ next-spill-slot ] cache ;
|
spill-temps get [ next-spill-slot ] cache ;
|
||||||
|
|
||||||
: add-mapping ( from to reg-class -- )
|
: add-mapping ( from to rep -- )
|
||||||
'[ _ 2array ] bi@ 2array , ;
|
'[ _ 2array ] bi@ 2array , ;
|
||||||
|
|
||||||
:: resolve-value-data-flow ( bb to vreg -- )
|
:: resolve-value-data-flow ( bb to vreg -- )
|
||||||
vreg bb vreg-at-end
|
vreg bb vreg-at-end
|
||||||
vreg to vreg-at-start
|
vreg to vreg-at-start
|
||||||
2dup = [ 2drop ] [ vreg reg-class>> add-mapping ] if ;
|
2dup = [ 2drop ] [ vreg rep>> add-mapping ] if ;
|
||||||
|
|
||||||
: compute-mappings ( bb to -- mappings )
|
: compute-mappings ( bb to -- mappings )
|
||||||
dup live-in dup assoc-empty? [ 3drop f ] [
|
dup live-in dup assoc-empty? [ 3drop f ] [
|
||||||
|
@ -43,7 +43,7 @@ SYMBOL: spill-temps
|
||||||
drop [ first2 ] [ second spill-temp ] bi _spill ;
|
drop [ first2 ] [ second spill-temp ] bi _spill ;
|
||||||
|
|
||||||
: register->register ( from to -- )
|
: register->register ( from to -- )
|
||||||
swap [ first ] [ first2 ] bi* _copy ;
|
swap [ first ] [ first2 ] bi* ##copy ;
|
||||||
|
|
||||||
SYMBOL: temp
|
SYMBOL: temp
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2008, 2009 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel math accessors sequences namespaces make
|
USING: kernel math accessors sequences namespaces make
|
||||||
combinators assocs arrays locals cpu.architecture
|
combinators assocs arrays locals layouts cpu.architecture
|
||||||
compiler.cfg
|
compiler.cfg
|
||||||
compiler.cfg.comparisons
|
compiler.cfg.comparisons
|
||||||
compiler.cfg.stack-frame
|
compiler.cfg.stack-frame
|
||||||
|
@ -70,44 +70,17 @@ M: ##dispatch linearize-insn
|
||||||
[ successors>> [ block-number _dispatch-label ] each ]
|
[ successors>> [ block-number _dispatch-label ] each ]
|
||||||
bi* ;
|
bi* ;
|
||||||
|
|
||||||
: (compute-gc-roots) ( n live-values -- n )
|
: gc-root-offsets ( registers -- alist )
|
||||||
[
|
! Outputs a sequence of { offset register/spill-slot } pairs
|
||||||
[ nip 2array , ]
|
[ length iota [ cell * ] map ] keep zip ;
|
||||||
[ drop reg-class>> reg-size + ]
|
|
||||||
3bi
|
|
||||||
] assoc-each ;
|
|
||||||
|
|
||||||
: oop-values ( regs -- regs' )
|
|
||||||
[ drop reg-class>> int-regs eq? ] assoc-filter ;
|
|
||||||
|
|
||||||
: data-values ( regs -- regs' )
|
|
||||||
[ drop reg-class>> double-float-regs eq? ] assoc-filter ;
|
|
||||||
|
|
||||||
: compute-gc-roots ( live-values -- alist )
|
|
||||||
[
|
|
||||||
[ 0 ] dip
|
|
||||||
! we put float registers last; the GC doesn't actually scan them
|
|
||||||
[ oop-values (compute-gc-roots) ]
|
|
||||||
[ data-values (compute-gc-roots) ] bi
|
|
||||||
drop
|
|
||||||
] { } make ;
|
|
||||||
|
|
||||||
: count-gc-roots ( live-values -- n )
|
|
||||||
! Size of GC root area, minus the float registers
|
|
||||||
oop-values assoc-size ;
|
|
||||||
|
|
||||||
M: ##gc linearize-insn
|
M: ##gc linearize-insn
|
||||||
nip
|
nip
|
||||||
{
|
{
|
||||||
[ temp1>> ]
|
[ temp1>> ]
|
||||||
[ temp2>> ]
|
[ temp2>> ]
|
||||||
[
|
[ data-values>> ]
|
||||||
live-values>>
|
[ tagged-values>> gc-root-offsets dup length ]
|
||||||
[ compute-gc-roots ]
|
|
||||||
[ count-gc-roots ]
|
|
||||||
[ gc-roots-size ]
|
|
||||||
tri
|
|
||||||
]
|
|
||||||
[ uninitialized-locs>> ]
|
[ uninitialized-locs>> ]
|
||||||
} cleave
|
} cleave
|
||||||
_gc ;
|
_gc ;
|
||||||
|
@ -115,7 +88,7 @@ M: ##gc linearize-insn
|
||||||
: linearize-basic-blocks ( cfg -- insns )
|
: linearize-basic-blocks ( cfg -- insns )
|
||||||
[
|
[
|
||||||
[ linearization-order [ linearize-basic-block ] each ]
|
[ linearization-order [ linearize-basic-block ] each ]
|
||||||
[ spill-counts>> _spill-counts ]
|
[ spill-area-size>> _spill-area-size ]
|
||||||
bi
|
bi
|
||||||
] { } make ;
|
] { } make ;
|
||||||
|
|
||||||
|
|
|
@ -12,20 +12,20 @@ IN: compiler.cfg.liveness.tests
|
||||||
! Sanity check...
|
! Sanity check...
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##peek f V int-regs 0 D 0 }
|
T{ ##peek f V int-rep 0 D 0 }
|
||||||
T{ ##replace f V int-regs 0 D 0 }
|
T{ ##replace f V int-rep 0 D 0 }
|
||||||
T{ ##replace f V int-regs 1 D 1 }
|
T{ ##replace f V int-rep 1 D 1 }
|
||||||
T{ ##peek f V int-regs 1 D 1 }
|
T{ ##peek f V int-rep 1 D 1 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
} 1 test-bb
|
} 1 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 2 D 0 }
|
T{ ##replace f V int-rep 2 D 0 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
} 2 test-bb
|
} 2 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 3 D 0 }
|
T{ ##replace f V int-rep 3 D 0 }
|
||||||
T{ ##return }
|
T{ ##return }
|
||||||
} 3 test-bb
|
} 3 test-bb
|
||||||
|
|
||||||
|
@ -35,9 +35,9 @@ test-liveness
|
||||||
|
|
||||||
[
|
[
|
||||||
H{
|
H{
|
||||||
{ V int-regs 1 V int-regs 1 }
|
{ V int-rep 1 V int-rep 1 }
|
||||||
{ V int-regs 2 V int-regs 2 }
|
{ V int-rep 2 V int-rep 2 }
|
||||||
{ V int-regs 3 V int-regs 3 }
|
{ V int-rep 3 V int-rep 3 }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
[ 1 get live-in ]
|
[ 1 get live-in ]
|
||||||
|
@ -46,12 +46,12 @@ unit-test
|
||||||
! Tricky case; defs must be killed before uses
|
! Tricky case; defs must be killed before uses
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##peek f V int-regs 0 D 0 }
|
T{ ##peek f V int-rep 0 D 0 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
} 1 test-bb
|
} 1 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##add-imm f V int-regs 0 V int-regs 0 10 }
|
T{ ##add-imm f V int-rep 0 V int-rep 0 10 }
|
||||||
T{ ##return }
|
T{ ##return }
|
||||||
} 2 test-bb
|
} 2 test-bb
|
||||||
|
|
||||||
|
@ -59,4 +59,4 @@ V{
|
||||||
|
|
||||||
test-liveness
|
test-liveness
|
||||||
|
|
||||||
[ H{ { V int-regs 0 V int-regs 0 } } ] [ 2 get live-in ] unit-test
|
[ H{ { V int-rep 0 V int-rep 0 } } ] [ 2 get live-in ] unit-test
|
|
@ -1,12 +1,14 @@
|
||||||
! Copyright (C) 2009 Slava Pestov.
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: compiler.cfg.linearization compiler.cfg.gc-checks
|
USING: kernel namespaces compiler.cfg compiler.cfg.linearization
|
||||||
compiler.cfg.linear-scan compiler.cfg.build-stack-frame
|
compiler.cfg.gc-checks compiler.cfg.linear-scan
|
||||||
compiler.cfg.rpo ;
|
compiler.cfg.build-stack-frame ;
|
||||||
IN: compiler.cfg.mr
|
IN: compiler.cfg.mr
|
||||||
|
|
||||||
: build-mr ( cfg -- mr )
|
: build-mr ( cfg -- mr )
|
||||||
insert-gc-checks
|
dup cfg [
|
||||||
linear-scan
|
insert-gc-checks
|
||||||
flatten-cfg
|
linear-scan
|
||||||
build-stack-frame ;
|
flatten-cfg
|
||||||
|
build-stack-frame
|
||||||
|
] with-variable ;
|
|
@ -1,6 +1,7 @@
|
||||||
! Copyright (C) 2008, 2009 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel sequences accessors combinators namespaces
|
USING: kernel sequences accessors combinators namespaces
|
||||||
|
compiler.cfg
|
||||||
compiler.cfg.tco
|
compiler.cfg.tco
|
||||||
compiler.cfg.useless-conditionals
|
compiler.cfg.useless-conditionals
|
||||||
compiler.cfg.branch-splitting
|
compiler.cfg.branch-splitting
|
||||||
|
@ -29,7 +30,7 @@ SYMBOL: check-optimizer?
|
||||||
: optimize-cfg ( cfg -- cfg' )
|
: optimize-cfg ( cfg -- cfg' )
|
||||||
! Note that compute-predecessors has to be called several times.
|
! Note that compute-predecessors has to be called several times.
|
||||||
! The passes that need this document it.
|
! The passes that need this document it.
|
||||||
[
|
dup cfg [
|
||||||
optimize-tail-calls
|
optimize-tail-calls
|
||||||
delete-useless-conditionals
|
delete-useless-conditionals
|
||||||
compute-predecessors
|
compute-predecessors
|
||||||
|
@ -47,4 +48,4 @@ SYMBOL: check-optimizer?
|
||||||
destruct-ssa
|
destruct-ssa
|
||||||
delete-empty-blocks
|
delete-empty-blocks
|
||||||
?check
|
?check
|
||||||
] with-scope ;
|
] with-variable ;
|
||||||
|
|
|
@ -11,53 +11,53 @@ SYMBOL: temp
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
T{ ##copy f V int-regs 4 V int-regs 2 }
|
T{ ##copy f V int-rep 4 V int-rep 2 int-rep }
|
||||||
T{ ##copy f V int-regs 2 V int-regs 1 }
|
T{ ##copy f V int-rep 2 V int-rep 1 int-rep }
|
||||||
T{ ##copy f V int-regs 1 V int-regs 4 }
|
T{ ##copy f V int-rep 1 V int-rep 4 int-rep }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
H{
|
H{
|
||||||
{ V int-regs 1 V int-regs 2 }
|
{ V int-rep 1 V int-rep 2 }
|
||||||
{ V int-regs 2 V int-regs 1 }
|
{ V int-rep 2 V int-rep 1 }
|
||||||
} test-parallel-copy
|
} test-parallel-copy
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
T{ ##copy f V int-regs 1 V int-regs 2 }
|
T{ ##copy f V int-rep 1 V int-rep 2 int-rep }
|
||||||
T{ ##copy f V int-regs 3 V int-regs 4 }
|
T{ ##copy f V int-rep 3 V int-rep 4 int-rep }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
H{
|
H{
|
||||||
{ V int-regs 1 V int-regs 2 }
|
{ V int-rep 1 V int-rep 2 }
|
||||||
{ V int-regs 3 V int-regs 4 }
|
{ V int-rep 3 V int-rep 4 }
|
||||||
} test-parallel-copy
|
} test-parallel-copy
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
T{ ##copy f V int-regs 1 V int-regs 3 }
|
T{ ##copy f V int-rep 1 V int-rep 3 int-rep }
|
||||||
T{ ##copy f V int-regs 2 V int-regs 1 }
|
T{ ##copy f V int-rep 2 V int-rep 1 int-rep }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
H{
|
H{
|
||||||
{ V int-regs 1 V int-regs 3 }
|
{ V int-rep 1 V int-rep 3 }
|
||||||
{ V int-regs 2 V int-regs 3 }
|
{ V int-rep 2 V int-rep 3 }
|
||||||
} test-parallel-copy
|
} test-parallel-copy
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
T{ ##copy f V int-regs 4 V int-regs 3 }
|
T{ ##copy f V int-rep 4 V int-rep 3 int-rep }
|
||||||
T{ ##copy f V int-regs 3 V int-regs 2 }
|
T{ ##copy f V int-rep 3 V int-rep 2 int-rep }
|
||||||
T{ ##copy f V int-regs 2 V int-regs 1 }
|
T{ ##copy f V int-rep 2 V int-rep 1 int-rep }
|
||||||
T{ ##copy f V int-regs 1 V int-regs 4 }
|
T{ ##copy f V int-rep 1 V int-rep 4 int-rep }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
{
|
{
|
||||||
{ V int-regs 2 V int-regs 1 }
|
{ V int-rep 2 V int-rep 1 }
|
||||||
{ V int-regs 3 V int-regs 2 }
|
{ V int-rep 3 V int-rep 2 }
|
||||||
{ V int-regs 1 V int-regs 3 }
|
{ V int-rep 1 V int-rep 3 }
|
||||||
{ V int-regs 4 V int-regs 3 }
|
{ V int-rep 4 V int-rep 3 }
|
||||||
} test-parallel-copy
|
} test-parallel-copy
|
||||||
] unit-test
|
] unit-test
|
|
@ -1,8 +1,8 @@
|
||||||
! Copyright (C) 2009 Slava Pestov.
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: assocs compiler.cfg.hats compiler.cfg.instructions
|
USING: assocs cpu.architecture compiler.cfg.hats
|
||||||
deques dlists fry kernel locals namespaces sequences
|
compiler.cfg.instructions deques dlists fry kernel locals namespaces
|
||||||
hashtables ;
|
sequences hashtables ;
|
||||||
IN: compiler.cfg.parallel-copy
|
IN: compiler.cfg.parallel-copy
|
||||||
|
|
||||||
! Revisiting Out-of-SSA Translation for Correctness, Code Quality, and Efficiency
|
! Revisiting Out-of-SSA Translation for Correctness, Code Quality, and Efficiency
|
||||||
|
@ -57,4 +57,4 @@ PRIVATE>
|
||||||
] slurp-deque
|
] slurp-deque
|
||||||
] with-scope ; inline
|
] with-scope ; inline
|
||||||
|
|
||||||
: parallel-copy ( mapping -- ) i [ ##copy ] parallel-mapping ;
|
: parallel-copy ( mapping -- ) i [ int-rep ##copy ] parallel-mapping ;
|
|
@ -4,7 +4,7 @@ USING: accessors namespaces kernel arrays parser math math.order ;
|
||||||
IN: compiler.cfg.registers
|
IN: compiler.cfg.registers
|
||||||
|
|
||||||
! Virtual registers, used by CFG and machine IRs
|
! Virtual registers, used by CFG and machine IRs
|
||||||
TUPLE: vreg { reg-class read-only } { n fixnum read-only } ;
|
TUPLE: vreg { rep read-only } { n fixnum read-only } ;
|
||||||
|
|
||||||
M: vreg equal? over vreg? [ [ n>> ] bi@ eq? ] [ 2drop f ] if ;
|
M: vreg equal? over vreg? [ [ n>> ] bi@ eq? ] [ 2drop f ] if ;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ M: vreg hashcode* nip n>> ;
|
||||||
|
|
||||||
SYMBOL: vreg-counter
|
SYMBOL: vreg-counter
|
||||||
|
|
||||||
: next-vreg ( reg-class -- vreg ) \ vreg-counter counter vreg boa ;
|
: next-vreg ( rep -- vreg ) \ vreg-counter counter vreg boa ;
|
||||||
|
|
||||||
! Stack locations -- 'n' is an index starting from the top of the stack
|
! Stack locations -- 'n' is an index starting from the top of the stack
|
||||||
! going down. So 0 is the top of the stack, 1 is what would be the top
|
! going down. So 0 is the top of the stack, 1 is what would be the top
|
||||||
|
|
|
@ -11,6 +11,6 @@ SYMBOL: renamings
|
||||||
renamings get ?at drop ;
|
renamings get ?at drop ;
|
||||||
|
|
||||||
: fresh-value ( vreg -- vreg' )
|
: fresh-value ( vreg -- vreg' )
|
||||||
reg-class>> next-vreg ;
|
rep>> next-vreg ;
|
||||||
|
|
||||||
RENAMING: rename [ rename-value ] [ rename-value ] [ fresh-value ]
|
RENAMING: rename [ rename-value ] [ rename-value ] [ fresh-value ]
|
||||||
|
|
|
@ -13,24 +13,24 @@ IN: compiler.cfg.ssa.construction.tests
|
||||||
reset-counters
|
reset-counters
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 1 100 }
|
T{ ##load-immediate f V int-rep 1 100 }
|
||||||
T{ ##add-imm f V int-regs 2 V int-regs 1 50 }
|
T{ ##add-imm f V int-rep 2 V int-rep 1 50 }
|
||||||
T{ ##add-imm f V int-regs 2 V int-regs 2 10 }
|
T{ ##add-imm f V int-rep 2 V int-rep 2 10 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
} 0 test-bb
|
} 0 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 3 3 }
|
T{ ##load-immediate f V int-rep 3 3 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
} 1 test-bb
|
} 1 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 3 4 }
|
T{ ##load-immediate f V int-rep 3 4 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
} 2 test-bb
|
} 2 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 3 D 0 }
|
T{ ##replace f V int-rep 3 D 0 }
|
||||||
T{ ##return }
|
T{ ##return }
|
||||||
} 3 test-bb
|
} 3 test-bb
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ V{
|
||||||
|
|
||||||
: test-ssa ( -- )
|
: test-ssa ( -- )
|
||||||
cfg new 0 get >>entry
|
cfg new 0 get >>entry
|
||||||
|
dup cfg set
|
||||||
compute-predecessors
|
compute-predecessors
|
||||||
construct-ssa
|
construct-ssa
|
||||||
drop ;
|
drop ;
|
||||||
|
@ -48,23 +49,23 @@ V{
|
||||||
|
|
||||||
[
|
[
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 1 100 }
|
T{ ##load-immediate f V int-rep 1 100 }
|
||||||
T{ ##add-imm f V int-regs 2 V int-regs 1 50 }
|
T{ ##add-imm f V int-rep 2 V int-rep 1 50 }
|
||||||
T{ ##add-imm f V int-regs 3 V int-regs 2 10 }
|
T{ ##add-imm f V int-rep 3 V int-rep 2 10 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
}
|
}
|
||||||
] [ 0 get instructions>> ] unit-test
|
] [ 0 get instructions>> ] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 4 3 }
|
T{ ##load-immediate f V int-rep 4 3 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
}
|
}
|
||||||
] [ 1 get instructions>> ] unit-test
|
] [ 1 get instructions>> ] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 5 4 }
|
T{ ##load-immediate f V int-rep 5 4 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
}
|
}
|
||||||
] [ 2 get instructions>> ] unit-test
|
] [ 2 get instructions>> ] unit-test
|
||||||
|
@ -74,8 +75,8 @@ V{
|
||||||
|
|
||||||
[
|
[
|
||||||
V{
|
V{
|
||||||
T{ ##phi f V int-regs 6 H{ { 1 V int-regs 4 } { 2 V int-regs 5 } } }
|
T{ ##phi f V int-rep 6 H{ { 1 V int-rep 4 } { 2 V int-rep 5 } } }
|
||||||
T{ ##replace f V int-regs 6 D 0 }
|
T{ ##replace f V int-rep 6 D 0 }
|
||||||
T{ ##return }
|
T{ ##return }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
|
@ -87,9 +88,9 @@ reset-counters
|
||||||
|
|
||||||
V{ } 0 test-bb
|
V{ } 0 test-bb
|
||||||
V{ } 1 test-bb
|
V{ } 1 test-bb
|
||||||
V{ T{ ##peek f V int-regs 0 D 0 } } 2 test-bb
|
V{ T{ ##peek f V int-rep 0 D 0 } } 2 test-bb
|
||||||
V{ T{ ##peek f V int-regs 0 D 0 } } 3 test-bb
|
V{ T{ ##peek f V int-rep 0 D 0 } } 3 test-bb
|
||||||
V{ T{ ##replace f V int-regs 0 D 0 } } 4 test-bb
|
V{ T{ ##replace f V int-rep 0 D 0 } } 4 test-bb
|
||||||
V{ } 5 test-bb
|
V{ } 5 test-bb
|
||||||
V{ } 6 test-bb
|
V{ } 6 test-bb
|
||||||
|
|
||||||
|
@ -104,8 +105,8 @@ V{ } 6 test-bb
|
||||||
|
|
||||||
[
|
[
|
||||||
V{
|
V{
|
||||||
T{ ##phi f V int-regs 3 H{ { 2 V int-regs 1 } { 3 V int-regs 2 } } }
|
T{ ##phi f V int-rep 3 H{ { 2 V int-rep 1 } { 3 V int-rep 2 } } }
|
||||||
T{ ##replace f V int-regs 3 D 0 }
|
T{ ##replace f V int-rep 3 D 0 }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
4 get instructions>>
|
4 get instructions>>
|
||||||
|
|
|
@ -9,6 +9,7 @@ compiler.cfg.liveness
|
||||||
compiler.cfg.registers
|
compiler.cfg.registers
|
||||||
compiler.cfg.dominance
|
compiler.cfg.dominance
|
||||||
compiler.cfg.instructions
|
compiler.cfg.instructions
|
||||||
|
compiler.cfg.renaming
|
||||||
compiler.cfg.renaming.functor
|
compiler.cfg.renaming.functor
|
||||||
compiler.cfg.ssa.construction.tdmsc ;
|
compiler.cfg.ssa.construction.tdmsc ;
|
||||||
IN: compiler.cfg.ssa.construction
|
IN: compiler.cfg.ssa.construction
|
||||||
|
@ -75,7 +76,7 @@ SYMBOLS: stacks pushed ;
|
||||||
H{ } clone stacks set ;
|
H{ } clone stacks set ;
|
||||||
|
|
||||||
: gen-name ( vreg -- vreg' )
|
: gen-name ( vreg -- vreg' )
|
||||||
[ reg-class>> next-vreg dup ] keep
|
[ fresh-value dup ] keep
|
||||||
dup pushed get 2dup key?
|
dup pushed get 2dup key?
|
||||||
[ 2drop stacks get at set-last ]
|
[ 2drop stacks get at set-last ]
|
||||||
[ conjoin stacks get push-at ]
|
[ conjoin stacks get push-at ]
|
||||||
|
|
|
@ -5,7 +5,7 @@ tools.test vectors sets ;
|
||||||
IN: compiler.cfg.ssa.construction.tdmsc.tests
|
IN: compiler.cfg.ssa.construction.tdmsc.tests
|
||||||
|
|
||||||
: test-tdmsc ( -- )
|
: test-tdmsc ( -- )
|
||||||
cfg new 0 get >>entry
|
cfg new 0 get >>entry dup cfg set
|
||||||
compute-predecessors
|
compute-predecessors
|
||||||
dup compute-dominance
|
dup compute-dominance
|
||||||
compute-merge-sets ;
|
compute-merge-sets ;
|
||||||
|
|
|
@ -93,7 +93,6 @@ HINTS: filter-by { bit-array object } ;
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
: compute-merge-sets ( cfg -- )
|
: compute-merge-sets ( cfg -- )
|
||||||
dup cfg set
|
|
||||||
H{ } clone visited set
|
H{ } clone visited set
|
||||||
[ compute-levels ]
|
[ compute-levels ]
|
||||||
[ init-merge-sets ]
|
[ init-merge-sets ]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
! Copyright (C) 2009 Slava Pestov.
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors assocs kernel locals
|
USING: accessors assocs kernel locals
|
||||||
|
cpu.architecture
|
||||||
compiler.cfg.rpo
|
compiler.cfg.rpo
|
||||||
compiler.cfg.hats
|
compiler.cfg.hats
|
||||||
compiler.cfg.utilities
|
compiler.cfg.utilities
|
||||||
|
@ -11,7 +12,7 @@ IN: compiler.cfg.ssa.cssa
|
||||||
|
|
||||||
:: insert-copy ( bb src -- bb dst )
|
:: insert-copy ( bb src -- bb dst )
|
||||||
i :> dst
|
i :> dst
|
||||||
bb [ dst src ##copy ] add-instructions
|
bb [ dst src int-rep ##copy ] add-instructions
|
||||||
bb dst ;
|
bb dst ;
|
||||||
|
|
||||||
: convert-phi ( ##phi -- )
|
: convert-phi ( ##phi -- )
|
||||||
|
|
|
@ -58,13 +58,9 @@ SYMBOL: copies
|
||||||
|
|
||||||
GENERIC: prepare-insn ( insn -- )
|
GENERIC: prepare-insn ( insn -- )
|
||||||
|
|
||||||
: prepare-copy ( insn -- )
|
M: ##copy prepare-insn
|
||||||
[ dst>> ] [ src>> ] bi 2array copies get push ;
|
[ dst>> ] [ src>> ] bi 2array copies get push ;
|
||||||
|
|
||||||
M: ##copy prepare-insn prepare-copy ;
|
|
||||||
|
|
||||||
M: ##copy-float prepare-insn prepare-copy ;
|
|
||||||
|
|
||||||
M: ##phi prepare-insn
|
M: ##phi prepare-insn
|
||||||
[ dst>> ] [ inputs>> values ] bi
|
[ dst>> ] [ inputs>> values ] bi
|
||||||
[ eliminate-copy ] with each ;
|
[ eliminate-copy ] with each ;
|
||||||
|
@ -85,10 +81,8 @@ M: insn prepare-insn drop ;
|
||||||
[ 2drop ] [ eliminate-copy ] if
|
[ 2drop ] [ eliminate-copy ] if
|
||||||
] assoc-each ;
|
] assoc-each ;
|
||||||
|
|
||||||
UNION: copy-insn ##copy ##copy-float ;
|
|
||||||
|
|
||||||
: useless-copy? ( ##copy -- ? )
|
: useless-copy? ( ##copy -- ? )
|
||||||
dup copy-insn? [ [ dst>> ] [ src>> ] bi eq? ] [ drop f ] if ;
|
dup ##copy? [ [ dst>> ] [ src>> ] bi eq? ] [ drop f ] if ;
|
||||||
|
|
||||||
: perform-renaming ( cfg -- )
|
: perform-renaming ( cfg -- )
|
||||||
leader-map get keys [ dup leader ] H{ } map>assoc renamings set
|
leader-map get keys [ dup leader ] H{ } map>assoc renamings set
|
||||||
|
|
|
@ -16,19 +16,19 @@ IN: compiler.cfg.ssa.interference.tests
|
||||||
compute-live-ranges ;
|
compute-live-ranges ;
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##peek f V int-regs 0 D 0 }
|
T{ ##peek f V int-rep 0 D 0 }
|
||||||
T{ ##peek f V int-regs 2 D 0 }
|
T{ ##peek f V int-rep 2 D 0 }
|
||||||
T{ ##copy f V int-regs 1 V int-regs 0 }
|
T{ ##copy f V int-rep 1 V int-rep 0 }
|
||||||
T{ ##copy f V int-regs 3 V int-regs 2 }
|
T{ ##copy f V int-rep 3 V int-rep 2 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
} 0 test-bb
|
} 0 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##peek f V int-regs 4 D 0 }
|
T{ ##peek f V int-rep 4 D 0 }
|
||||||
T{ ##peek f V int-regs 5 D 0 }
|
T{ ##peek f V int-rep 5 D 0 }
|
||||||
T{ ##replace f V int-regs 3 D 0 }
|
T{ ##replace f V int-rep 3 D 0 }
|
||||||
T{ ##peek f V int-regs 6 D 0 }
|
T{ ##peek f V int-rep 6 D 0 }
|
||||||
T{ ##replace f V int-regs 5 D 0 }
|
T{ ##replace f V int-rep 5 D 0 }
|
||||||
T{ ##return }
|
T{ ##return }
|
||||||
} 1 test-bb
|
} 1 test-bb
|
||||||
|
|
||||||
|
@ -36,17 +36,17 @@ V{
|
||||||
|
|
||||||
[ ] [ test-interference ] unit-test
|
[ ] [ test-interference ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 V int-regs 1 vregs-interfere? ] unit-test
|
[ f ] [ V int-rep 0 V int-rep 1 vregs-interfere? ] unit-test
|
||||||
[ f ] [ V int-regs 1 V int-regs 0 vregs-interfere? ] unit-test
|
[ f ] [ V int-rep 1 V int-rep 0 vregs-interfere? ] unit-test
|
||||||
[ f ] [ V int-regs 2 V int-regs 3 vregs-interfere? ] unit-test
|
[ f ] [ V int-rep 2 V int-rep 3 vregs-interfere? ] unit-test
|
||||||
[ f ] [ V int-regs 3 V int-regs 2 vregs-interfere? ] unit-test
|
[ f ] [ V int-rep 3 V int-rep 2 vregs-interfere? ] unit-test
|
||||||
[ t ] [ V int-regs 0 V int-regs 2 vregs-interfere? ] unit-test
|
[ t ] [ V int-rep 0 V int-rep 2 vregs-interfere? ] unit-test
|
||||||
[ t ] [ V int-regs 2 V int-regs 0 vregs-interfere? ] unit-test
|
[ t ] [ V int-rep 2 V int-rep 0 vregs-interfere? ] unit-test
|
||||||
[ f ] [ V int-regs 1 V int-regs 3 vregs-interfere? ] unit-test
|
[ f ] [ V int-rep 1 V int-rep 3 vregs-interfere? ] unit-test
|
||||||
[ f ] [ V int-regs 3 V int-regs 1 vregs-interfere? ] unit-test
|
[ f ] [ V int-rep 3 V int-rep 1 vregs-interfere? ] unit-test
|
||||||
[ t ] [ V int-regs 3 V int-regs 4 vregs-interfere? ] unit-test
|
[ t ] [ V int-rep 3 V int-rep 4 vregs-interfere? ] unit-test
|
||||||
[ t ] [ V int-regs 4 V int-regs 3 vregs-interfere? ] unit-test
|
[ t ] [ V int-rep 4 V int-rep 3 vregs-interfere? ] unit-test
|
||||||
[ t ] [ V int-regs 3 V int-regs 5 vregs-interfere? ] unit-test
|
[ t ] [ V int-rep 3 V int-rep 5 vregs-interfere? ] unit-test
|
||||||
[ t ] [ V int-regs 5 V int-regs 3 vregs-interfere? ] unit-test
|
[ t ] [ V int-rep 5 V int-rep 3 vregs-interfere? ] unit-test
|
||||||
[ f ] [ V int-regs 3 V int-regs 6 vregs-interfere? ] unit-test
|
[ f ] [ V int-rep 3 V int-rep 6 vregs-interfere? ] unit-test
|
||||||
[ f ] [ V int-regs 6 V int-regs 3 vregs-interfere? ] unit-test
|
[ f ] [ V int-rep 6 V int-rep 3 vregs-interfere? ] unit-test
|
|
@ -28,17 +28,17 @@ IN: compiler.cfg.ssa.liveness
|
||||||
precompute-liveness ;
|
precompute-liveness ;
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##peek f V int-regs 0 D 0 }
|
T{ ##peek f V int-rep 0 D 0 }
|
||||||
T{ ##replace f V int-regs 0 D 0 }
|
T{ ##replace f V int-rep 0 D 0 }
|
||||||
T{ ##replace f V int-regs 1 D 1 }
|
T{ ##replace f V int-rep 1 D 1 }
|
||||||
} 0 test-bb
|
} 0 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 2 D 0 }
|
T{ ##replace f V int-rep 2 D 0 }
|
||||||
} 1 test-bb
|
} 1 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 3 D 0 }
|
T{ ##replace f V int-rep 3 D 0 }
|
||||||
} 2 test-bb
|
} 2 test-bb
|
||||||
|
|
||||||
0 { 1 2 } edges
|
0 { 1 2 } edges
|
||||||
|
@ -57,78 +57,78 @@ V{
|
||||||
[ t ] [ 1 self-T_q ] unit-test
|
[ t ] [ 1 self-T_q ] unit-test
|
||||||
[ t ] [ 2 self-T_q ] unit-test
|
[ t ] [ 2 self-T_q ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 0 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 0 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 1 0 get live-in? ] unit-test
|
[ t ] [ V int-rep 1 0 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 2 0 get live-in? ] unit-test
|
[ t ] [ V int-rep 2 0 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 3 0 get live-in? ] unit-test
|
[ t ] [ V int-rep 3 0 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 0 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 0 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 0 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 0 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 2 0 get live-out? ] unit-test
|
[ t ] [ V int-rep 2 0 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 3 0 get live-out? ] unit-test
|
[ t ] [ V int-rep 3 0 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 1 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 1 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 1 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 1 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 2 1 get live-in? ] unit-test
|
[ t ] [ V int-rep 2 1 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 3 1 get live-in? ] unit-test
|
[ f ] [ V int-rep 3 1 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 1 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 1 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 1 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 1 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 2 1 get live-out? ] unit-test
|
[ f ] [ V int-rep 2 1 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 3 1 get live-out? ] unit-test
|
[ f ] [ V int-rep 3 1 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 2 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 2 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 2 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 2 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 2 2 get live-in? ] unit-test
|
[ f ] [ V int-rep 2 2 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 3 2 get live-in? ] unit-test
|
[ t ] [ V int-rep 3 2 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 2 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 2 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 2 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 2 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 2 2 get live-out? ] unit-test
|
[ f ] [ V int-rep 2 2 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 3 2 get live-out? ] unit-test
|
[ f ] [ V int-rep 3 2 get live-out? ] unit-test
|
||||||
|
|
||||||
V{ } 0 test-bb
|
V{ } 0 test-bb
|
||||||
V{ } 1 test-bb
|
V{ } 1 test-bb
|
||||||
V{ } 2 test-bb
|
V{ } 2 test-bb
|
||||||
V{ } 3 test-bb
|
V{ } 3 test-bb
|
||||||
V{
|
V{
|
||||||
T{ ##phi f V int-regs 2 H{ { 2 V int-regs 0 } { 3 V int-regs 1 } } }
|
T{ ##phi f V int-rep 2 H{ { 2 V int-rep 0 } { 3 V int-rep 1 } } }
|
||||||
} 4 test-bb
|
} 4 test-bb
|
||||||
test-diamond
|
test-diamond
|
||||||
|
|
||||||
[ ] [ test-liveness ] unit-test
|
[ ] [ test-liveness ] unit-test
|
||||||
|
|
||||||
[ t ] [ V int-regs 0 1 get live-in? ] unit-test
|
[ t ] [ V int-rep 0 1 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 1 1 get live-in? ] unit-test
|
[ t ] [ V int-rep 1 1 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 2 1 get live-in? ] unit-test
|
[ f ] [ V int-rep 2 1 get live-in? ] unit-test
|
||||||
|
|
||||||
[ t ] [ V int-regs 0 1 get live-out? ] unit-test
|
[ t ] [ V int-rep 0 1 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 1 1 get live-out? ] unit-test
|
[ t ] [ V int-rep 1 1 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 2 1 get live-out? ] unit-test
|
[ f ] [ V int-rep 2 1 get live-out? ] unit-test
|
||||||
|
|
||||||
[ t ] [ V int-regs 0 2 get live-in? ] unit-test
|
[ t ] [ V int-rep 0 2 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 2 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 2 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 2 2 get live-in? ] unit-test
|
[ f ] [ V int-rep 2 2 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 2 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 2 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 2 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 2 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 2 2 get live-out? ] unit-test
|
[ f ] [ V int-rep 2 2 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 3 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 3 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 1 3 get live-in? ] unit-test
|
[ t ] [ V int-rep 1 3 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 2 3 get live-in? ] unit-test
|
[ f ] [ V int-rep 2 3 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 3 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 3 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 3 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 3 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 2 3 get live-out? ] unit-test
|
[ f ] [ V int-rep 2 3 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 4 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 4 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 4 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 4 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 2 4 get live-in? ] unit-test
|
[ f ] [ V int-rep 2 4 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 4 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 4 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 4 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 4 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 2 4 get live-out? ] unit-test
|
[ f ] [ V int-rep 2 4 get live-out? ] unit-test
|
||||||
|
|
||||||
! This is the CFG in Figure 3 from the paper
|
! This is the CFG in Figure 3 from the paper
|
||||||
V{ } 0 test-bb
|
V{ } 0 test-bb
|
||||||
|
@ -137,23 +137,23 @@ V{ } 1 test-bb
|
||||||
V{ } 2 test-bb
|
V{ } 2 test-bb
|
||||||
1 2 edge
|
1 2 edge
|
||||||
V{
|
V{
|
||||||
T{ ##peek f V int-regs 0 D 0 }
|
T{ ##peek f V int-rep 0 D 0 }
|
||||||
T{ ##peek f V int-regs 1 D 0 }
|
T{ ##peek f V int-rep 1 D 0 }
|
||||||
T{ ##peek f V int-regs 2 D 0 }
|
T{ ##peek f V int-rep 2 D 0 }
|
||||||
} 3 test-bb
|
} 3 test-bb
|
||||||
V{ } 11 test-bb
|
V{ } 11 test-bb
|
||||||
2 { 3 11 } edges
|
2 { 3 11 } edges
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 0 D 0 }
|
T{ ##replace f V int-rep 0 D 0 }
|
||||||
} 4 test-bb
|
} 4 test-bb
|
||||||
V{ } 8 test-bb
|
V{ } 8 test-bb
|
||||||
3 { 8 4 } edges
|
3 { 8 4 } edges
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 1 D 0 }
|
T{ ##replace f V int-rep 1 D 0 }
|
||||||
} 9 test-bb
|
} 9 test-bb
|
||||||
8 9 edge
|
8 9 edge
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 2 D 0 }
|
T{ ##replace f V int-rep 2 D 0 }
|
||||||
} 5 test-bb
|
} 5 test-bb
|
||||||
4 5 edge
|
4 5 edge
|
||||||
V{ } 10 test-bb
|
V{ } 10 test-bb
|
||||||
|
@ -203,90 +203,90 @@ V{ } 7 test-bb
|
||||||
[ f ] [ 10 get back-edge-target? ] unit-test
|
[ f ] [ 10 get back-edge-target? ] unit-test
|
||||||
[ f ] [ 11 get back-edge-target? ] unit-test
|
[ f ] [ 11 get back-edge-target? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 1 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 1 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 1 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 1 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 2 1 get live-in? ] unit-test
|
[ f ] [ V int-rep 2 1 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 1 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 1 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 1 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 1 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 2 1 get live-out? ] unit-test
|
[ f ] [ V int-rep 2 1 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 2 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 2 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 2 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 2 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 2 2 get live-in? ] unit-test
|
[ f ] [ V int-rep 2 2 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 2 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 2 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 2 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 2 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 2 2 get live-out? ] unit-test
|
[ f ] [ V int-rep 2 2 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 3 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 3 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 3 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 3 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 2 3 get live-in? ] unit-test
|
[ f ] [ V int-rep 2 3 get live-in? ] unit-test
|
||||||
|
|
||||||
[ t ] [ V int-regs 0 3 get live-out? ] unit-test
|
[ t ] [ V int-rep 0 3 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 1 3 get live-out? ] unit-test
|
[ t ] [ V int-rep 1 3 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 2 3 get live-out? ] unit-test
|
[ t ] [ V int-rep 2 3 get live-out? ] unit-test
|
||||||
|
|
||||||
[ t ] [ V int-regs 0 4 get live-in? ] unit-test
|
[ t ] [ V int-rep 0 4 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 4 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 4 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 2 4 get live-in? ] unit-test
|
[ t ] [ V int-rep 2 4 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 4 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 4 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 4 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 4 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 2 4 get live-out? ] unit-test
|
[ t ] [ V int-rep 2 4 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 5 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 5 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 5 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 5 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 2 5 get live-in? ] unit-test
|
[ t ] [ V int-rep 2 5 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 5 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 5 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 5 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 5 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 2 5 get live-out? ] unit-test
|
[ t ] [ V int-rep 2 5 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 6 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 6 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 6 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 6 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 2 6 get live-in? ] unit-test
|
[ t ] [ V int-rep 2 6 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 6 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 6 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 6 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 6 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 2 6 get live-out? ] unit-test
|
[ t ] [ V int-rep 2 6 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 7 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 7 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 7 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 7 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 2 7 get live-in? ] unit-test
|
[ f ] [ V int-rep 2 7 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 7 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 7 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 7 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 7 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 2 7 get live-out? ] unit-test
|
[ f ] [ V int-rep 2 7 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 8 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 8 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 1 8 get live-in? ] unit-test
|
[ t ] [ V int-rep 1 8 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 2 8 get live-in? ] unit-test
|
[ t ] [ V int-rep 2 8 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 8 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 8 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 1 8 get live-out? ] unit-test
|
[ t ] [ V int-rep 1 8 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 2 8 get live-out? ] unit-test
|
[ t ] [ V int-rep 2 8 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 9 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 9 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 1 9 get live-in? ] unit-test
|
[ t ] [ V int-rep 1 9 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 2 9 get live-in? ] unit-test
|
[ t ] [ V int-rep 2 9 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 9 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 9 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 1 9 get live-out? ] unit-test
|
[ t ] [ V int-rep 1 9 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 2 9 get live-out? ] unit-test
|
[ t ] [ V int-rep 2 9 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 10 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 10 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 1 10 get live-in? ] unit-test
|
[ t ] [ V int-rep 1 10 get live-in? ] unit-test
|
||||||
[ t ] [ V int-regs 2 10 get live-in? ] unit-test
|
[ t ] [ V int-rep 2 10 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 10 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 10 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 1 10 get live-out? ] unit-test
|
[ t ] [ V int-rep 1 10 get live-out? ] unit-test
|
||||||
[ t ] [ V int-regs 2 10 get live-out? ] unit-test
|
[ t ] [ V int-rep 2 10 get live-out? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 11 get live-in? ] unit-test
|
[ f ] [ V int-rep 0 11 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 1 11 get live-in? ] unit-test
|
[ f ] [ V int-rep 1 11 get live-in? ] unit-test
|
||||||
[ f ] [ V int-regs 2 11 get live-in? ] unit-test
|
[ f ] [ V int-rep 2 11 get live-in? ] unit-test
|
||||||
|
|
||||||
[ f ] [ V int-regs 0 11 get live-out? ] unit-test
|
[ f ] [ V int-rep 0 11 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 1 11 get live-out? ] unit-test
|
[ f ] [ V int-rep 1 11 get live-out? ] unit-test
|
||||||
[ f ] [ V int-regs 2 11 get live-out? ] unit-test
|
[ f ] [ V int-rep 2 11 get live-out? ] unit-test
|
||||||
|
|
|
@ -9,41 +9,27 @@ TUPLE: stack-frame
|
||||||
{ return integer }
|
{ return integer }
|
||||||
{ total-size integer }
|
{ total-size integer }
|
||||||
{ gc-root-size integer }
|
{ gc-root-size integer }
|
||||||
spill-counts ;
|
{ spill-area-size integer } ;
|
||||||
|
|
||||||
! Stack frame utilities
|
! Stack frame utilities
|
||||||
: param-base ( -- n )
|
: param-base ( -- n )
|
||||||
stack-frame get [ params>> ] [ return>> ] bi + ;
|
stack-frame get [ params>> ] [ return>> ] bi + ;
|
||||||
|
|
||||||
: spill-float-offset ( n -- offset )
|
: spill-offset ( n -- offset )
|
||||||
double-float-regs reg-size * ;
|
|
||||||
|
|
||||||
: spill-integer-base ( -- n )
|
|
||||||
stack-frame get spill-counts>> double-float-regs [ swap at ] keep reg-size *
|
|
||||||
param-base + ;
|
param-base + ;
|
||||||
|
|
||||||
: spill-integer-offset ( n -- offset )
|
|
||||||
cells spill-integer-base + ;
|
|
||||||
|
|
||||||
: spill-area-size ( stack-frame -- n )
|
|
||||||
spill-counts>> [ swap reg-size * ] { } assoc>map sum ;
|
|
||||||
|
|
||||||
: gc-root-base ( -- n )
|
: gc-root-base ( -- n )
|
||||||
stack-frame get spill-area-size
|
stack-frame get spill-area-size>> param-base + ;
|
||||||
param-base + ;
|
|
||||||
|
|
||||||
: gc-root-offset ( n -- n' ) gc-root-base + ;
|
: gc-root-offset ( n -- n' ) gc-root-base + ;
|
||||||
|
|
||||||
: gc-roots-size ( live-values -- n )
|
|
||||||
keys [ reg-class>> reg-size ] sigma ;
|
|
||||||
|
|
||||||
: (stack-frame-size) ( stack-frame -- n )
|
: (stack-frame-size) ( stack-frame -- n )
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
[ spill-area-size ]
|
|
||||||
[ gc-root-size>> ]
|
|
||||||
[ params>> ]
|
[ params>> ]
|
||||||
[ return>> ]
|
[ return>> ]
|
||||||
|
[ gc-root-size>> ]
|
||||||
|
[ spill-area-size>> ]
|
||||||
} cleave
|
} cleave
|
||||||
] sum-outputs ;
|
] sum-outputs ;
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,14 @@ V{
|
||||||
} 0 test-bb
|
} 0 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##replace f V int-regs 0 D 0 }
|
T{ ##replace f V int-rep 0 D 0 }
|
||||||
T{ ##replace f V int-regs 0 D 1 }
|
T{ ##replace f V int-rep 0 D 1 }
|
||||||
T{ ##replace f V int-regs 0 D 2 }
|
T{ ##replace f V int-rep 0 D 2 }
|
||||||
T{ ##inc-r f 1 }
|
T{ ##inc-r f 1 }
|
||||||
} 1 test-bb
|
} 1 test-bb
|
||||||
|
|
||||||
V{
|
V{
|
||||||
T{ ##peek f V int-regs 0 D 0 }
|
T{ ##peek f V int-rep 0 D 0 }
|
||||||
T{ ##inc-d f 1 }
|
T{ ##inc-d f 1 }
|
||||||
} 2 test-bb
|
} 2 test-bb
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,5 @@ IN: compiler.cfg.tco
|
||||||
] [ drop ] if ;
|
] [ drop ] if ;
|
||||||
|
|
||||||
: optimize-tail-calls ( cfg -- cfg' )
|
: optimize-tail-calls ( cfg -- cfg' )
|
||||||
dup cfg set
|
|
||||||
dup [ optimize-tail-call ] each-basic-block
|
dup [ optimize-tail-call ] each-basic-block
|
||||||
cfg-changed ;
|
cfg-changed ;
|
|
@ -6,11 +6,22 @@ compiler.cfg.registers cpu.architecture namespaces tools.test ;
|
||||||
|
|
||||||
[
|
[
|
||||||
V{
|
V{
|
||||||
T{ ##copy f V int-regs 1 V int-regs 2 }
|
T{ ##copy f V int-rep 1 V int-rep 2 int-rep }
|
||||||
T{ ##sub f V int-regs 1 V int-regs 1 V int-regs 3 }
|
T{ ##sub f V int-rep 1 V int-rep 1 V int-rep 3 }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
{
|
{
|
||||||
T{ ##sub f V int-regs 1 V int-regs 2 V int-regs 3 }
|
T{ ##sub f V int-rep 1 V int-rep 2 V int-rep 3 }
|
||||||
|
} (convert-two-operand)
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
V{
|
||||||
|
T{ ##copy f V double-float-rep 1 V double-float-rep 2 double-float-rep }
|
||||||
|
T{ ##sub-float f V double-float-rep 1 V double-float-rep 1 V double-float-rep 3 }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ ##sub-float f V double-float-rep 1 V double-float-rep 2 V double-float-rep 3 }
|
||||||
} (convert-two-operand)
|
} (convert-two-operand)
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
|
@ -44,10 +44,7 @@ UNION: two-operand-insn
|
||||||
GENERIC: convert-two-operand* ( insn -- )
|
GENERIC: convert-two-operand* ( insn -- )
|
||||||
|
|
||||||
: emit-copy ( dst src -- )
|
: emit-copy ( dst src -- )
|
||||||
dup reg-class>> {
|
dup rep>> ##copy ; inline
|
||||||
{ int-regs [ ##copy ] }
|
|
||||||
{ double-float-regs [ ##copy-float ] }
|
|
||||||
} case ; inline
|
|
||||||
|
|
||||||
M: two-operand-insn convert-two-operand*
|
M: two-operand-insn convert-two-operand*
|
||||||
[ [ dst>> ] [ src1>> ] bi emit-copy ]
|
[ [ dst>> ] [ src1>> ] bi emit-copy ]
|
||||||
|
|
|
@ -23,7 +23,6 @@ M: unary-expr simplify*
|
||||||
#! its source VN.
|
#! its source VN.
|
||||||
[ in>> vn>expr ] [ op>> ] bi {
|
[ in>> vn>expr ] [ op>> ] bi {
|
||||||
{ \ ##copy [ ] }
|
{ \ ##copy [ ] }
|
||||||
{ \ ##copy-float [ ] }
|
|
||||||
{ \ ##unbox-float [ simplify-unbox-float ] }
|
{ \ ##unbox-float [ simplify-unbox-float ] }
|
||||||
{ \ ##unbox-alien [ simplify-unbox-alien ] }
|
{ \ ##unbox-alien [ simplify-unbox-alien ] }
|
||||||
{ \ ##unbox-any-c-ptr [ simplify-unbox-alien ] }
|
{ \ ##unbox-any-c-ptr [ simplify-unbox-alien ] }
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,7 +14,7 @@ IN: compiler.cfg.value-numbering
|
||||||
! Local value numbering. Predecessors must be recomputed after this
|
! Local value numbering. Predecessors must be recomputed after this
|
||||||
: >copy ( insn -- insn/##copy )
|
: >copy ( insn -- insn/##copy )
|
||||||
dup dst>> dup vreg>vn vn>vreg
|
dup dst>> dup vreg>vn vn>vreg
|
||||||
2dup eq? [ 2drop ] [ \ ##copy new-insn nip ] if ;
|
2dup eq? [ 2drop ] [ dup rep>> \ ##copy new-insn nip ] if ;
|
||||||
|
|
||||||
: rewrite-loop ( insn -- insn' )
|
: rewrite-loop ( insn -- insn' )
|
||||||
dup rewrite [ rewrite-loop ] [ ] ?if ;
|
dup rewrite [ rewrite-loop ] [ ] ?if ;
|
||||||
|
|
|
@ -173,12 +173,12 @@ M: ##div-float generate-insn dst/src1/src2 %div-float ;
|
||||||
M: ##integer>float generate-insn dst/src %integer>float ;
|
M: ##integer>float generate-insn dst/src %integer>float ;
|
||||||
M: ##float>integer generate-insn dst/src %float>integer ;
|
M: ##float>integer generate-insn dst/src %float>integer ;
|
||||||
|
|
||||||
M: ##copy generate-insn dst/src %copy ;
|
M: ##copy generate-insn [ dst/src ] [ rep>> ] bi %copy ;
|
||||||
M: ##copy-float generate-insn dst/src %copy-float ;
|
|
||||||
M: ##unbox-float generate-insn dst/src %unbox-float ;
|
M: ##unbox-float generate-insn dst/src %unbox-float ;
|
||||||
M: ##unbox-any-c-ptr generate-insn dst/src/temp %unbox-any-c-ptr ;
|
M: ##unbox-any-c-ptr generate-insn dst/src/temp %unbox-any-c-ptr ;
|
||||||
M: ##box-float generate-insn dst/src/temp %box-float ;
|
M: ##box-float generate-insn dst/src/temp %box-float ;
|
||||||
M: ##box-alien generate-insn dst/src/temp %box-alien ;
|
M: ##box-alien generate-insn dst/src/temp %box-alien ;
|
||||||
|
|
||||||
M: ##alien-unsigned-1 generate-insn dst/src %alien-unsigned-1 ;
|
M: ##alien-unsigned-1 generate-insn dst/src %alien-unsigned-1 ;
|
||||||
M: ##alien-unsigned-2 generate-insn dst/src %alien-unsigned-2 ;
|
M: ##alien-unsigned-2 generate-insn dst/src %alien-unsigned-2 ;
|
||||||
|
@ -226,31 +226,37 @@ M: ##write-barrier generate-insn
|
||||||
GENERIC# save-gc-root 1 ( gc-root operand temp -- )
|
GENERIC# save-gc-root 1 ( gc-root operand temp -- )
|
||||||
|
|
||||||
M:: spill-slot save-gc-root ( gc-root operand temp -- )
|
M:: spill-slot save-gc-root ( gc-root operand temp -- )
|
||||||
temp operand n>> %reload-integer
|
temp operand n>> int-rep %reload
|
||||||
gc-root temp %save-gc-root ;
|
gc-root temp %save-gc-root ;
|
||||||
|
|
||||||
M: object save-gc-root drop %save-gc-root ;
|
M: object save-gc-root drop %save-gc-root ;
|
||||||
|
|
||||||
: save-gc-roots ( gc-roots temp -- ) '[ _ save-gc-root ] assoc-each ;
|
: save-gc-roots ( gc-roots temp -- ) '[ _ save-gc-root ] assoc-each ;
|
||||||
|
|
||||||
|
: save-data-regs ( data-regs -- ) [ first3 %spill ] each ;
|
||||||
|
|
||||||
GENERIC# load-gc-root 1 ( gc-root operand temp -- )
|
GENERIC# load-gc-root 1 ( gc-root operand temp -- )
|
||||||
|
|
||||||
M:: spill-slot load-gc-root ( gc-root operand temp -- )
|
M:: spill-slot load-gc-root ( gc-root operand temp -- )
|
||||||
gc-root temp %load-gc-root
|
gc-root temp %load-gc-root
|
||||||
temp operand n>> %spill-integer ;
|
temp operand n>> int-rep %spill ;
|
||||||
|
|
||||||
M: object load-gc-root drop %load-gc-root ;
|
M: object load-gc-root drop %load-gc-root ;
|
||||||
|
|
||||||
: load-gc-roots ( gc-roots temp -- ) '[ _ load-gc-root ] assoc-each ;
|
: load-gc-roots ( gc-roots temp -- ) '[ _ load-gc-root ] assoc-each ;
|
||||||
|
|
||||||
|
: load-data-regs ( data-regs -- ) [ first3 %reload ] each ;
|
||||||
|
|
||||||
M: _gc generate-insn
|
M: _gc generate-insn
|
||||||
"no-gc" define-label
|
"no-gc" define-label
|
||||||
{
|
{
|
||||||
[ [ "no-gc" get ] dip [ temp1>> ] [ temp2>> ] bi %check-nursery ]
|
[ [ "no-gc" get ] dip [ temp1>> ] [ temp2>> ] bi %check-nursery ]
|
||||||
[ [ uninitialized-locs>> ] [ temp1>> ] bi wipe-locs ]
|
[ [ uninitialized-locs>> ] [ temp1>> ] bi wipe-locs ]
|
||||||
[ [ gc-roots>> ] [ temp1>> ] bi save-gc-roots ]
|
[ data-values>> save-data-regs ]
|
||||||
[ gc-root-count>> %call-gc ]
|
[ [ tagged-values>> ] [ temp1>> ] bi save-gc-roots ]
|
||||||
[ [ gc-roots>> ] [ temp1>> ] bi load-gc-roots ]
|
[ gc-root-size>> %call-gc ]
|
||||||
|
[ [ tagged-values>> ] [ temp1>> ] bi load-gc-roots ]
|
||||||
|
[ data-values>> load-data-regs ]
|
||||||
} cleave
|
} cleave
|
||||||
"no-gc" resolve-label ;
|
"no-gc" resolve-label ;
|
||||||
|
|
||||||
|
@ -261,54 +267,45 @@ M: ##alien-global generate-insn
|
||||||
%alien-global ;
|
%alien-global ;
|
||||||
|
|
||||||
! ##alien-invoke
|
! ##alien-invoke
|
||||||
GENERIC: reg-class-variable ( register-class -- symbol )
|
GENERIC: next-fastcall-param ( reg-class -- )
|
||||||
|
|
||||||
M: reg-class reg-class-variable ;
|
: ?dummy-stack-params ( rep -- )
|
||||||
|
dummy-stack-params? [ rep-size cell align stack-params +@ ] [ drop ] if ;
|
||||||
|
|
||||||
M: float-regs reg-class-variable drop float-regs ;
|
: ?dummy-int-params ( rep -- )
|
||||||
|
dummy-int-params? [ rep-size cell /i 1 max int-regs +@ ] [ drop ] if ;
|
||||||
|
|
||||||
GENERIC: inc-reg-class ( register-class -- )
|
: ?dummy-fp-params ( rep -- )
|
||||||
|
|
||||||
: ?dummy-stack-params ( reg-class -- )
|
|
||||||
dummy-stack-params? [ reg-size cell align stack-params +@ ] [ drop ] if ;
|
|
||||||
|
|
||||||
: ?dummy-int-params ( reg-class -- )
|
|
||||||
dummy-int-params? [ reg-size cell /i 1 max int-regs +@ ] [ drop ] if ;
|
|
||||||
|
|
||||||
: ?dummy-fp-params ( reg-class -- )
|
|
||||||
drop dummy-fp-params? [ float-regs inc ] when ;
|
drop dummy-fp-params? [ float-regs inc ] when ;
|
||||||
|
|
||||||
M: int-regs inc-reg-class
|
M: int-rep next-fastcall-param
|
||||||
[ reg-class-variable inc ]
|
int-regs inc [ ?dummy-stack-params ] [ ?dummy-fp-params ] bi ;
|
||||||
[ ?dummy-stack-params ]
|
|
||||||
[ ?dummy-fp-params ]
|
|
||||||
tri ;
|
|
||||||
|
|
||||||
M: float-regs inc-reg-class
|
M: single-float-rep next-fastcall-param
|
||||||
[ reg-class-variable inc ]
|
float-regs inc [ ?dummy-stack-params ] [ ?dummy-int-params ] bi ;
|
||||||
[ ?dummy-stack-params ]
|
|
||||||
[ ?dummy-int-params ]
|
|
||||||
tri ;
|
|
||||||
|
|
||||||
GENERIC: reg-class-full? ( class -- ? )
|
M: double-float-rep next-fastcall-param
|
||||||
|
float-regs inc [ ?dummy-stack-params ] [ ?dummy-int-params ] bi ;
|
||||||
|
|
||||||
|
GENERIC: reg-class-full? ( reg-class -- ? )
|
||||||
|
|
||||||
M: stack-params reg-class-full? drop t ;
|
M: stack-params reg-class-full? drop t ;
|
||||||
|
|
||||||
M: object reg-class-full?
|
M: reg-class reg-class-full?
|
||||||
[ reg-class-variable get ] [ param-regs length ] bi >= ;
|
[ get ] [ param-regs length ] bi >= ;
|
||||||
|
|
||||||
: spill-param ( reg-class -- n reg-class )
|
: alloc-stack-param ( rep -- n reg-class rep )
|
||||||
stack-params get
|
stack-params get
|
||||||
[ reg-size cell align stack-params +@ ] dip
|
[ rep-size cell align stack-params +@ ] dip
|
||||||
stack-params ;
|
stack-params dup ;
|
||||||
|
|
||||||
: fastcall-param ( reg-class -- n reg-class )
|
: alloc-fastcall-param ( rep -- n reg-class rep )
|
||||||
[ reg-class-variable get ] [ inc-reg-class ] [ ] tri ;
|
[ reg-class-of [ get ] [ inc ] [ ] tri ] keep ;
|
||||||
|
|
||||||
: alloc-parameter ( parameter -- reg reg-class )
|
: alloc-parameter ( parameter -- reg rep )
|
||||||
c-type-reg-class dup reg-class-full?
|
c-type-rep dup reg-class-of reg-class-full?
|
||||||
[ spill-param ] [ fastcall-param ] if
|
[ alloc-stack-param ] [ alloc-fastcall-param ] if
|
||||||
[ param-reg ] keep ;
|
[ param-reg ] dip ;
|
||||||
|
|
||||||
: (flatten-int-type) ( size -- seq )
|
: (flatten-int-type) ( size -- seq )
|
||||||
cell /i "void*" c-type <repetition> ;
|
cell /i "void*" c-type <repetition> ;
|
||||||
|
@ -340,12 +337,12 @@ M: long-long-type flatten-value-type ( type -- types )
|
||||||
: reverse-each-parameter ( parameters quot -- )
|
: reverse-each-parameter ( parameters quot -- )
|
||||||
[ [ parameter-sizes nip ] keep ] dip 2reverse-each ; inline
|
[ [ parameter-sizes nip ] keep ] dip 2reverse-each ; inline
|
||||||
|
|
||||||
: reset-freg-counts ( -- )
|
: reset-fastcall-counts ( -- )
|
||||||
{ int-regs float-regs stack-params } [ 0 swap set ] each ;
|
{ int-regs float-regs stack-params } [ 0 swap set ] each ;
|
||||||
|
|
||||||
: with-param-regs ( quot -- )
|
: with-param-regs ( quot -- )
|
||||||
#! In quot you can call alloc-parameter
|
#! In quot you can call alloc-parameter
|
||||||
[ reset-freg-counts call ] with-scope ; inline
|
[ reset-fastcall-counts call ] with-scope ; inline
|
||||||
|
|
||||||
: move-parameters ( node word -- )
|
: move-parameters ( node word -- )
|
||||||
#! Moves values from C stack to registers (if word is
|
#! Moves values from C stack to registers (if word is
|
||||||
|
@ -431,6 +428,7 @@ M: ##alien-indirect generate-insn
|
||||||
alien-parameters [ box-parameter ] each-parameter ;
|
alien-parameters [ box-parameter ] each-parameter ;
|
||||||
|
|
||||||
: registers>objects ( node -- )
|
: registers>objects ( node -- )
|
||||||
|
! Generate code for boxing input parameters in a callback.
|
||||||
[
|
[
|
||||||
dup \ %save-param-reg move-parameters
|
dup \ %save-param-reg move-parameters
|
||||||
"nest_stacks" f %alien-invoke
|
"nest_stacks" f %alien-invoke
|
||||||
|
@ -528,21 +526,9 @@ M: _compare-float-branch generate-insn
|
||||||
>binary-branch< %compare-float-branch ;
|
>binary-branch< %compare-float-branch ;
|
||||||
|
|
||||||
M: _spill generate-insn
|
M: _spill generate-insn
|
||||||
[ src>> ] [ n>> ] [ class>> ] tri {
|
[ src>> ] [ n>> ] [ rep>> ] tri %spill ;
|
||||||
{ int-regs [ %spill-integer ] }
|
|
||||||
{ double-float-regs [ %spill-float ] }
|
|
||||||
} case ;
|
|
||||||
|
|
||||||
M: _reload generate-insn
|
M: _reload generate-insn
|
||||||
[ dst>> ] [ n>> ] [ class>> ] tri {
|
[ dst>> ] [ n>> ] [ rep>> ] tri %reload ;
|
||||||
{ int-regs [ %reload-integer ] }
|
|
||||||
{ double-float-regs [ %reload-float ] }
|
|
||||||
} case ;
|
|
||||||
|
|
||||||
M: _copy generate-insn
|
M: _spill-area-size generate-insn drop ;
|
||||||
[ dst>> ] [ src>> ] [ class>> ] tri {
|
|
||||||
{ int-regs [ %copy ] }
|
|
||||||
{ double-float-regs [ %copy-float ] }
|
|
||||||
} case ;
|
|
||||||
|
|
||||||
M: _spill-counts generate-insn drop ;
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ IN: compiler.tests.low-level-ir
|
||||||
V{ T{ ##prologue } T{ ##branch } } 0 test-bb
|
V{ T{ ##prologue } T{ ##branch } } 0 test-bb
|
||||||
V{
|
V{
|
||||||
T{ ##inc-d f 1 }
|
T{ ##inc-d f 1 }
|
||||||
T{ ##replace f V int-regs 0 D 0 }
|
T{ ##replace f V int-rep 0 D 0 }
|
||||||
T{ ##branch }
|
T{ ##branch }
|
||||||
} [ clone ] map append 1 test-bb
|
} [ clone ] map append 1 test-bb
|
||||||
V{
|
V{
|
||||||
|
@ -35,13 +35,13 @@ IN: compiler.tests.low-level-ir
|
||||||
! loading immediates
|
! loading immediates
|
||||||
[ f ] [
|
[ f ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 0 5 }
|
T{ ##load-immediate f V int-rep 0 5 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ "hello" ] [
|
[ "hello" ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-reference f V int-regs 0 "hello" }
|
T{ ##load-reference f V int-rep 0 "hello" }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
@ -49,72 +49,72 @@ IN: compiler.tests.low-level-ir
|
||||||
! one of the sources
|
! one of the sources
|
||||||
[ t ] [
|
[ t ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 1 $[ 2 cell log2 shift ] }
|
T{ ##load-immediate f V int-rep 1 $[ 2 cell log2 shift ] }
|
||||||
T{ ##load-reference f V int-regs 0 { t f t } }
|
T{ ##load-reference f V int-rep 0 { t f t } }
|
||||||
T{ ##slot f V int-regs 0 V int-regs 0 V int-regs 1 $[ array tag-number ] V int-regs 2 }
|
T{ ##slot f V int-rep 0 V int-rep 0 V int-rep 1 $[ array tag-number ] V int-rep 2 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ t ] [
|
[ t ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-reference f V int-regs 0 { t f t } }
|
T{ ##load-reference f V int-rep 0 { t f t } }
|
||||||
T{ ##slot-imm f V int-regs 0 V int-regs 0 2 $[ array tag-number ] V int-regs 2 }
|
T{ ##slot-imm f V int-rep 0 V int-rep 0 2 $[ array tag-number ] V int-rep 2 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ t ] [
|
[ t ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 1 $[ 2 cell log2 shift ] }
|
T{ ##load-immediate f V int-rep 1 $[ 2 cell log2 shift ] }
|
||||||
T{ ##load-reference f V int-regs 0 { t f t } }
|
T{ ##load-reference f V int-rep 0 { t f t } }
|
||||||
T{ ##set-slot f V int-regs 0 V int-regs 0 V int-regs 1 $[ array tag-number ] V int-regs 2 }
|
T{ ##set-slot f V int-rep 0 V int-rep 0 V int-rep 1 $[ array tag-number ] V int-rep 2 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
dup first eq?
|
dup first eq?
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ t ] [
|
[ t ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-reference f V int-regs 0 { t f t } }
|
T{ ##load-reference f V int-rep 0 { t f t } }
|
||||||
T{ ##set-slot-imm f V int-regs 0 V int-regs 0 2 $[ array tag-number ] }
|
T{ ##set-slot-imm f V int-rep 0 V int-rep 0 2 $[ array tag-number ] }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
dup first eq?
|
dup first eq?
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ 8 ] [
|
[ 8 ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 0 4 }
|
T{ ##load-immediate f V int-rep 0 4 }
|
||||||
T{ ##shl f V int-regs 0 V int-regs 0 V int-regs 0 }
|
T{ ##shl f V int-rep 0 V int-rep 0 V int-rep 0 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ 4 ] [
|
[ 4 ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 0 4 }
|
T{ ##load-immediate f V int-rep 0 4 }
|
||||||
T{ ##shl-imm f V int-regs 0 V int-regs 0 3 }
|
T{ ##shl-imm f V int-rep 0 V int-rep 0 3 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ 31 ] [
|
[ 31 ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-reference f V int-regs 1 B{ 31 67 52 } }
|
T{ ##load-reference f V int-rep 1 B{ 31 67 52 } }
|
||||||
T{ ##unbox-any-c-ptr f V int-regs 0 V int-regs 1 V int-regs 2 }
|
T{ ##unbox-any-c-ptr f V int-rep 0 V int-rep 1 V int-rep 2 }
|
||||||
T{ ##alien-unsigned-1 f V int-regs 0 V int-regs 0 }
|
T{ ##alien-unsigned-1 f V int-rep 0 V int-rep 0 }
|
||||||
T{ ##shl-imm f V int-regs 0 V int-regs 0 3 }
|
T{ ##shl-imm f V int-rep 0 V int-rep 0 3 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ CHAR: l ] [
|
[ CHAR: l ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-reference f V int-regs 0 "hello world" }
|
T{ ##load-reference f V int-rep 0 "hello world" }
|
||||||
T{ ##load-immediate f V int-regs 1 3 }
|
T{ ##load-immediate f V int-rep 1 3 }
|
||||||
T{ ##string-nth f V int-regs 0 V int-regs 0 V int-regs 1 V int-regs 2 }
|
T{ ##string-nth f V int-rep 0 V int-rep 0 V int-rep 1 V int-rep 2 }
|
||||||
T{ ##shl-imm f V int-regs 0 V int-regs 0 3 }
|
T{ ##shl-imm f V int-rep 0 V int-rep 0 3 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ 1 ] [
|
[ 1 ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 0 16 }
|
T{ ##load-immediate f V int-rep 0 16 }
|
||||||
T{ ##add-imm f V int-regs 0 V int-regs 0 -8 }
|
T{ ##add-imm f V int-rep 0 V int-rep 0 -8 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
@ -125,15 +125,15 @@ USE: multiline
|
||||||
|
|
||||||
[ 100 ] [
|
[ 100 ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-immediate f V int-regs 0 100 }
|
T{ ##load-immediate f V int-rep 0 100 }
|
||||||
T{ ##integer>bignum f V int-regs 0 V int-regs 0 V int-regs 1 }
|
T{ ##integer>bignum f V int-rep 0 V int-rep 0 V int-rep 1 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ 1 ] [
|
[ 1 ] [
|
||||||
V{
|
V{
|
||||||
T{ ##load-reference f V int-regs 0 ALIEN: 8 }
|
T{ ##load-reference f V int-rep 0 ALIEN: 8 }
|
||||||
T{ ##unbox-any-c-ptr f V int-regs 0 V int-regs 0 V int-regs 1 }
|
T{ ##unbox-any-c-ptr f V int-rep 0 V int-rep 0 V int-rep 1 }
|
||||||
} compile-test-bb
|
} compile-test-bb
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
|
|
@ -1,43 +1,51 @@
|
||||||
! Copyright (C) 2006, 2008 Slava Pestov.
|
! Copyright (C) 2006, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors arrays generic kernel kernel.private math
|
USING: accessors arrays generic kernel kernel.private math
|
||||||
memory namespaces make sequences layouts system hashtables
|
memory namespaces make sequences layouts system hashtables
|
||||||
classes alien byte-arrays combinators words sets fry ;
|
classes alien byte-arrays combinators words sets fry ;
|
||||||
IN: cpu.architecture
|
IN: cpu.architecture
|
||||||
|
|
||||||
|
! Representations -- these are like low-level types
|
||||||
|
|
||||||
|
! Integer registers can contain data with one of these two representations
|
||||||
|
SINGLETONS: tagged-rep int-rep ;
|
||||||
|
|
||||||
|
! Floating point registers can contain data with
|
||||||
|
! one of these representations
|
||||||
|
SINGLETONS: single-float-rep double-float-rep ;
|
||||||
|
|
||||||
|
UNION: representation tagged-rep int-rep single-float-rep double-float-rep ;
|
||||||
|
|
||||||
! Register classes
|
! Register classes
|
||||||
SINGLETON: int-regs
|
SINGLETONS: int-regs float-regs ;
|
||||||
SINGLETON: single-float-regs
|
|
||||||
SINGLETON: double-float-regs
|
|
||||||
UNION: float-regs single-float-regs double-float-regs ;
|
|
||||||
UNION: reg-class int-regs float-regs ;
|
UNION: reg-class int-regs float-regs ;
|
||||||
|
CONSTANT: reg-classes { int-regs float-regs }
|
||||||
|
|
||||||
! A pseudo-register class for parameters spilled on the stack
|
! A pseudo-register class for parameters spilled on the stack
|
||||||
SINGLETON: stack-params
|
SINGLETON: stack-params
|
||||||
|
|
||||||
GENERIC: reg-size ( register-class -- n )
|
: reg-class-of ( rep -- reg-class )
|
||||||
|
{
|
||||||
|
{ tagged-rep [ int-regs ] }
|
||||||
|
{ int-rep [ int-regs ] }
|
||||||
|
{ single-float-rep [ float-regs ] }
|
||||||
|
{ double-float-rep [ float-regs ] }
|
||||||
|
{ stack-params [ stack-params ] }
|
||||||
|
} case ;
|
||||||
|
|
||||||
M: int-regs reg-size drop cell ;
|
: rep-size ( rep -- n )
|
||||||
|
{
|
||||||
M: single-float-regs reg-size drop 4 ;
|
{ tagged-rep [ cell ] }
|
||||||
|
{ int-rep [ cell ] }
|
||||||
M: double-float-regs reg-size drop 8 ;
|
{ single-float-rep [ 4 ] }
|
||||||
|
{ double-float-rep [ 8 ] }
|
||||||
M: stack-params reg-size drop cell ;
|
{ stack-params [ cell ] }
|
||||||
|
} case ;
|
||||||
|
|
||||||
! Mapping from register class to machine registers
|
! Mapping from register class to machine registers
|
||||||
HOOK: machine-registers cpu ( -- assoc )
|
HOOK: machine-registers cpu ( -- assoc )
|
||||||
|
|
||||||
! Return values of this class go here
|
|
||||||
GENERIC: return-reg ( register-class -- reg )
|
|
||||||
|
|
||||||
! Sequence of registers used for parameter passing in class
|
|
||||||
GENERIC: param-regs ( register-class -- regs )
|
|
||||||
|
|
||||||
GENERIC: param-reg ( n register-class -- reg )
|
|
||||||
|
|
||||||
M: object param-reg param-regs nth ;
|
|
||||||
|
|
||||||
HOOK: two-operand? cpu ( -- ? )
|
HOOK: two-operand? cpu ( -- ? )
|
||||||
|
|
||||||
HOOK: %load-immediate cpu ( reg obj -- )
|
HOOK: %load-immediate cpu ( reg obj -- )
|
||||||
|
@ -100,8 +108,7 @@ HOOK: %div-float cpu ( dst src1 src2 -- )
|
||||||
HOOK: %integer>float cpu ( dst src -- )
|
HOOK: %integer>float cpu ( dst src -- )
|
||||||
HOOK: %float>integer cpu ( dst src -- )
|
HOOK: %float>integer cpu ( dst src -- )
|
||||||
|
|
||||||
HOOK: %copy cpu ( dst src -- )
|
HOOK: %copy cpu ( dst src rep -- )
|
||||||
HOOK: %copy-float cpu ( dst src -- )
|
|
||||||
HOOK: %unbox-float cpu ( dst src -- )
|
HOOK: %unbox-float cpu ( dst src -- )
|
||||||
HOOK: %unbox-any-c-ptr cpu ( dst src temp -- )
|
HOOK: %unbox-any-c-ptr cpu ( dst src temp -- )
|
||||||
HOOK: %box-float cpu ( dst src temp -- )
|
HOOK: %box-float cpu ( dst src temp -- )
|
||||||
|
@ -146,15 +153,27 @@ HOOK: %compare-branch cpu ( label cc src1 src2 -- )
|
||||||
HOOK: %compare-imm-branch cpu ( label cc src1 src2 -- )
|
HOOK: %compare-imm-branch cpu ( label cc src1 src2 -- )
|
||||||
HOOK: %compare-float-branch cpu ( label cc src1 src2 -- )
|
HOOK: %compare-float-branch cpu ( label cc src1 src2 -- )
|
||||||
|
|
||||||
HOOK: %spill-integer cpu ( src n -- )
|
HOOK: %spill cpu ( src n rep -- )
|
||||||
HOOK: %spill-float cpu ( src n -- )
|
HOOK: %reload cpu ( dst n rep -- )
|
||||||
HOOK: %reload-integer cpu ( dst n -- )
|
|
||||||
HOOK: %reload-float cpu ( dst n -- )
|
|
||||||
|
|
||||||
HOOK: %loop-entry cpu ( -- )
|
HOOK: %loop-entry cpu ( -- )
|
||||||
|
|
||||||
! FFI stuff
|
! FFI stuff
|
||||||
|
|
||||||
|
! Return values of this class go here
|
||||||
|
GENERIC: return-reg ( reg-class -- reg )
|
||||||
|
|
||||||
|
! Sequence of registers used for parameter passing in class
|
||||||
|
GENERIC: param-regs ( reg-class -- regs )
|
||||||
|
|
||||||
|
M: stack-params param-regs drop f ;
|
||||||
|
|
||||||
|
GENERIC: param-reg ( n reg-class -- reg )
|
||||||
|
|
||||||
|
M: reg-class param-reg param-regs nth ;
|
||||||
|
|
||||||
|
M: stack-params param-reg drop ;
|
||||||
|
|
||||||
! Is this integer small enough to appear in value template
|
! Is this integer small enough to appear in value template
|
||||||
! slots?
|
! slots?
|
||||||
HOOK: small-enough? cpu ( n -- ? )
|
HOOK: small-enough? cpu ( n -- ? )
|
||||||
|
@ -176,7 +195,7 @@ HOOK: dummy-fp-params? cpu ( -- ? )
|
||||||
|
|
||||||
HOOK: %prepare-unbox cpu ( -- )
|
HOOK: %prepare-unbox cpu ( -- )
|
||||||
|
|
||||||
HOOK: %unbox cpu ( n reg-class func -- )
|
HOOK: %unbox cpu ( n rep func -- )
|
||||||
|
|
||||||
HOOK: %unbox-long-long cpu ( n func -- )
|
HOOK: %unbox-long-long cpu ( n func -- )
|
||||||
|
|
||||||
|
@ -184,7 +203,7 @@ HOOK: %unbox-small-struct cpu ( c-type -- )
|
||||||
|
|
||||||
HOOK: %unbox-large-struct cpu ( n c-type -- )
|
HOOK: %unbox-large-struct cpu ( n c-type -- )
|
||||||
|
|
||||||
HOOK: %box cpu ( n reg-class func -- )
|
HOOK: %box cpu ( n rep func -- )
|
||||||
|
|
||||||
HOOK: %box-long-long cpu ( n func -- )
|
HOOK: %box-long-long cpu ( n func -- )
|
||||||
|
|
||||||
|
@ -194,9 +213,9 @@ HOOK: %box-small-struct cpu ( c-type -- )
|
||||||
|
|
||||||
HOOK: %box-large-struct cpu ( n c-type -- )
|
HOOK: %box-large-struct cpu ( n c-type -- )
|
||||||
|
|
||||||
GENERIC: %save-param-reg ( stack reg reg-class -- )
|
HOOK: %save-param-reg cpu ( stack reg rep -- )
|
||||||
|
|
||||||
GENERIC: %load-param-reg ( stack reg reg-class -- )
|
HOOK: %load-param-reg cpu ( stack reg rep -- )
|
||||||
|
|
||||||
HOOK: %prepare-alien-invoke cpu ( -- )
|
HOOK: %prepare-alien-invoke cpu ( -- )
|
||||||
|
|
||||||
|
@ -222,7 +241,3 @@ HOOK: %callback-value cpu ( ctype -- )
|
||||||
HOOK: %callback-return cpu ( params -- )
|
HOOK: %callback-return cpu ( params -- )
|
||||||
|
|
||||||
M: object %callback-return drop %return ;
|
M: object %callback-return drop %return ;
|
||||||
|
|
||||||
M: stack-params param-reg drop ;
|
|
||||||
|
|
||||||
M: stack-params param-regs drop f ;
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ enable-float-intrinsics
|
||||||
M: ppc machine-registers
|
M: ppc machine-registers
|
||||||
{
|
{
|
||||||
{ int-regs $[ 2 12 [a,b] 15 29 [a,b] append ] }
|
{ int-regs $[ 2 12 [a,b] 15 29 [a,b] append ] }
|
||||||
{ double-float-regs $[ 0 29 [a,b] ] }
|
{ float-regs $[ 0 29 [a,b] ] }
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
CONSTANT: scratch-reg 30
|
CONSTANT: scratch-reg 30
|
||||||
|
@ -493,26 +493,18 @@ M: float-regs return-reg drop 1 ;
|
||||||
M: int-regs %save-param-reg drop 1 rot local@ STW ;
|
M: int-regs %save-param-reg drop 1 rot local@ STW ;
|
||||||
M: int-regs %load-param-reg drop 1 rot local@ LWZ ;
|
M: int-regs %load-param-reg drop 1 rot local@ LWZ ;
|
||||||
|
|
||||||
GENERIC: STF ( src dst off reg-class -- )
|
M: single-float-rep %save-param-reg drop 1 rot local@ STFS ;
|
||||||
|
M: single-float-rep %load-param-reg 1 rot local@ LFS ;
|
||||||
|
|
||||||
M: single-float-regs STF drop STFS ;
|
M: double-float-rep %save-param-reg drop 1 rot local@ STFD ;
|
||||||
M: double-float-regs STF drop STFD ;
|
M: double-float-rep %load-param-reg 1 rot local@ LFD ;
|
||||||
|
|
||||||
M: float-regs %save-param-reg [ 1 rot local@ ] dip STF ;
|
M: stack-params %load-param-reg ( stack reg rep -- )
|
||||||
|
|
||||||
GENERIC: LF ( dst src off reg-class -- )
|
|
||||||
|
|
||||||
M: single-float-regs LF drop LFS ;
|
|
||||||
M: double-float-regs LF drop LFD ;
|
|
||||||
|
|
||||||
M: float-regs %load-param-reg [ 1 rot local@ ] dip LF ;
|
|
||||||
|
|
||||||
M: stack-params %load-param-reg ( stack reg reg-class -- )
|
|
||||||
drop [ 0 1 rot local@ LWZ 0 1 ] dip param@ STW ;
|
drop [ 0 1 rot local@ LWZ 0 1 ] dip param@ STW ;
|
||||||
|
|
||||||
: next-param@ ( n -- x ) param@ stack-frame get total-size>> + ;
|
: next-param@ ( n -- x ) param@ stack-frame get total-size>> + ;
|
||||||
|
|
||||||
M: stack-params %save-param-reg ( stack reg reg-class -- )
|
M: stack-params %save-param-reg ( stack reg rep -- )
|
||||||
#! Funky. Read the parameter from the caller's stack frame.
|
#! Funky. Read the parameter from the caller's stack frame.
|
||||||
#! This word is used in callbacks
|
#! This word is used in callbacks
|
||||||
drop
|
drop
|
||||||
|
@ -524,12 +516,12 @@ M: ppc %prepare-unbox ( -- )
|
||||||
3 ds-reg 0 LWZ
|
3 ds-reg 0 LWZ
|
||||||
ds-reg dup cell SUBI ;
|
ds-reg dup cell SUBI ;
|
||||||
|
|
||||||
M: ppc %unbox ( n reg-class func -- )
|
M: ppc %unbox ( n rep func -- )
|
||||||
! Value must be in r3
|
! Value must be in r3
|
||||||
! Call the unboxer
|
! Call the unboxer
|
||||||
f %alien-invoke
|
f %alien-invoke
|
||||||
! Store the return value on the C stack
|
! Store the return value on the C stack
|
||||||
over [ [ return-reg ] keep %save-param-reg ] [ 2drop ] if ;
|
over [ [ reg-class-of return-reg ] keep %save-param-reg ] [ 2drop ] if ;
|
||||||
|
|
||||||
M: ppc %unbox-long-long ( n func -- )
|
M: ppc %unbox-long-long ( n func -- )
|
||||||
! Value must be in r3:r4
|
! Value must be in r3:r4
|
||||||
|
@ -548,11 +540,11 @@ M: ppc %unbox-large-struct ( n c-type -- )
|
||||||
! Call the function
|
! Call the function
|
||||||
"to_value_struct" f %alien-invoke ;
|
"to_value_struct" f %alien-invoke ;
|
||||||
|
|
||||||
M: ppc %box ( n reg-class func -- )
|
M: ppc %box ( n rep func -- )
|
||||||
! If the source is a stack location, load it into freg #0.
|
! If the source is a stack location, load it into freg #0.
|
||||||
! If the source is f, then we assume the value is already in
|
! If the source is f, then we assume the value is already in
|
||||||
! freg #0.
|
! freg #0.
|
||||||
[ over [ 0 over param-reg swap %load-param-reg ] [ 2drop ] if ] dip
|
[ over [ 0 over reg-class-of param-reg swap %load-param-reg ] [ 2drop ] if ] dip
|
||||||
f %alien-invoke ;
|
f %alien-invoke ;
|
||||||
|
|
||||||
M: ppc %box-long-long ( n func -- )
|
M: ppc %box-long-long ( n func -- )
|
||||||
|
|
|
@ -10,21 +10,18 @@ cpu.x86.assembler.operands cpu.x86 cpu.architecture ;
|
||||||
IN: cpu.x86.32
|
IN: cpu.x86.32
|
||||||
|
|
||||||
! We implement the FFI for Linux, OS X and Windows all at once.
|
! We implement the FFI for Linux, OS X and Windows all at once.
|
||||||
! OS X requires that the stack be 16-byte aligned, and we do
|
! OS X requires that the stack be 16-byte aligned.
|
||||||
! this on all platforms, sacrificing some stack space for
|
|
||||||
! code simplicity.
|
|
||||||
|
|
||||||
M: x86.32 machine-registers
|
M: x86.32 machine-registers
|
||||||
{
|
{
|
||||||
{ int-regs { EAX ECX EDX EBP EBX } }
|
{ int-regs { EAX ECX EDX EBP EBX } }
|
||||||
{ double-float-regs { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } }
|
{ float-regs { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } }
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
M: x86.32 ds-reg ESI ;
|
M: x86.32 ds-reg ESI ;
|
||||||
M: x86.32 rs-reg EDI ;
|
M: x86.32 rs-reg EDI ;
|
||||||
M: x86.32 stack-reg ESP ;
|
M: x86.32 stack-reg ESP ;
|
||||||
M: x86.32 temp-reg-1 ECX ;
|
M: x86.32 temp-reg ECX ;
|
||||||
M: x86.32 temp-reg-2 EDX ;
|
|
||||||
|
|
||||||
M:: x86.32 %dispatch ( src temp -- )
|
M:: x86.32 %dispatch ( src temp -- )
|
||||||
! Load jump table base.
|
! Load jump table base.
|
||||||
|
@ -63,29 +60,23 @@ M: x86.32 return-struct-in-registers? ( c-type -- ? )
|
||||||
! On x86, parameters are never passed in registers.
|
! On x86, parameters are never passed in registers.
|
||||||
M: int-regs return-reg drop EAX ;
|
M: int-regs return-reg drop EAX ;
|
||||||
M: int-regs param-regs drop { } ;
|
M: int-regs param-regs drop { } ;
|
||||||
M: int-regs push-return-reg return-reg PUSH ;
|
|
||||||
|
|
||||||
M: int-regs load-return-reg
|
|
||||||
return-reg swap next-stack@ MOV ;
|
|
||||||
|
|
||||||
M: int-regs store-return-reg
|
|
||||||
[ stack@ ] [ return-reg ] bi* MOV ;
|
|
||||||
|
|
||||||
M: float-regs param-regs drop { } ;
|
M: float-regs param-regs drop { } ;
|
||||||
|
|
||||||
: FSTP ( operand size -- ) 4 = [ FSTPS ] [ FSTPL ] if ;
|
GENERIC: push-return-reg ( rep -- )
|
||||||
|
GENERIC: load-return-reg ( n rep -- )
|
||||||
|
GENERIC: store-return-reg ( n rep -- )
|
||||||
|
|
||||||
M: float-regs push-return-reg
|
M: int-rep push-return-reg drop EAX PUSH ;
|
||||||
stack-reg swap reg-size
|
M: int-rep load-return-reg drop EAX swap next-stack@ MOV ;
|
||||||
[ SUB ] [ [ [] ] dip FSTP ] 2bi ;
|
M: int-rep store-return-reg drop stack@ EAX MOV ;
|
||||||
|
|
||||||
: FLD ( operand size -- ) 4 = [ FLDS ] [ FLDL ] if ;
|
M: single-float-rep push-return-reg drop ESP 4 SUB ESP [] FSTPS ;
|
||||||
|
M: single-float-rep load-return-reg drop next-stack@ FLDS ;
|
||||||
|
M: single-float-rep store-return-reg drop stack@ FSTPS ;
|
||||||
|
|
||||||
M: float-regs load-return-reg
|
M: double-float-rep push-return-reg drop ESP 8 SUB ESP [] FSTPL ;
|
||||||
[ next-stack@ ] [ reg-size ] bi* FLD ;
|
M: double-float-rep load-return-reg drop next-stack@ FLDL ;
|
||||||
|
M: double-float-rep store-return-reg drop stack@ FSTPL ;
|
||||||
M: float-regs store-return-reg
|
|
||||||
[ stack@ ] [ reg-size ] bi* FSTP ;
|
|
||||||
|
|
||||||
: align-sub ( n -- )
|
: align-sub ( n -- )
|
||||||
[ align-stack ] keep - decr-stack-reg ;
|
[ align-stack ] keep - decr-stack-reg ;
|
||||||
|
@ -101,21 +92,21 @@ M: x86.32 %prologue ( n -- )
|
||||||
0 PUSH rc-absolute-cell rel-this
|
0 PUSH rc-absolute-cell rel-this
|
||||||
3 cells - decr-stack-reg ;
|
3 cells - decr-stack-reg ;
|
||||||
|
|
||||||
M: object %load-param-reg 3drop ;
|
M: x86.32 %load-param-reg 3drop ;
|
||||||
|
|
||||||
M: object %save-param-reg 3drop ;
|
M: x86.32 %save-param-reg 3drop ;
|
||||||
|
|
||||||
: (%box) ( n reg-class -- )
|
: (%box) ( n rep -- )
|
||||||
#! If n is f, push the return register onto the stack; we
|
#! If n is f, push the return register onto the stack; we
|
||||||
#! are boxing a return value of a C function. If n is an
|
#! are boxing a return value of a C function. If n is an
|
||||||
#! integer, push [ESP+n] on the stack; we are boxing a
|
#! integer, push [ESP+n] on the stack; we are boxing a
|
||||||
#! parameter being passed to a callback from C.
|
#! parameter being passed to a callback from C.
|
||||||
over [ load-return-reg ] [ 2drop ] if ;
|
over [ load-return-reg ] [ 2drop ] if ;
|
||||||
|
|
||||||
M:: x86.32 %box ( n reg-class func -- )
|
M:: x86.32 %box ( n rep func -- )
|
||||||
n reg-class (%box)
|
n rep (%box)
|
||||||
reg-class reg-size [
|
rep rep-size [
|
||||||
reg-class push-return-reg
|
rep push-return-reg
|
||||||
func f %alien-invoke
|
func f %alien-invoke
|
||||||
] with-aligned-stack ;
|
] with-aligned-stack ;
|
||||||
|
|
||||||
|
@ -165,7 +156,7 @@ M: x86.32 %prepare-unbox ( -- )
|
||||||
EAX ESI [] MOV
|
EAX ESI [] MOV
|
||||||
ESI 4 SUB ;
|
ESI 4 SUB ;
|
||||||
|
|
||||||
: (%unbox) ( func -- )
|
: call-unbox-func ( func -- )
|
||||||
4 [
|
4 [
|
||||||
! Push parameter
|
! Push parameter
|
||||||
EAX PUSH
|
EAX PUSH
|
||||||
|
@ -173,17 +164,17 @@ M: x86.32 %prepare-unbox ( -- )
|
||||||
f %alien-invoke
|
f %alien-invoke
|
||||||
] with-aligned-stack ;
|
] with-aligned-stack ;
|
||||||
|
|
||||||
M: x86.32 %unbox ( n reg-class func -- )
|
M: x86.32 %unbox ( n rep func -- )
|
||||||
#! The value being unboxed must already be in EAX.
|
#! The value being unboxed must already be in EAX.
|
||||||
#! If n is f, we're unboxing a return value about to be
|
#! If n is f, we're unboxing a return value about to be
|
||||||
#! returned by the callback. Otherwise, we're unboxing
|
#! returned by the callback. Otherwise, we're unboxing
|
||||||
#! a parameter to a C function about to be called.
|
#! a parameter to a C function about to be called.
|
||||||
(%unbox)
|
call-unbox-func
|
||||||
! Store the return value on the C stack
|
! Store the return value on the C stack
|
||||||
over [ store-return-reg ] [ 2drop ] if ;
|
over [ store-return-reg ] [ 2drop ] if ;
|
||||||
|
|
||||||
M: x86.32 %unbox-long-long ( n func -- )
|
M: x86.32 %unbox-long-long ( n func -- )
|
||||||
(%unbox)
|
call-unbox-func
|
||||||
! Store the return value on the C stack
|
! Store the return value on the C stack
|
||||||
[
|
[
|
||||||
dup stack@ EAX MOV
|
dup stack@ EAX MOV
|
||||||
|
|
|
@ -11,7 +11,7 @@ IN: cpu.x86.64
|
||||||
M: x86.64 machine-registers
|
M: x86.64 machine-registers
|
||||||
{
|
{
|
||||||
{ int-regs { RAX RCX RDX RBX RBP RSI RDI R8 R9 R10 R11 R12 R13 } }
|
{ int-regs { RAX RCX RDX RBX RBP RSI RDI R8 R9 R10 R11 R12 R13 } }
|
||||||
{ double-float-regs {
|
{ float-regs {
|
||||||
XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7
|
XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7
|
||||||
XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15
|
XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15
|
||||||
} }
|
} }
|
||||||
|
@ -46,20 +46,21 @@ M: int-regs return-reg drop RAX ;
|
||||||
M: float-regs return-reg drop XMM0 ;
|
M: float-regs return-reg drop XMM0 ;
|
||||||
|
|
||||||
M: x86.64 %prologue ( n -- )
|
M: x86.64 %prologue ( n -- )
|
||||||
temp-reg-1 0 MOV rc-absolute-cell rel-this
|
temp-reg 0 MOV rc-absolute-cell rel-this
|
||||||
dup PUSH
|
dup PUSH
|
||||||
temp-reg-1 PUSH
|
temp-reg PUSH
|
||||||
stack-reg swap 3 cells - SUB ;
|
stack-reg swap 3 cells - SUB ;
|
||||||
|
|
||||||
M: stack-params %load-param-reg
|
M: stack-params copy-register*
|
||||||
drop
|
drop
|
||||||
[ R11 swap param@ MOV ] dip
|
{
|
||||||
param@ R11 MOV ;
|
{ [ dup integer? ] [ R11 swap next-stack@ MOV R11 MOV ] }
|
||||||
|
{ [ over integer? ] [ R11 swap MOV param@ R11 MOV ] }
|
||||||
|
} cond ;
|
||||||
|
|
||||||
M: stack-params %save-param-reg
|
M: x86 %save-param-reg [ param@ ] 2dip copy-register ;
|
||||||
drop
|
|
||||||
R11 swap next-stack@ MOV
|
M: x86 %load-param-reg [ swap param@ ] dip copy-register ;
|
||||||
param@ R11 MOV ;
|
|
||||||
|
|
||||||
: with-return-regs ( quot -- )
|
: with-return-regs ( quot -- )
|
||||||
[
|
[
|
||||||
|
@ -73,20 +74,22 @@ M: x86.64 %prepare-unbox ( -- )
|
||||||
param-reg-1 R14 [] MOV
|
param-reg-1 R14 [] MOV
|
||||||
R14 cell SUB ;
|
R14 cell SUB ;
|
||||||
|
|
||||||
M: x86.64 %unbox ( n reg-class func -- )
|
M:: x86.64 %unbox ( n rep func -- )
|
||||||
! Call the unboxer
|
! Call the unboxer
|
||||||
f %alien-invoke
|
func f %alien-invoke
|
||||||
! Store the return value on the C stack
|
! Store the return value on the C stack if this is an
|
||||||
over [ [ return-reg ] keep %save-param-reg ] [ 2drop ] if ;
|
! alien-invoke, otherwise leave it the return register if
|
||||||
|
! this is the end of alien-callback
|
||||||
|
n [ n rep reg-class-of return-reg rep %save-param-reg ] when ;
|
||||||
|
|
||||||
M: x86.64 %unbox-long-long ( n func -- )
|
M: x86.64 %unbox-long-long ( n func -- )
|
||||||
int-regs swap %unbox ;
|
[ int-rep ] dip %unbox ;
|
||||||
|
|
||||||
: %unbox-struct-field ( c-type i -- )
|
: %unbox-struct-field ( c-type i -- )
|
||||||
! Alien must be in param-reg-1.
|
! Alien must be in param-reg-1.
|
||||||
R11 swap cells [+] swap reg-class>> {
|
R11 swap cells [+] swap rep>> reg-class-of {
|
||||||
{ int-regs [ int-regs get pop swap MOV ] }
|
{ int-regs [ int-regs get pop swap MOV ] }
|
||||||
{ double-float-regs [ float-regs get pop swap MOVSD ] }
|
{ float-regs [ float-regs get pop swap MOVSD ] }
|
||||||
} case ;
|
} case ;
|
||||||
|
|
||||||
M: x86.64 %unbox-small-struct ( c-type -- )
|
M: x86.64 %unbox-small-struct ( c-type -- )
|
||||||
|
@ -109,27 +112,31 @@ M: x86.64 %unbox-large-struct ( n c-type -- )
|
||||||
! Copy the struct to the C stack
|
! Copy the struct to the C stack
|
||||||
"to_value_struct" f %alien-invoke ;
|
"to_value_struct" f %alien-invoke ;
|
||||||
|
|
||||||
: load-return-value ( reg-class -- )
|
: load-return-value ( rep -- )
|
||||||
0 over param-reg swap return-reg
|
[ [ 0 ] dip reg-class-of param-reg ]
|
||||||
2dup eq? [ 2drop ] [ MOV ] if ;
|
[ reg-class-of return-reg ]
|
||||||
|
[ ]
|
||||||
|
tri copy-register ;
|
||||||
|
|
||||||
M: x86.64 %box ( n reg-class func -- )
|
M:: x86.64 %box ( n rep func -- )
|
||||||
rot [
|
n [
|
||||||
rot [ 0 swap param-reg ] keep %load-param-reg
|
n
|
||||||
|
0 rep reg-class-of param-reg
|
||||||
|
rep %load-param-reg
|
||||||
] [
|
] [
|
||||||
swap load-return-value
|
rep load-return-value
|
||||||
] if*
|
] if
|
||||||
f %alien-invoke ;
|
func f %alien-invoke ;
|
||||||
|
|
||||||
M: x86.64 %box-long-long ( n func -- )
|
M: x86.64 %box-long-long ( n func -- )
|
||||||
int-regs swap %box ;
|
[ int-rep ] dip %box ;
|
||||||
|
|
||||||
: box-struct-field@ ( i -- operand ) 1+ cells param@ ;
|
: box-struct-field@ ( i -- operand ) 1+ cells param@ ;
|
||||||
|
|
||||||
: %box-struct-field ( c-type i -- )
|
: %box-struct-field ( c-type i -- )
|
||||||
box-struct-field@ swap reg-class>> {
|
box-struct-field@ swap c-type-rep reg-class-of {
|
||||||
{ int-regs [ int-regs get pop MOV ] }
|
{ int-regs [ int-regs get pop MOV ] }
|
||||||
{ double-float-regs [ float-regs get pop MOVSD ] }
|
{ float-regs [ float-regs get pop MOVSD ] }
|
||||||
} case ;
|
} case ;
|
||||||
|
|
||||||
M: x86.64 %box-small-struct ( c-type -- )
|
M: x86.64 %box-small-struct ( c-type -- )
|
||||||
|
|
|
@ -6,7 +6,8 @@ cpu.x86.assembler cpu.x86.assembler.operands cpu.x86 compiler.codegen
|
||||||
compiler.cfg.registers ;
|
compiler.cfg.registers ;
|
||||||
IN: cpu.x86.64.unix
|
IN: cpu.x86.64.unix
|
||||||
|
|
||||||
M: int-regs param-regs drop { RDI RSI RDX RCX R8 R9 } ;
|
M: int-regs param-regs
|
||||||
|
drop { RDI RSI RDX RCX R8 R9 } ;
|
||||||
|
|
||||||
M: float-regs param-regs
|
M: float-regs param-regs
|
||||||
drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ;
|
drop { XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 } ;
|
||||||
|
@ -15,7 +16,7 @@ M: x86.64 reserved-area-size 0 ;
|
||||||
|
|
||||||
! The ABI for passing structs by value is pretty messed up
|
! The ABI for passing structs by value is pretty messed up
|
||||||
<< "void*" c-type clone "__stack_value" define-primitive-type
|
<< "void*" c-type clone "__stack_value" define-primitive-type
|
||||||
stack-params "__stack_value" c-type (>>reg-class) >>
|
stack-params "__stack_value" c-type (>>rep) >>
|
||||||
|
|
||||||
: struct-types&offset ( struct-type -- pairs )
|
: struct-types&offset ( struct-type -- pairs )
|
||||||
fields>> [
|
fields>> [
|
||||||
|
@ -29,7 +30,7 @@ stack-params "__stack_value" c-type (>>reg-class) >>
|
||||||
|
|
||||||
: flatten-small-struct ( c-type -- seq )
|
: flatten-small-struct ( c-type -- seq )
|
||||||
struct-types&offset split-struct [
|
struct-types&offset split-struct [
|
||||||
[ c-type c-type-reg-class ] map
|
[ c-type c-type-rep reg-class-of ] map
|
||||||
int-regs swap member? "void*" "double" ? c-type
|
int-regs swap member? "void*" "double" ? c-type
|
||||||
] map ;
|
] map ;
|
||||||
|
|
||||||
|
@ -53,6 +54,4 @@ M: x86.64 dummy-int-params? f ;
|
||||||
|
|
||||||
M: x86.64 dummy-fp-params? f ;
|
M: x86.64 dummy-fp-params? f ;
|
||||||
|
|
||||||
M: x86.64 temp-reg-1 R8 ;
|
M: x86.64 temp-reg R8 ;
|
||||||
|
|
||||||
M: x86.64 temp-reg-2 R9 ;
|
|
||||||
|
|
|
@ -22,9 +22,7 @@ M: x86.64 dummy-int-params? t ;
|
||||||
|
|
||||||
M: x86.64 dummy-fp-params? t ;
|
M: x86.64 dummy-fp-params? t ;
|
||||||
|
|
||||||
M: x86.64 temp-reg-1 RAX ;
|
M: x86.64 temp-reg RAX ;
|
||||||
|
|
||||||
M: x86.64 temp-reg-2 RCX ;
|
|
||||||
|
|
||||||
<<
|
<<
|
||||||
"longlong" "ptrdiff_t" typedef
|
"longlong" "ptrdiff_t" typedef
|
||||||
|
|
|
@ -26,15 +26,11 @@ REGISTERS: 128
|
||||||
XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7
|
XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7
|
||||||
XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15 ;
|
XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15 ;
|
||||||
|
|
||||||
<PRIVATE
|
|
||||||
|
|
||||||
GENERIC: extended? ( op -- ? )
|
|
||||||
|
|
||||||
M: object extended? drop f ;
|
|
||||||
|
|
||||||
PREDICATE: register < word
|
PREDICATE: register < word
|
||||||
"register" word-prop ;
|
"register" word-prop ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
PREDICATE: register-8 < register
|
PREDICATE: register-8 < register
|
||||||
"register-size" word-prop 8 = ;
|
"register-size" word-prop 8 = ;
|
||||||
|
|
||||||
|
@ -50,6 +46,10 @@ PREDICATE: register-64 < register
|
||||||
PREDICATE: register-128 < register
|
PREDICATE: register-128 < register
|
||||||
"register-size" word-prop 128 = ;
|
"register-size" word-prop 128 = ;
|
||||||
|
|
||||||
|
GENERIC: extended? ( op -- ? )
|
||||||
|
|
||||||
|
M: object extended? drop f ;
|
||||||
|
|
||||||
M: register extended? "register" word-prop 7 > ;
|
M: register extended? "register" word-prop 7 > ;
|
||||||
|
|
||||||
! Addressing modes
|
! Addressing modes
|
||||||
|
|
|
@ -30,9 +30,7 @@ HOOK: reserved-area-size cpu ( -- n )
|
||||||
|
|
||||||
: param@ ( n -- op ) reserved-area-size + stack@ ;
|
: param@ ( n -- op ) reserved-area-size + stack@ ;
|
||||||
|
|
||||||
: spill-integer@ ( n -- op ) spill-integer-offset param@ ;
|
: spill@ ( n -- op ) spill-offset param@ ;
|
||||||
|
|
||||||
: spill-float@ ( n -- op ) spill-float-offset param@ ;
|
|
||||||
|
|
||||||
: gc-root@ ( n -- op ) gc-root-offset param@ ;
|
: gc-root@ ( n -- op ) gc-root-offset param@ ;
|
||||||
|
|
||||||
|
@ -48,9 +46,11 @@ HOOK: reserved-area-size cpu ( -- n )
|
||||||
M: x86 stack-frame-size ( stack-frame -- i )
|
M: x86 stack-frame-size ( stack-frame -- i )
|
||||||
(stack-frame-size) 3 cells reserved-area-size + + align-stack ;
|
(stack-frame-size) 3 cells reserved-area-size + + align-stack ;
|
||||||
|
|
||||||
HOOK: temp-reg-1 cpu ( -- reg )
|
! Must be a volatile register not used for parameter passing, for safe
|
||||||
HOOK: temp-reg-2 cpu ( -- reg )
|
! use in calls in and out of C
|
||||||
|
HOOK: temp-reg cpu ( -- reg )
|
||||||
|
|
||||||
|
! Fastcall calling convention
|
||||||
HOOK: param-reg-1 cpu ( -- reg )
|
HOOK: param-reg-1 cpu ( -- reg )
|
||||||
HOOK: param-reg-2 cpu ( -- reg )
|
HOOK: param-reg-2 cpu ( -- reg )
|
||||||
|
|
||||||
|
@ -126,9 +126,6 @@ M: x86 %sar-imm nip SAR ;
|
||||||
M: x86 %not drop NOT ;
|
M: x86 %not drop NOT ;
|
||||||
M: x86 %log2 BSR ;
|
M: x86 %log2 BSR ;
|
||||||
|
|
||||||
: ?MOV ( dst src -- )
|
|
||||||
2dup = [ 2drop ] [ MOV ] if ; inline
|
|
||||||
|
|
||||||
:: overflow-template ( label dst src1 src2 insn -- )
|
:: overflow-template ( label dst src1 src2 insn -- )
|
||||||
src1 src2 insn call
|
src1 src2 insn call
|
||||||
label JO ; inline
|
label JO ; inline
|
||||||
|
@ -210,10 +207,17 @@ M: x86 %div-float nip DIVSD ;
|
||||||
M: x86 %integer>float CVTSI2SD ;
|
M: x86 %integer>float CVTSI2SD ;
|
||||||
M: x86 %float>integer CVTTSD2SI ;
|
M: x86 %float>integer CVTTSD2SI ;
|
||||||
|
|
||||||
M: x86 %copy ( dst src -- ) ?MOV ;
|
GENERIC: copy-register* ( dst src rep -- )
|
||||||
|
|
||||||
M: x86 %copy-float ( dst src -- )
|
M: int-rep copy-register* drop MOV ;
|
||||||
2dup = [ 2drop ] [ MOVSD ] if ;
|
M: tagged-rep copy-register* drop MOV ;
|
||||||
|
M: single-float-rep copy-register* drop MOVSS ;
|
||||||
|
M: double-float-rep copy-register* drop MOVSD ;
|
||||||
|
|
||||||
|
: copy-register ( dst src rep -- )
|
||||||
|
2over eq? [ 3drop ] [ copy-register* ] if ;
|
||||||
|
|
||||||
|
M: x86 %copy ( dst src rep -- ) copy-register ;
|
||||||
|
|
||||||
M: x86 %unbox-float ( dst src -- )
|
M: x86 %unbox-float ( dst src -- )
|
||||||
float-offset [+] MOVSD ;
|
float-offset [+] MOVSD ;
|
||||||
|
@ -301,6 +305,9 @@ M: x86.64 has-small-reg? 2drop t ;
|
||||||
[ quot call ] with-save/restore
|
[ quot call ] with-save/restore
|
||||||
] if ; inline
|
] if ; inline
|
||||||
|
|
||||||
|
: ?MOV ( dst src -- )
|
||||||
|
2dup = [ 2drop ] [ MOV ] if ; inline
|
||||||
|
|
||||||
M:: x86 %string-nth ( dst src index temp -- )
|
M:: x86 %string-nth ( dst src index temp -- )
|
||||||
! We request a small-reg of size 8 since those of size 16 are
|
! We request a small-reg of size 8 since those of size 16 are
|
||||||
! a superset.
|
! a superset.
|
||||||
|
@ -512,39 +519,21 @@ M: x86 %compare-float-branch ( label cc src1 src2 -- )
|
||||||
{ cc/= [ JNE ] }
|
{ cc/= [ JNE ] }
|
||||||
} case ;
|
} case ;
|
||||||
|
|
||||||
M: x86 %spill-integer ( src n -- ) spill-integer@ swap MOV ;
|
M: x86 %spill ( src n rep -- ) [ spill@ swap ] dip copy-register ;
|
||||||
M: x86 %reload-integer ( dst n -- ) spill-integer@ MOV ;
|
M: x86 %reload ( dst n rep -- ) [ spill@ ] dip copy-register ;
|
||||||
|
|
||||||
M: x86 %spill-float ( src n -- ) spill-float@ swap MOVSD ;
|
|
||||||
M: x86 %reload-float ( dst n -- ) spill-float@ MOVSD ;
|
|
||||||
|
|
||||||
M: x86 %loop-entry 16 code-alignment [ NOP ] times ;
|
M: x86 %loop-entry 16 code-alignment [ NOP ] times ;
|
||||||
|
|
||||||
M: int-regs %save-param-reg drop [ param@ ] dip MOV ;
|
|
||||||
M: int-regs %load-param-reg drop swap param@ MOV ;
|
|
||||||
|
|
||||||
GENERIC: MOVSS/D ( dst src reg-class -- )
|
|
||||||
|
|
||||||
M: single-float-regs MOVSS/D drop MOVSS ;
|
|
||||||
M: double-float-regs MOVSS/D drop MOVSD ;
|
|
||||||
|
|
||||||
M: float-regs %save-param-reg [ param@ ] 2dip MOVSS/D ;
|
|
||||||
M: float-regs %load-param-reg [ swap param@ ] dip MOVSS/D ;
|
|
||||||
|
|
||||||
GENERIC: push-return-reg ( reg-class -- )
|
|
||||||
GENERIC: load-return-reg ( n reg-class -- )
|
|
||||||
GENERIC: store-return-reg ( n reg-class -- )
|
|
||||||
|
|
||||||
M: x86 %prepare-alien-invoke
|
M: x86 %prepare-alien-invoke
|
||||||
#! Save Factor stack pointers in case the C code calls a
|
#! Save Factor stack pointers in case the C code calls a
|
||||||
#! callback which does a GC, which must reliably trace
|
#! callback which does a GC, which must reliably trace
|
||||||
#! all roots.
|
#! all roots.
|
||||||
temp-reg-1 "stack_chain" f %alien-global
|
temp-reg "stack_chain" f %alien-global
|
||||||
temp-reg-1 temp-reg-1 [] MOV
|
temp-reg temp-reg [] MOV
|
||||||
temp-reg-1 [] stack-reg MOV
|
temp-reg [] stack-reg MOV
|
||||||
temp-reg-1 [] cell SUB
|
temp-reg [] cell SUB
|
||||||
temp-reg-1 2 cells [+] ds-reg MOV
|
temp-reg 2 cells [+] ds-reg MOV
|
||||||
temp-reg-1 3 cells [+] rs-reg MOV ;
|
temp-reg 3 cells [+] rs-reg MOV ;
|
||||||
|
|
||||||
M: x86 value-struct? drop t ;
|
M: x86 value-struct? drop t ;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue