Merge branch 'master' of git://factorcode.org/git/factor
commit
0b33c52886
|
@ -171,6 +171,7 @@ M: #if emit-node
|
||||||
[
|
[
|
||||||
V{ } clone node-stack set
|
V{ } clone node-stack set
|
||||||
##prologue
|
##prologue
|
||||||
|
begin-basic-block
|
||||||
emit-nodes
|
emit-nodes
|
||||||
basic-block get [
|
basic-block get [
|
||||||
##epilogue
|
##epilogue
|
||||||
|
|
|
@ -219,3 +219,14 @@ TUPLE: my-tuple ;
|
||||||
: bad-value-bug ( a -- b ) [ 3 ] [ 3 ] if f <array> ;
|
: bad-value-bug ( a -- b ) [ 3 ] [ 3 ] if f <array> ;
|
||||||
|
|
||||||
[ { f f f } ] [ t bad-value-bug ] unit-test
|
[ { f f f } ] [ t bad-value-bug ] unit-test
|
||||||
|
|
||||||
|
! PowerPC regression
|
||||||
|
TUPLE: id obj ;
|
||||||
|
|
||||||
|
: (gc-check-bug) ( a b -- c )
|
||||||
|
{ [ id boa ] [ id boa ] } dispatch ;
|
||||||
|
|
||||||
|
: gc-check-bug ( -- )
|
||||||
|
10000000 [ "hi" 0 (gc-check-bug) drop ] times ;
|
||||||
|
|
||||||
|
[ ] [ gc-check-bug ] unit-test
|
||||||
|
|
|
@ -4,7 +4,8 @@ USING: accessors assocs sequences kernel combinators make math
|
||||||
math.order math.ranges system namespaces locals layouts words
|
math.order math.ranges system namespaces locals layouts words
|
||||||
alien alien.c-types cpu.architecture cpu.ppc.assembler
|
alien alien.c-types cpu.architecture cpu.ppc.assembler
|
||||||
compiler.cfg.registers compiler.cfg.instructions
|
compiler.cfg.registers compiler.cfg.instructions
|
||||||
compiler.constants compiler.codegen compiler.codegen.fixup ;
|
compiler.constants compiler.codegen compiler.codegen.fixup
|
||||||
|
compiler.cfg.intrinsics compiler.cfg.stack-frame ;
|
||||||
IN: cpu.ppc
|
IN: cpu.ppc
|
||||||
|
|
||||||
! PowerPC register assignments:
|
! PowerPC register assignments:
|
||||||
|
@ -15,15 +16,19 @@ IN: cpu.ppc
|
||||||
! f0-f29: float vregs
|
! f0-f29: float vregs
|
||||||
! f30, f31: float scratch
|
! f30, f31: float scratch
|
||||||
|
|
||||||
|
enable-float-intrinsics
|
||||||
|
|
||||||
|
<< \ ##integer>float t frame-required? set-word-prop
|
||||||
|
\ ##float>integer t frame-required? set-word-prop >>
|
||||||
|
|
||||||
M: ppc machine-registers
|
M: ppc machine-registers
|
||||||
{
|
{
|
||||||
{ int-regs T{ range f 2 26 1 } }
|
{ int-regs T{ range f 2 26 1 } }
|
||||||
{ double-float-regs T{ range f 0 28 1 } }
|
{ double-float-regs T{ range f 0 29 1 } }
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
: scratch-reg 28 ; inline
|
: scratch-reg 28 ; inline
|
||||||
: fp-scratch-reg-1 29 ; inline
|
: fp-scratch-reg 30 ; inline
|
||||||
: fp-scratch-reg-2 30 ; inline
|
|
||||||
|
|
||||||
M: ppc two-operand? f ;
|
M: ppc two-operand? f ;
|
||||||
|
|
||||||
|
@ -54,8 +59,16 @@ M: ppc %inc-d ( n -- ) ds-reg (%inc) ;
|
||||||
M: ppc %inc-r ( n -- ) rs-reg (%inc) ;
|
M: ppc %inc-r ( n -- ) rs-reg (%inc) ;
|
||||||
|
|
||||||
HOOK: reserved-area-size os ( -- n )
|
HOOK: reserved-area-size os ( -- n )
|
||||||
HOOK: lr-save os ( -- n )
|
|
||||||
|
|
||||||
|
! The start of the stack frame contains the size of this frame
|
||||||
|
! as well as the currently executing XT
|
||||||
|
: factor-area-size ( -- n ) 2 cells ; foldable
|
||||||
|
: next-save ( n -- i ) cell - ;
|
||||||
|
: xt-save ( n -- i ) 2 cells - ;
|
||||||
|
|
||||||
|
! Next, we have the spill area as well as the FFI parameter area.
|
||||||
|
! They overlap, since basic blocks with FFI calls will never
|
||||||
|
! spill.
|
||||||
: param@ ( n -- x ) reserved-area-size + ; inline
|
: param@ ( n -- x ) reserved-area-size + ; inline
|
||||||
|
|
||||||
: param-save-size ( -- n ) 8 cells ; foldable
|
: param-save-size ( -- n ) 8 cells ; foldable
|
||||||
|
@ -63,19 +76,34 @@ HOOK: lr-save os ( -- n )
|
||||||
: local@ ( n -- x )
|
: local@ ( n -- x )
|
||||||
reserved-area-size param-save-size + + ; inline
|
reserved-area-size param-save-size + + ; inline
|
||||||
|
|
||||||
: factor-area-size ( -- n ) 2 cells ; foldable
|
: spill-integer-base ( -- n )
|
||||||
|
stack-frame get spill-counts>> double-float-regs swap at
|
||||||
|
double-float-regs reg-size * ;
|
||||||
|
|
||||||
: next-save ( n -- i ) cell - ;
|
: spill-integer@ ( n -- offset )
|
||||||
|
cells spill-integer-base + param@ ;
|
||||||
|
|
||||||
: xt-save ( n -- i ) 2 cells - ;
|
: spill-float@ ( n -- offset )
|
||||||
|
double-float-regs reg-size * param@ ;
|
||||||
|
|
||||||
|
! Some FP intrinsics need a temporary scratch area in the stack
|
||||||
|
! frame, 8 bytes in size
|
||||||
|
: scratch@ ( n -- offset )
|
||||||
|
stack-frame get total-size>>
|
||||||
|
factor-area-size -
|
||||||
|
param-save-size -
|
||||||
|
+ ;
|
||||||
|
|
||||||
|
! Finally we have the linkage area
|
||||||
|
HOOK: lr-save os ( -- n )
|
||||||
|
|
||||||
M: ppc stack-frame-size ( stack-frame -- i )
|
M: ppc stack-frame-size ( stack-frame -- i )
|
||||||
[ spill-counts>> [ swap reg-size * ] { } assoc>map sum ]
|
[ spill-counts>> [ swap reg-size * ] { } assoc>map sum ]
|
||||||
[ params>> ]
|
[ params>> ]
|
||||||
[ return>> ]
|
[ return>> ]
|
||||||
tri + +
|
tri + +
|
||||||
reserved-area-size +
|
|
||||||
param-save-size +
|
param-save-size +
|
||||||
|
reserved-area-size +
|
||||||
factor-area-size +
|
factor-area-size +
|
||||||
4 cells align ;
|
4 cells align ;
|
||||||
|
|
||||||
|
@ -198,19 +226,19 @@ M: ppc %div-float FDIV ;
|
||||||
|
|
||||||
M:: ppc %integer>float ( dst src -- )
|
M:: ppc %integer>float ( dst src -- )
|
||||||
HEX: 4330 scratch-reg LIS
|
HEX: 4330 scratch-reg LIS
|
||||||
scratch-reg 1 0 param@ STW
|
scratch-reg 1 0 scratch@ STW
|
||||||
scratch-reg src MR
|
scratch-reg src MR
|
||||||
scratch-reg dup HEX: 8000 XORIS
|
scratch-reg dup HEX: 8000 XORIS
|
||||||
scratch-reg 1 cell param@ STW
|
scratch-reg 1 4 scratch@ STW
|
||||||
fp-scratch-reg-2 1 0 param@ LFD
|
dst 1 0 scratch@ LFD
|
||||||
scratch-reg 4503601774854144.0 %load-indirect
|
scratch-reg 4503601774854144.0 %load-indirect
|
||||||
fp-scratch-reg-2 scratch-reg float-offset LFD
|
fp-scratch-reg scratch-reg float-offset LFD
|
||||||
fp-scratch-reg-2 fp-scratch-reg-2 fp-scratch-reg-2 FSUB ;
|
dst dst fp-scratch-reg FSUB ;
|
||||||
|
|
||||||
M:: ppc %float>integer ( dst src -- )
|
M:: ppc %float>integer ( dst src -- )
|
||||||
fp-scratch-reg-1 src FCTIWZ
|
fp-scratch-reg src FCTIWZ
|
||||||
fp-scratch-reg-2 1 0 param@ STFD
|
fp-scratch-reg 1 0 scratch@ STFD
|
||||||
dst 1 4 param@ LWZ ;
|
dst 1 4 scratch@ LWZ ;
|
||||||
|
|
||||||
M: ppc %copy ( dst src -- ) MR ;
|
M: ppc %copy ( dst src -- ) MR ;
|
||||||
|
|
||||||
|
@ -218,6 +246,10 @@ M: ppc %copy-float ( dst src -- ) FMR ;
|
||||||
|
|
||||||
M: ppc %unbox-float ( dst src -- ) float-offset LFD ;
|
M: ppc %unbox-float ( dst src -- ) float-offset LFD ;
|
||||||
|
|
||||||
|
M:: ppc %box-float ( dst src temp -- )
|
||||||
|
dst 16 float temp %allot
|
||||||
|
src dst float-offset STFD ;
|
||||||
|
|
||||||
M:: ppc %unbox-any-c-ptr ( dst src temp -- )
|
M:: ppc %unbox-any-c-ptr ( dst src temp -- )
|
||||||
[
|
[
|
||||||
{ "is-byte-array" "end" "start" } [ define-label ] each
|
{ "is-byte-array" "end" "start" } [ define-label ] each
|
||||||
|
@ -349,11 +381,6 @@ M: ppc %gc
|
||||||
"end" resolve-label ;
|
"end" resolve-label ;
|
||||||
|
|
||||||
M: ppc %prologue ( n -- )
|
M: ppc %prologue ( n -- )
|
||||||
#! We use a volatile register (r11) here for scratch. Because
|
|
||||||
#! callback bodies have a prologue too, we cannot assume
|
|
||||||
#! that c_to_factor saved all non-volatile registers, so
|
|
||||||
#! we have to respect the C calling convention. Also, we
|
|
||||||
#! cannot touch any param-regs either.
|
|
||||||
0 11 LOAD32 rc-absolute-ppc-2/2 rel-this
|
0 11 LOAD32 rc-absolute-ppc-2/2 rel-this
|
||||||
0 MFLR
|
0 MFLR
|
||||||
1 1 pick neg ADDI
|
1 1 pick neg ADDI
|
||||||
|
@ -410,32 +437,11 @@ M: ppc %compare-branch (%compare) %branch ;
|
||||||
M: ppc %compare-imm-branch (%compare-imm) %branch ;
|
M: ppc %compare-imm-branch (%compare-imm) %branch ;
|
||||||
M: ppc %compare-float-branch (%compare-float) %branch ;
|
M: ppc %compare-float-branch (%compare-float) %branch ;
|
||||||
|
|
||||||
: spill-integer-base ( stack-frame -- n )
|
M: ppc %spill-integer ( src n -- ) spill-integer@ 1 swap STW ;
|
||||||
[ params>> ] [ return>> ] bi + ;
|
M: ppc %reload-integer ( dst n -- ) spill-integer@ 1 swap LWZ ;
|
||||||
|
|
||||||
: stack@ 1 swap ; inline
|
M: ppc %spill-float ( src n -- ) spill-float@ 1 swap STFD ;
|
||||||
|
M: ppc %reload-float ( dst n -- ) spill-float@ 1 swap LFD ;
|
||||||
: spill-integer@ ( n -- reg offset )
|
|
||||||
cells
|
|
||||||
stack-frame get spill-integer-base
|
|
||||||
+ stack@ ;
|
|
||||||
|
|
||||||
: spill-float-base ( stack-frame -- n )
|
|
||||||
[ spill-counts>> int-regs swap at int-regs reg-size * ]
|
|
||||||
[ params>> ]
|
|
||||||
[ return>> ]
|
|
||||||
tri + + ;
|
|
||||||
|
|
||||||
: spill-float@ ( n -- reg offset )
|
|
||||||
double-float-regs reg-size *
|
|
||||||
stack-frame get spill-float-base
|
|
||||||
+ stack@ ;
|
|
||||||
|
|
||||||
M: ppc %spill-integer ( src n -- ) spill-integer@ STW ;
|
|
||||||
M: ppc %reload-integer ( dst n -- ) spill-integer@ LWZ ;
|
|
||||||
|
|
||||||
M: ppc %spill-float ( src n -- ) spill-float@ STFD ;
|
|
||||||
M: ppc %reload-float ( dst n -- ) spill-float@ LFD ;
|
|
||||||
|
|
||||||
M: ppc %loop-entry ;
|
M: ppc %loop-entry ;
|
||||||
|
|
||||||
|
|
|
@ -29,5 +29,5 @@ IN: io.unix.launcher.parser
|
||||||
|
|
||||||
PEG: tokenize-command ( command -- ast/f )
|
PEG: tokenize-command ( command -- ast/f )
|
||||||
'argument' " " token repeat1 list-of
|
'argument' " " token repeat1 list-of
|
||||||
" " token repeat0 swap over pack
|
" " token repeat0 tuck pack
|
||||||
just ;
|
just ;
|
||||||
|
|
|
@ -487,7 +487,7 @@ M: ebnf-terminal (transform) ( ast -- parser )
|
||||||
M: ebnf-foreign (transform) ( ast -- parser )
|
M: ebnf-foreign (transform) ( ast -- parser )
|
||||||
dup word>> search
|
dup word>> search
|
||||||
[ "Foreign word '" swap word>> append "' not found" append throw ] unless*
|
[ "Foreign word '" swap word>> append "' not found" append throw ] unless*
|
||||||
swap rule>> [ main ] unless* dupd swap rule [
|
swap rule>> [ main ] unless* over rule [
|
||||||
nip
|
nip
|
||||||
] [
|
] [
|
||||||
execute
|
execute
|
||||||
|
|
|
@ -16,7 +16,7 @@ HELP: standard-combination
|
||||||
{ $examples
|
{ $examples
|
||||||
"A generic word for append strings and characters to a sequence, dispatching on the object underneath the top of the stack:"
|
"A generic word for append strings and characters to a sequence, dispatching on the object underneath the top of the stack:"
|
||||||
{ $code
|
{ $code
|
||||||
"G: build-string 1 standard-combination ;"
|
"GENERIC# build-string 1 ( elt str -- )"
|
||||||
"M: string build-string swap push-all ;"
|
"M: string build-string swap push-all ;"
|
||||||
"M: integer build-string push ;"
|
"M: integer build-string push ;"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
USING: project-euler.215 tools.test ;
|
||||||
|
IN: project-euler.215.tests
|
||||||
|
|
||||||
|
[ 8 ] [ 9 3 solve ] unit-test
|
||||||
|
[ 806844323190414 ] [ euler215 ] unit-test
|
|
@ -0,0 +1,56 @@
|
||||||
|
USING: accessors kernel locals math ;
|
||||||
|
IN: project-euler.215
|
||||||
|
|
||||||
|
TUPLE: block two three ;
|
||||||
|
TUPLE: end { ways integer } ;
|
||||||
|
|
||||||
|
C: <block> block
|
||||||
|
C: <end> end
|
||||||
|
: <failure> 0 <end> ; inline
|
||||||
|
: <success> 1 <end> ; inline
|
||||||
|
|
||||||
|
: failure? ( t -- ? ) ways>> 0 = ; inline
|
||||||
|
|
||||||
|
: choice ( t p q -- t t ) [ [ two>> ] [ three>> ] bi ] 2dip bi* ; inline
|
||||||
|
|
||||||
|
GENERIC: merge ( t t -- t )
|
||||||
|
GENERIC# block-merge 1 ( t t -- t )
|
||||||
|
GENERIC# end-merge 1 ( t t -- t )
|
||||||
|
M: block merge block-merge ;
|
||||||
|
M: end merge end-merge ;
|
||||||
|
M: block block-merge [ [ two>> ] bi@ merge ]
|
||||||
|
[ [ three>> ] bi@ merge ] 2bi <block> ;
|
||||||
|
M: end block-merge nip ;
|
||||||
|
M: block end-merge drop ;
|
||||||
|
M: end end-merge [ ways>> ] bi@ + <end> ;
|
||||||
|
|
||||||
|
GENERIC: h-1 ( t -- t )
|
||||||
|
GENERIC: h0 ( t -- t )
|
||||||
|
GENERIC: h1 ( t -- t )
|
||||||
|
GENERIC: h2 ( t -- t )
|
||||||
|
|
||||||
|
M: block h-1 [ h1 ] [ h2 ] choice merge ;
|
||||||
|
M: block h0 drop <failure> ;
|
||||||
|
M: block h1 [ [ h1 ] [ h2 ] choice merge ]
|
||||||
|
[ [ h0 ] [ h1 ] choice merge ] bi <block> ;
|
||||||
|
M: block h2 [ h1 ] [ h2 ] choice merge <failure> swap <block> ;
|
||||||
|
|
||||||
|
M: end h-1 drop <failure> ;
|
||||||
|
M: end h0 ;
|
||||||
|
M: end h1 drop <failure> ;
|
||||||
|
M: end h2 dup failure? [ <failure> <block> ] unless ;
|
||||||
|
|
||||||
|
: next-row ( t -- t ) [ h-1 ] [ h1 ] choice swap <block> ;
|
||||||
|
|
||||||
|
: first-row ( n -- t )
|
||||||
|
[ <failure> <success> <failure> ] dip
|
||||||
|
1- [| a b c | b c <block> a b ] times 2drop ;
|
||||||
|
|
||||||
|
GENERIC: total ( t -- n )
|
||||||
|
M: block total [ total ] dup choice + ;
|
||||||
|
M: end total ways>> ;
|
||||||
|
|
||||||
|
: solve ( width height -- ways )
|
||||||
|
[ first-row ] dip 1- [ next-row ] times total ;
|
||||||
|
|
||||||
|
: euler215 ( -- ways ) 32 10 solve ;
|
Loading…
Reference in New Issue