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
|
2005-05-30 21:10:08 -04:00
|
|
|
USING: alien assembler compiler inference kernel
|
|
|
|
kernel-internals lists math memory namespaces words ;
|
2005-05-24 01:26:45 -04:00
|
|
|
|
2005-11-12 00:37:24 -05:00
|
|
|
: compile-dlsym ( symbol dll register -- )
|
2005-12-11 15:14:41 -05:00
|
|
|
>r 2dup dlsym r> LOAD32 rel-2-2 rel-dlsym ;
|
2005-11-12 00:37:24 -05:00
|
|
|
|
2005-05-30 21:10:08 -04:00
|
|
|
: compile-c-call ( symbol dll -- )
|
2005-11-12 00:37:24 -05:00
|
|
|
11 [ compile-dlsym ] keep MTLR BLRL ;
|
2005-05-30 21:10:08 -04:00
|
|
|
|
2005-10-23 22:31:01 -04:00
|
|
|
: stack-increment \ stack-reserve get 32 max stack@ 16 align ;
|
2005-10-18 20:19:10 -04:00
|
|
|
|
2005-05-24 01:26:45 -04:00
|
|
|
M: %prologue generate-node ( vop -- )
|
2005-03-15 18:18:33 -05:00
|
|
|
drop
|
2005-10-18 20:19:10 -04:00
|
|
|
1 1 stack-increment neg STWU
|
2005-03-15 18:18:33 -05:00
|
|
|
0 MFLR
|
2005-10-18 20:19:10 -04:00
|
|
|
0 1 stack-increment lr@ 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-10-18 20:19:10 -04:00
|
|
|
0 1 stack-increment lr@ LWZ
|
|
|
|
1 1 stack-increment 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-12-11 15:14:41 -05:00
|
|
|
compiled-offset 20 + 18 LOAD32 rel-2/2 rel-address
|
2005-10-18 20:19:10 -04:00
|
|
|
1 1 stack-increment neg STWU
|
2005-10-18 20:35:41 -04:00
|
|
|
18 1 stack-increment lr@ STW
|
2005-05-24 01:26:45 -04:00
|
|
|
B ;
|
|
|
|
|
2005-05-28 20:52:23 -04:00
|
|
|
: word-addr ( word -- )
|
2005-09-04 20:23:18 -04:00
|
|
|
#! Load a word address into r3.
|
2005-12-11 15:14:41 -05:00
|
|
|
dup word-xt 3 LOAD32 rel-2/2 rel-word ;
|
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.
|
2005-12-06 22:39:05 -05:00
|
|
|
dup postpone-word
|
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
|
|
|
|
2005-05-28 20:52:23 -04:00
|
|
|
M: %call generate-node ( vop -- )
|
2005-12-06 22:39:05 -05:00
|
|
|
vop-label 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.
|
2005-12-06 22:39:05 -05:00
|
|
|
dup postpone-word
|
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
|
|
|
|
2005-05-24 01:26:45 -04:00
|
|
|
M: %jump generate-node ( vop -- )
|
2005-12-07 21:46:54 -05:00
|
|
|
drop label compile-epilogue compile-jump ;
|
2005-05-24 01:26:45 -04:00
|
|
|
|
|
|
|
M: %jump-label generate-node ( vop -- )
|
2005-12-07 21:46:54 -05:00
|
|
|
drop label B ;
|
2005-03-17 23:29:08 -05:00
|
|
|
|
2005-05-24 01:26:45 -04:00
|
|
|
M: %jump-t generate-node ( vop -- )
|
2005-12-07 21:46:54 -05:00
|
|
|
drop 0 input-operand 0 swap f address CMPI vop-label BNE ;
|
2005-05-24 01:26:45 -04:00
|
|
|
|
|
|
|
M: %return-to generate-node ( vop -- )
|
2005-12-09 00:02:41 -05:00
|
|
|
drop label 0 3 LOAD32 absolute-2/2
|
2005-10-18 20:35:41 -04:00
|
|
|
1 1 stack-increment neg STWU
|
|
|
|
3 1 stack-increment lr@ STW ;
|
2005-05-24 01:26:45 -04:00
|
|
|
|
|
|
|
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 ;
|
2005-06-01 14:06:25 -04:00
|
|
|
|
2005-05-28 20:52:23 -04:00
|
|
|
M: %untag generate-node ( vop -- )
|
2005-12-07 21:46:54 -05:00
|
|
|
drop dest/src untag ;
|
2005-05-28 20:52:23 -04:00
|
|
|
|
2005-09-05 17:14:15 -04:00
|
|
|
: tag-fixnum ( src dest -- ) tag-bits SLWI ;
|
2005-06-03 00:47:00 -04:00
|
|
|
|
2005-11-13 22:04:14 -05:00
|
|
|
: untag-fixnum ( src dest -- ) tag-bits SRAWI ;
|
|
|
|
|
2005-05-24 01:26:45 -04:00
|
|
|
M: %dispatch generate-node ( vop -- )
|
2005-12-07 21:46:54 -05:00
|
|
|
drop
|
|
|
|
0 input-operand dup 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-12-11 15:14:41 -05:00
|
|
|
compiled-offset 24 + 0 scratch LOAD32 rel-2/2 rel-address
|
2005-12-07 21:46:54 -05:00
|
|
|
0 input-operand dup 0 scratch ADD
|
|
|
|
0 input-operand dup 0 LWZ
|
|
|
|
0 input-operand MTLR
|
2005-05-24 01:26:45 -04:00
|
|
|
BLR ;
|
2005-05-30 03:37:22 -04:00
|
|
|
|
2005-05-30 21:10:08 -04:00
|
|
|
M: %type generate-node ( vop -- )
|
2005-12-07 21:46:54 -05:00
|
|
|
drop
|
2005-05-30 21:10:08 -04:00
|
|
|
<label> "f" set
|
|
|
|
<label> "end" set
|
|
|
|
! Get the tag
|
2005-12-07 21:46:54 -05:00
|
|
|
0 input-operand 1 scratch tag-mask ANDI
|
2005-09-23 18:41:26 -04:00
|
|
|
! Tag the tag
|
2005-12-07 21:46:54 -05:00
|
|
|
1 scratch 0 scratch tag-fixnum
|
2005-05-30 21:10:08 -04:00
|
|
|
! Compare with object tag number (3).
|
2005-12-07 21:46:54 -05:00
|
|
|
0 1 scratch 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).
|
2005-12-07 21:46:54 -05:00
|
|
|
0 0 input-operand 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.
|
2005-12-07 21:46:54 -05:00
|
|
|
0 scratch 0 input-operand object-tag neg LWZ
|
|
|
|
0 scratch dup 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).
|
2005-12-07 21:46:54 -05:00
|
|
|
f type tag-bits shift 0 scratch LI
|
2005-05-30 21:10:08 -04:00
|
|
|
"end" get save-xt
|
2005-12-07 21:46:54 -05:00
|
|
|
0 output-operand 0 scratch MR ;
|
2005-08-15 15:34:00 -04:00
|
|
|
|
|
|
|
M: %tag generate-node ( vop -- )
|
2005-12-07 21:46:54 -05:00
|
|
|
drop dest/src swap tag-mask ANDI
|
|
|
|
0 output-operand dup tag-fixnum ;
|