2005-03-14 13:20:57 -05:00
|
|
|
! Copyright (C) 2005 Slava Pestov.
|
|
|
|
! See http://factor.sf.net/license.txt for BSD license.
|
2005-05-24 01:26:45 -04:00
|
|
|
IN: compiler-backend
|
|
|
|
USING: assembler compiler inference kernel kernel-internals
|
2005-05-30 03:37:22 -04:00
|
|
|
lists math memory namespaces words ;
|
2005-05-24 01:26:45 -04:00
|
|
|
|
|
|
|
! PowerPC register assignments
|
|
|
|
! r14 data stack
|
|
|
|
! r15 call stack
|
2005-05-30 00:21:17 -04:00
|
|
|
! r16-r30 vregs
|
2005-05-24 01:26:45 -04:00
|
|
|
|
|
|
|
M: integer v>operand tag-bits shift ;
|
2005-05-30 00:21:17 -04:00
|
|
|
M: vreg v>operand vreg-n 17 + ;
|
2005-03-14 13:20:57 -05:00
|
|
|
|
2005-05-24 01:26:45 -04:00
|
|
|
M: %prologue generate-node ( vop -- )
|
2005-03-15 18:18:33 -05:00
|
|
|
drop
|
2005-03-19 20:37:25 -05:00
|
|
|
1 1 -16 STWU
|
2005-03-15 18:18:33 -05:00
|
|
|
0 MFLR
|
2005-05-24 01:26:45 -04:00
|
|
|
0 1 20 STW ;
|
2005-03-15 18:18:33 -05:00
|
|
|
|
2005-03-17 23:29:08 -05:00
|
|
|
: compile-epilogue
|
2005-05-28 20:52:23 -04:00
|
|
|
#! At the end of each word that calls a subroutine, we store
|
|
|
|
#! the previous link register value in r0 by popping it off
|
|
|
|
#! the stack, set the link register to the contents of r0,
|
|
|
|
#! and jump to the link register.
|
2005-03-19 20:37:25 -05:00
|
|
|
0 1 20 LWZ
|
|
|
|
1 1 16 ADDI
|
2005-03-17 23:29:08 -05:00
|
|
|
0 MTLR ;
|
|
|
|
|
2005-05-28 20:52:23 -04:00
|
|
|
M: %call-label generate-node ( vop -- )
|
|
|
|
#! Near calling convention for inlined recursive combinators
|
|
|
|
#! Note: length of instruction sequence is hard-coded.
|
|
|
|
vop-label
|
2005-05-13 18:27:18 -04:00
|
|
|
0 1 rel-address compiled-offset 20 + 18 LOAD32
|
2005-03-21 20:53:26 -05:00
|
|
|
1 1 -16 STWU
|
|
|
|
18 1 20 STW
|
2005-05-24 01:26:45 -04:00
|
|
|
B ;
|
|
|
|
|
2005-05-28 20:52:23 -04:00
|
|
|
: word-addr ( word -- )
|
|
|
|
dup 0 1 rel-primitive word-xt 19 LOAD32 ;
|
2005-05-24 01:26:45 -04:00
|
|
|
|
2005-05-28 20:52:23 -04:00
|
|
|
: compile-call ( label -- )
|
|
|
|
#! Far C call for primitives, near C call for compiled defs.
|
|
|
|
dup primitive? [ word-addr 19 MTLR BLRL ] [ BL ] ifte ;
|
2005-03-21 20:53:26 -05:00
|
|
|
|
2005-05-28 20:52:23 -04:00
|
|
|
M: %call generate-node ( vop -- )
|
|
|
|
vop-label dup postpone-word compile-call ;
|
2005-03-19 00:30:49 -05:00
|
|
|
|
2005-05-28 20:52:23 -04:00
|
|
|
: compile-jump ( label -- )
|
|
|
|
#! For tail calls. IP not saved on C stack.
|
|
|
|
dup primitive? [ word-addr 19 MTCTR BCTR ] [ B ] ifte ;
|
2005-03-19 00:30:49 -05:00
|
|
|
|
2005-05-24 01:26:45 -04:00
|
|
|
M: %jump generate-node ( vop -- )
|
2005-05-28 20:52:23 -04:00
|
|
|
vop-label dup postpone-word compile-epilogue compile-jump ;
|
2005-05-24 01:26:45 -04:00
|
|
|
|
|
|
|
M: %jump-label generate-node ( vop -- )
|
2005-05-28 20:52:23 -04:00
|
|
|
vop-label B ;
|
2005-03-17 23:29:08 -05:00
|
|
|
|
2005-05-24 01:26:45 -04:00
|
|
|
: conditional ( vop -- label )
|
|
|
|
dup vop-in-1 v>operand 0 swap f address CMPI vop-label ;
|
2005-03-19 00:30:49 -05:00
|
|
|
|
2005-05-24 01:26:45 -04:00
|
|
|
M: %jump-f generate-node ( vop -- )
|
|
|
|
conditional BEQ ;
|
2005-03-19 21:23:21 -05:00
|
|
|
|
2005-05-24 01:26:45 -04:00
|
|
|
M: %jump-t generate-node ( vop -- )
|
|
|
|
conditional BNE ;
|
|
|
|
|
|
|
|
M: %return-to generate-node ( vop -- )
|
|
|
|
vop-label 0 18 LOAD32 absolute-16/16
|
|
|
|
1 1 -16 STWU
|
|
|
|
18 1 20 STW ;
|
|
|
|
|
|
|
|
M: %return generate-node ( vop -- )
|
|
|
|
drop compile-epilogue BLR ;
|
|
|
|
|
2005-05-28 20:52:23 -04:00
|
|
|
M: %untag generate-node ( vop -- )
|
|
|
|
dest/src 0 0 28 RLWINM ;
|
|
|
|
|
2005-05-30 02:19:54 -04:00
|
|
|
M: %untag-fixnum generate-node ( vop -- )
|
|
|
|
dest/src tag-bits SRAWI ;
|
|
|
|
|
2005-05-30 03:37:22 -04:00
|
|
|
M: %tag-fixnum generate-node ( vop -- )
|
|
|
|
! todo: formalize scratch register usage
|
|
|
|
3 19 LI
|
|
|
|
dest/src 19 SLW ;
|
|
|
|
|
2005-05-24 01:26:45 -04:00
|
|
|
M: %dispatch generate-node ( vop -- )
|
2005-05-30 03:37:22 -04:00
|
|
|
0 <vreg> check-src
|
2005-05-30 02:19:54 -04:00
|
|
|
2 18 LI
|
|
|
|
17 17 18 SLW
|
2005-03-19 21:23:21 -05:00
|
|
|
! The value 24 is a magic number. It is the length of the
|
|
|
|
! instruction sequence that follows to be generated.
|
2005-05-30 02:19:54 -04:00
|
|
|
0 1 rel-address compiled-offset 24 + 18 LOAD32
|
|
|
|
17 17 18 ADD
|
|
|
|
17 17 0 LWZ
|
|
|
|
17 MTLR
|
2005-05-24 01:26:45 -04:00
|
|
|
BLR ;
|
2005-05-30 03:37:22 -04:00
|
|
|
|
|
|
|
M: %arithmetic-type generate-node ( vop -- )
|
|
|
|
0 <vreg> check-dest
|
|
|
|
<label> "end" set
|
|
|
|
! Load top two stack values
|
|
|
|
17 14 -4 LWZ
|
|
|
|
18 14 0 LWZ
|
|
|
|
! Compute their tags
|
|
|
|
17 17 tag-mask ANDI
|
|
|
|
18 18 tag-mask ANDI
|
|
|
|
! Are the tags equal?
|
|
|
|
0 17 18 CMPL
|
|
|
|
"end" get BEQ
|
|
|
|
! No, they are not equal. Call a runtime function to
|
|
|
|
! coerce the integers to a higher type.
|
|
|
|
"arithmetic_type" f compile-c-call
|
|
|
|
"end" get save-xt ;
|