factor/library/compiler/ppc/generator.factor

115 lines
3.3 KiB
Factor
Raw Normal View History

2005-03-14 13:20:57 -05:00
! Copyright (C) 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
IN: compiler-backend
2005-05-30 21:10:08 -04:00
USING: alien assembler compiler inference kernel
kernel-internals lists math memory namespaces words ;
2005-05-30 21:10:08 -04:00
: compile-c-call ( symbol dll -- )
2005-09-05 20:33:36 -04:00
2dup dlsym 11 LOAD32 0 1 rel-dlsym 11 MTLR BLRL ;
2005-05-30 21:10:08 -04:00
: stack-increment \ stack-reserve get stack@ 16 align ;
M: %prologue generate-node ( vop -- )
drop
1 1 stack-increment neg STWU
0 MFLR
0 1 stack-increment lr@ STW ;
: compile-epilogue
#! 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.
0 1 stack-increment lr@ LWZ
1 1 stack-increment ADDI
0 MTLR ;
M: %call-label generate-node ( vop -- )
#! Near calling convention for inlined recursive combinators
#! Note: length of instruction sequence is hard-coded.
vop-label
2005-10-11 21:46:14 -04:00
compiled-offset 20 + 18 LOAD32 0 1 rel-address
1 1 stack-increment neg STWU
18 1 stack-increment lr@ STW
B ;
: word-addr ( word -- )
#! Load a word address into r3.
dup word-xt 3 LOAD32 0 1 rel-word ;
: compile-call ( label -- )
#! Far C call for primitives, near C call for compiled defs.
2005-09-24 15:21:17 -04:00
dup primitive? [ word-addr 3 MTLR BLRL ] [ BL ] if ;
2005-03-21 20:53:26 -05:00
M: %call generate-node ( vop -- )
vop-label dup postpone-word compile-call ;
2005-03-19 00:30:49 -05:00
: compile-jump ( label -- )
#! For tail calls. IP not saved on C stack.
2005-09-24 15:21:17 -04:00
dup primitive? [ word-addr 3 MTCTR BCTR ] [ B ] if ;
2005-03-19 00:30:49 -05:00
M: %jump generate-node ( vop -- )
vop-label dup postpone-word compile-epilogue compile-jump ;
M: %jump-label generate-node ( vop -- )
vop-label B ;
M: %jump-t generate-node ( vop -- )
dup 0 vop-in v>operand 0 swap f address CMPI vop-label BNE ;
M: %return-to generate-node ( vop -- )
vop-label 0 3 LOAD32 absolute-16/16
1 1 stack-increment neg STWU
3 1 stack-increment lr@ STW ;
M: %return generate-node ( vop -- )
drop compile-epilogue BLR ;
2005-06-05 02:43:05 -04:00
: untag ( dest src -- ) 0 0 31 tag-bits - RLWINM ;
M: %untag generate-node ( vop -- )
dest/src untag ;
2005-09-05 17:14:15 -04:00
: tag-fixnum ( src dest -- ) tag-bits SLWI ;
M: %dispatch generate-node ( vop -- )
2005-05-30 03:37:22 -04:00
0 <vreg> check-src
3 3 1 SRAWI
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-10-11 21:46:14 -04:00
compiled-offset 24 + 4 LOAD32 0 1 rel-address
3 3 4 ADD
3 3 0 LWZ
3 MTLR
BLR ;
2005-05-30 03:37:22 -04:00
2005-05-30 21:10:08 -04:00
M: %type generate-node ( vop -- )
0 <vreg> check-src
<label> "f" set
<label> "end" set
! Get the tag
3 5 tag-mask ANDI
! Tag the tag
5 4 tag-fixnum
2005-05-30 21:10:08 -04:00
! Compare with object tag number (3).
0 5 object-tag CMPI
2005-05-30 21:10:08 -04:00
! Jump if the object doesn't store type info in its header
"end" get BNE
! It does store type info in its header
! Is the pointer itself equal to 3? Then its F_TYPE (9).
0 3 object-tag CMPI
2005-05-30 21:10:08 -04:00
"f" get BEQ
! The pointer is not equal to 3. Load the object header.
4 3 object-tag neg LWZ
4 4 untag
2005-05-30 21:10:08 -04:00
"end" get B
"f" get save-xt
! The pointer is equal to 3. Load F_TYPE (9).
f type tag-bits shift 4 LI
2005-05-30 21:10:08 -04:00
"end" get save-xt
3 4 MR ;
M: %tag generate-node ( vop -- )
dup 0 vop-in v>operand swap 0 vop-out v>operand
[ tag-mask ANDI ] keep dup tag-fixnum ;