From 639da2d33541ae7b7ac0b49e5205d61e440e00be Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@slava-pestovs-macbook-pro.local>
Date: Fri, 7 Nov 2008 20:45:25 -0600
Subject: [PATCH] Refactor OS-specific parts of PowerPC backend

---
 basis/cpu/ppc/linux/linux.factor   |  19 ++++
 basis/cpu/ppc/linux/tags.txt       |   1 +
 basis/cpu/ppc/macosx/macosx.factor |  20 ++++
 basis/cpu/ppc/macosx/tags.txt      |   1 +
 basis/cpu/ppc/ppc.factor           | 144 +++++++++++------------------
 5 files changed, 95 insertions(+), 90 deletions(-)
 create mode 100644 basis/cpu/ppc/linux/linux.factor
 create mode 100644 basis/cpu/ppc/linux/tags.txt
 create mode 100644 basis/cpu/ppc/macosx/macosx.factor
 create mode 100644 basis/cpu/ppc/macosx/tags.txt

diff --git a/basis/cpu/ppc/linux/linux.factor b/basis/cpu/ppc/linux/linux.factor
new file mode 100644
index 0000000000..d92709a399
--- /dev/null
+++ b/basis/cpu/ppc/linux/linux.factor
@@ -0,0 +1,19 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors system kernel alien.c-types cpu.architecture cpu.ppc ;
+IN: cpu.ppc.linux
+
+<<
+t "longlong" c-type (>>stack-align?)
+t "ulonglong" c-type (>>stack-align?)
+>>
+
+M: linux reserved-area-size 2 ;
+
+M: linux lr-save 1 ;
+
+M: float-regs param-regs { 1 2 3 4 5 6 7 8 } ;
+
+M: ppc value-structs? drop f ;
+
+M: ppc fp-shadows-int? drop f ;
diff --git a/basis/cpu/ppc/linux/tags.txt b/basis/cpu/ppc/linux/tags.txt
new file mode 100644
index 0000000000..6bf68304bb
--- /dev/null
+++ b/basis/cpu/ppc/linux/tags.txt
@@ -0,0 +1 @@
+unportable
diff --git a/basis/cpu/ppc/macosx/macosx.factor b/basis/cpu/ppc/macosx/macosx.factor
new file mode 100644
index 0000000000..1e0a6caca0
--- /dev/null
+++ b/basis/cpu/ppc/macosx/macosx.factor
@@ -0,0 +1,20 @@
+! Copyright (C) 2008 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors system kernel alien.c-types cpu.architecture cpu.ppc ;
+IN: cpu.ppc.macosx
+
+<<
+4 "longlong" c-type (>>align)
+4 "ulonglong" c-type (>>align)
+4 "double" c-type (>>align)
+>>
+
+M: macosx reserved-area-size 6 ;
+
+M: macosx lr-save 2 ;
+
+M: float-regs param-regs { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ;
+
+M: ppc value-structs? drop t ;
+
+M: ppc fp-shadows-int? drop t ;
diff --git a/basis/cpu/ppc/macosx/tags.txt b/basis/cpu/ppc/macosx/tags.txt
new file mode 100644
index 0000000000..6bf68304bb
--- /dev/null
+++ b/basis/cpu/ppc/macosx/tags.txt
@@ -0,0 +1 @@
+unportable
diff --git a/basis/cpu/ppc/ppc.factor b/basis/cpu/ppc/ppc.factor
index b60fd47b89..d2d1e26396 100644
--- a/basis/cpu/ppc/ppc.factor
+++ b/basis/cpu/ppc/ppc.factor
@@ -4,8 +4,7 @@ USING: accessors assocs sequences kernel combinators make math
 math.order math.ranges system namespaces locals layouts words
 alien alien.c-types cpu.architecture cpu.ppc.assembler
 compiler.cfg.registers compiler.cfg.instructions
-compiler.constants compiler.codegen compiler.codegen.fixup
-compiler.cfg.intrinsics compiler.cfg.stack-frame ;
+compiler.constants compiler.codegen compiler.codegen.fixup ;
 IN: cpu.ppc
 
 ! PowerPC register assignments:
@@ -16,31 +15,15 @@ IN: cpu.ppc
 ! f0-f29: float vregs
 ! f30, f31: float scratch
 
-<< {
-    { [ os macosx? ] [
-        4 "longlong" c-type (>>align)
-        4 "ulonglong" c-type (>>align)
-        4 "double" c-type (>>align)
-    ] }
-    { [ os linux? ] [
-        t "longlong" c-type (>>stack-align?)
-        t "ulonglong" c-type (>>stack-align?)
-    ] }
-} cond
-
-enable-float-intrinsics
-
-\ ##integer>float t frame-required? set-word-prop
-\ ##float>integer t frame-required? set-word-prop >>
-
 M: ppc machine-registers
     {
         { int-regs T{ range f 2 26 1 } }
-        { double-float-regs T{ range f 0 29 1 } }
+        { double-float-regs T{ range f 0 28 1 } }
     } ;
 
 : scratch-reg 28 ; inline
-: fp-scratch-reg 30 ; inline
+: fp-scratch-reg-1 29 ; inline
+: fp-scratch-reg-2 30 ; inline
 
 M: ppc two-operand? f ;
 
@@ -70,21 +53,9 @@ M: ppc %replace loc>operand STW ;
 M: ppc %inc-d ( n -- ) ds-reg (%inc) ;
 M: ppc %inc-r ( n -- ) rs-reg (%inc) ;
 
-: reserved-area-size ( -- n )
-    os {
-        { linux [ 2 ] }
-        { macosx [ 6 ] }
-    } case cells ; foldable
+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-save-size ( -- n ) 8 cells ; foldable
@@ -92,38 +63,19 @@ M: ppc %inc-r ( n -- ) rs-reg (%inc) ;
 : local@ ( n -- x )
     reserved-area-size param-save-size + + ; inline
 
-: spill-integer-base ( -- n )
-    stack-frame get spill-counts>> double-float-regs swap at
-    double-float-regs reg-size * ;
+: factor-area-size ( -- n ) 2 cells ; foldable
 
-: spill-integer@ ( n -- offset )
-    cells spill-integer-base + param@ ;
+: next-save ( n -- i ) cell - ;
 
-: 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
-: lr-save ( -- n )
-    os {
-        { linux [ 1 ] }
-        { macosx [ 2 ] }
-    } case cells ; foldable
+: xt-save ( n -- i ) 2 cells - ;
 
 M: ppc stack-frame-size ( stack-frame -- i )
     [ spill-counts>> [ swap reg-size * ] { } assoc>map sum ]
     [ params>> ]
     [ return>> ]
     tri + +
-    param-save-size +
     reserved-area-size +
+    param-save-size +
     factor-area-size +
     4 cells align ;
 
@@ -246,19 +198,19 @@ M: ppc %div-float FDIV ;
 
 M:: ppc %integer>float ( dst src -- )
     HEX: 4330 scratch-reg LIS
-    scratch-reg 1 0 scratch@ STW
+    scratch-reg 1 0 param@ STW
     scratch-reg src MR
     scratch-reg dup HEX: 8000 XORIS
-    scratch-reg 1 4 scratch@ STW
-    dst 1 0 scratch@ LFD
+    scratch-reg 1 cell param@ STW
+    fp-scratch-reg-2 1 0 param@ LFD
     scratch-reg 4503601774854144.0 %load-indirect
-    fp-scratch-reg scratch-reg float-offset LFD
-    dst dst fp-scratch-reg FSUB ;
+    fp-scratch-reg-2 scratch-reg float-offset LFD
+    fp-scratch-reg-2 fp-scratch-reg-2 fp-scratch-reg-2 FSUB ;
 
 M:: ppc %float>integer ( dst src -- )
-    fp-scratch-reg src FCTIWZ
-    fp-scratch-reg 1 0 scratch@ STFD
-    dst 1 4 scratch@ LWZ ;
+    fp-scratch-reg-1 src FCTIWZ
+    fp-scratch-reg-2 1 0 param@ STFD
+    dst 1 4 param@ LWZ ;
 
 M: ppc %copy ( dst src -- ) MR ;
 
@@ -266,10 +218,6 @@ M: ppc %copy-float ( dst src -- ) FMR ;
 
 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 -- )
     [
         { "is-byte-array" "end" "start" } [ define-label ] each
@@ -401,12 +349,12 @@ M: ppc %gc
     "end" resolve-label ;
 
 M: ppc %prologue ( n -- )
-    0 11 LOAD32 rc-absolute-ppc-2/2 rel-this
+    0 scratch-reg LOAD32 rc-absolute-ppc-2/2 rel-this
     0 MFLR
     1 1 pick neg ADDI
-    11 1 pick xt-save STW
-    dup 11 LI
-    11 1 pick next-save STW
+    scratch-reg 1 pick xt-save STW
+    dup scratch-reg LI
+    scratch-reg 1 pick next-save STW
     0 1 rot lr-save + STW ;
 
 M: ppc %epilogue ( n -- )
@@ -457,22 +405,38 @@ M: ppc %compare-branch (%compare) %branch ;
 M: ppc %compare-imm-branch (%compare-imm) %branch ;
 M: ppc %compare-float-branch (%compare-float) %branch ;
 
-M: ppc %spill-integer ( src n -- ) spill-integer@ 1 swap STW ;
-M: ppc %reload-integer ( dst n -- ) spill-integer@ 1 swap LWZ ;
+: spill-integer-base ( stack-frame -- n )
+    [ params>> ] [ return>> ] bi + ;
 
-M: ppc %spill-float ( src n -- ) spill-float@ 1 swap STFD ;
-M: ppc %reload-float ( dst n -- ) spill-float@ 1 swap LFD ;
+: stack@ 1 swap ; inline
+
+: 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: int-regs return-reg drop 3 ;
 M: int-regs param-regs drop { 3 4 5 6 7 8 9 10 } ;
 M: float-regs return-reg drop 1 ;
-M: float-regs param-regs 
-    drop os H{
-        { macosx { 1 2 3 4 5 6 7 8 9 10 11 12 13 } }
-        { linux { 1 2 3 4 5 6 7 8 } }
-    } at ;
 
 M: int-regs %save-param-reg drop 1 rot local@ STW ;
 M: int-regs %load-param-reg drop 1 rot local@ LWZ ;
@@ -595,13 +559,6 @@ M: ppc %callback-value ( ctype -- )
     ! Unbox former top of data stack to return registers
     unbox-return ;
 
-M: ppc value-structs?
-    #! On Linux/PPC, value structs are passed in the same way
-    #! as reference structs, we just have to make a copy first.
-    os linux? not ;
-
-M: ppc fp-shadows-int? ( -- ? ) os macosx? ;
-
 M: ppc small-enough? ( n -- ? ) -32768 32767 between? ;
 
 M: ppc struct-small-enough? ( size -- ? ) drop f ;
@@ -611,3 +568,10 @@ M: ppc %box-small-struct
 
 M: ppc %unbox-small-struct
     drop "No small structs" throw ;
+
+USE: vocabs.loader
+
+{
+    { [ os macosx? ] [ "cpu.ppc.macosx" require ] }
+    { [ os linux? ] [ "cpu.ppc.linux" require ] }
+} cond