Add Modula-2 set operations to PowerPC ncg.
authorGeorge Koehler <xkernigh@netscape.net>
Sat, 10 Dec 2016 17:23:07 +0000 (12:23 -0500)
committerGeorge Koehler <xkernigh@netscape.net>
Sat, 10 Dec 2016 17:23:07 +0000 (12:23 -0500)
This provides and, ior, xor, com, zer, set, cms when defined($1) and
ior, set when !defined($1).  I don't provide the other operations
!defined($1) because our Modula-2 compiler hasn't used them.

I wrote a Modula-2 example in
https://gist.github.com/kernigh/add79662bb3c63ffb7c46d01dc8ae788

Put a dummy comment in mach/powerpc/libem/build.lua so git checkout
will touch that file.  Without the touch, the build system doesn't see
the new *.s files.

mach/powerpc/libem/and.s [new file with mode: 0644]
mach/powerpc/libem/build.lua
mach/powerpc/libem/cms.s [new file with mode: 0644]
mach/powerpc/libem/com.s [new file with mode: 0644]
mach/powerpc/libem/ior.s [new file with mode: 0644]
mach/powerpc/libem/set.s [new file with mode: 0644]
mach/powerpc/libem/xor.s [new file with mode: 0644]
mach/powerpc/libem/zer.s [new file with mode: 0644]
mach/powerpc/ncg/table

diff --git a/mach/powerpc/libem/and.s b/mach/powerpc/libem/and.s
new file mode 100644 (file)
index 0000000..4a1a81c
--- /dev/null
@@ -0,0 +1,24 @@
+#include "powerpc.h"
+
+.sect .text
+
+! Set intersection.
+!  Stack: ( b a -- a*b )
+!  With r3 = size of set
+
+.define .and
+.and:
+       mr      r4, sp                  ! r4 = ptr to set a
+       add     r5, sp, r3              ! r5 = ptr to set b
+       rlwinm  r6, r3, 30, 2, 31
+       mtspr   ctr, r6                 ! ctr = r3 / 4
+1:
+       lwz     r7, 0(r4)
+       lwz     r8, 0(r5)
+       and     r8, r7, r8              ! intersection of words
+       stw     r8, 0(r5)
+       addi    r4, r4, 4
+       addi    r5, r5, 4
+       bc      DNZ, 0, 1b              ! loop ctr times
+       add     sp, sp, r3
+       bclr    ALWAYS, 0, 0
index 318be38..786be4e 100644 (file)
@@ -7,7 +7,7 @@ for _, plat in ipairs(vars.plats) do
        acklibrary {
                name = "lib_"..plat,
                srcs = {
-                       "./*.s",
+                       "./*.s", -- zer.s
                        "./*.e",
                },
                vars = { plat = plat },
diff --git a/mach/powerpc/libem/cms.s b/mach/powerpc/libem/cms.s
new file mode 100644 (file)
index 0000000..53cb656
--- /dev/null
@@ -0,0 +1,32 @@
+#include "powerpc.h"
+
+.sect .text
+
+! Compare sets a, b.
+!  Stack: ( b a -- )
+!  With r3 = size of each set
+!  Yields r3 = 0 if equal, nonzero if not equal
+
+.define .cms
+.cms:
+       mr      r4, sp                  ! r4 = ptr to set a
+       add     r5, sp, r3              ! r5 = ptr to set b
+       mr      r6, r3                  ! r6 = size
+       rlwinm  r3, r3, 30, 2, 31
+       mtspr   ctr, r3                 ! ctr = size / 4
+1:
+       lwz     r7, 0(r4)
+       lwz     r8, 0(r5)
+       cmp     cr0, 0, r7, r8          ! compare words in sets
+       addi    r4, r4, 4
+       addi    r5, r5, 4
+       bc      IFFALSE, EQ, 2f         ! branch if not equal
+       bc      DNZ, 0, 1b              ! loop ctr times
+       addi    r3, r0, 0               ! equal: return 0
+       b       3f
+2:
+       addi    r3, r0, 1               ! not equal: return 1
+3:
+       rlwinm  r6, r6, 1, 0, 30        ! r6 = size * 2
+       add     sp, sp, r6              ! remove sets from stack
+       bclr    ALWAYS, 0, 0
diff --git a/mach/powerpc/libem/com.s b/mach/powerpc/libem/com.s
new file mode 100644 (file)
index 0000000..8b70823
--- /dev/null
@@ -0,0 +1,20 @@
+#include "powerpc.h"
+
+.sect .text
+
+! Set complement.
+!  Stack: ( a -- ~a )
+!  With r3 = size of set
+
+.define .com
+.com:
+       mr      r4, sp                  ! r4 = pointer to set a
+       rlwinm  r5, r3, 30, 2, 31
+       mtspr   ctr, r5                 ! ctr = r3 / 4
+1:
+       lwz     r6, 0(r4)
+       nor     r6, r6, r6              ! complement of word
+       stw     r6, 0(r4)
+       addi    r4, r4, 4
+       bc      DNZ, 0, 1b              ! loop ctr times
+       bclr    ALWAYS, 0, 0
diff --git a/mach/powerpc/libem/ior.s b/mach/powerpc/libem/ior.s
new file mode 100644 (file)
index 0000000..61e0999
--- /dev/null
@@ -0,0 +1,24 @@
+#include "powerpc.h"
+
+.sect .text
+
+! Set union.
+!  Stack: ( b a -- a+b )
+!  With r3 = size of set
+
+.define .ior
+.ior:
+       mr      r4, sp                  ! r4 = ptr to set a
+       add     r5, sp, r3              ! r5 = ptr to set b
+       rlwinm  r6, r3, 30, 2, 31
+       mtspr   ctr, r6                 ! ctr = r3 / 4
+1:
+       lwz     r7, 0(r4)
+       lwz     r8, 0(r5)
+       or      r8, r7, r8              ! union of words
+       stw     r8, 0(r5)
+       addi    r4, r4, 4
+       addi    r5, r5, 4
+       bc      DNZ, 0, 1b              ! loop ctr times
+       add     sp, sp, r3
+       bclr    ALWAYS, 0, 0
diff --git a/mach/powerpc/libem/set.s b/mach/powerpc/libem/set.s
new file mode 100644 (file)
index 0000000..18ad877
--- /dev/null
@@ -0,0 +1,29 @@
+#include "powerpc.h"
+
+.sect .text
+
+! Create singleton set.
+!  Stack: ( -- set )
+!  With r3 = size of set, r4 = bit number
+
+.define .set
+.set:
+       rlwinm  r7, r3, 30, 2, 31
+       neg     r5, r3
+       add     sp, sp, r5              ! allocate set
+       mr      r6, sp                  ! r6 = ptr to set
+       mtspr   ctr, r7                 ! ctr = r3 / 4
+1:
+       rlwinm. r7, r4, 0, 0, 26        ! r7 = r4 & ~31
+       bc      IFTRUE, EQ, 2f          ! branch if r4 in 0..31
+       addi    r5, r0, 0               ! no bit, word is zero
+       b       3f
+2:
+       addi    r5, r0, 1
+       slw     r5, r5, r4              ! yes bit, set bit in word
+3:
+       stw     r5, 0(r6)               ! store word in set
+       addi    r4, r4, -32
+       addi    r6, r6, 4
+       bc      DNZ, 0, 1b              ! loop ctr times
+       bclr    ALWAYS, 0, 0
diff --git a/mach/powerpc/libem/xor.s b/mach/powerpc/libem/xor.s
new file mode 100644 (file)
index 0000000..9d4bc76
--- /dev/null
@@ -0,0 +1,24 @@
+#include "powerpc.h"
+
+.sect .text
+
+! Set symmetric difference.
+!  Stack: ( b a -- a/b )
+!  With r3 = size of set
+
+.define .xor
+.xor:
+       mr      r4, sp                  ! r4 = ptr to set a
+       add     r5, sp, r3              ! r5 = ptr to set b
+       rlwinm  r6, r3, 30, 2, 31
+       mtspr   ctr, r6                 ! ctr = r3 / 4
+1:
+       lwz     r7, 0(r4)
+       lwz     r8, 0(r5)
+       xor     r8, r7, r8              ! symmetric difference of words
+       stw     r8, 0(r5)
+       addi    r4, r4, 4
+       addi    r5, r5, 4
+       bc      DNZ, 0, 1b              ! loop ctr times
+       add     sp, sp, r3
+       bclr    ALWAYS, 0, 0
diff --git a/mach/powerpc/libem/zer.s b/mach/powerpc/libem/zer.s
new file mode 100644 (file)
index 0000000..ba978ba
--- /dev/null
@@ -0,0 +1,21 @@
+#include "powerpc.h"
+
+.sect .text
+
+! Create empty set.
+!  Stack: ( -- set )
+!  With r3 = size of set
+
+.define .zer
+.zer:
+       rlwinm  r7, r3, 30, 2, 31
+       addi    r4, r0, 0               ! r4 = zero
+       neg     r5, r3
+       add     sp, sp, r5              ! allocate set
+       mr      r6, sp                  ! r6 = ptr to set
+       mtspr   ctr, r7                 ! ctr = r3 / 4
+1:
+       stw     r4, 0(r6)               ! store zero in set
+       addi    r6, r6, 4
+       bc      DNZ, 0, 1b              ! loop ctr times
+       bclr    ALWAYS, 0, 0
index a6859ca..adb0db2 100644 (file)
@@ -1463,9 +1463,11 @@ PATTERNS
                                andisX %a, %2, {CONST, hi(%1.val)}
                        yields %a
 
-       pat and !defined($1)               /* AND set */
+       pat and defined($1)                /* AND set */
                with STACK
+                       kills ALL
                        gen
+                               move {CONST, $1}, R3
                                bl {LABEL, ".and"}
 
        pat ior $1==4                      /* OR word */
@@ -1498,8 +1500,17 @@ PATTERNS
                        uses reusing %2, REG={OR_RIS, %2, hi(%1.val)}
                        yields {OR_RC, %2, lo(%1.val)}
 
-       pat ior !defined($1)               /* OR set */
+       pat ior defined($1)                /* OR set */
                with STACK
+                       kills ALL
+                       gen
+                               move {CONST, $1}, R3
+                               bl {LABEL, ".ior"}
+
+       /* OR set (variable), used in lang/m2/libm2/LtoUset.e */
+       pat ior !defined($1)
+               with GPR3 STACK
+                       kills ALL
                        gen
                                bl {LABEL, ".ior"}
 
@@ -1523,9 +1534,11 @@ PATTERNS
                        uses reusing %2, REG={XOR_RIS, %2, hi(%1.val)}
                        yields {XOR_RC, %2, lo(%1.val)}
 
-       pat xor !defined($1)               /* XOR set */
+       pat xor defined($1)                /* XOR set */
                with STACK
+                       kills ALL
                        gen
+                               move {CONST, $1}, R3
                                bl {LABEL, ".xor"}
 
        pat com $1==INT32                  /* NOT word */
@@ -1547,11 +1560,23 @@ PATTERNS
                with GPR
                        yields {NOT_R, %1}
 
-       pat com !defined($1)               /* NOT set */
+       pat com defined($1)                /* NOT set */
                with STACK
                        gen
+                               move {CONST, $1}, R3
                                bl {LABEL, ".com"}
 
+       pat zer $1==4                      /* Push zero */
+               leaving
+                       loc 0
+
+       pat zer defined($1)                /* Create empty set */
+               with STACK
+                       kills ALL
+                       gen
+                               move {CONST, $1}, R3
+                               bl {LABEL, ".zer"}
+
        pat sli $1==4                      /* Shift left (second << top) */
                with CONST_ALL GPR
                        uses reusing %2, REG
@@ -1625,17 +1650,19 @@ PATTERNS
 
 
 
-
 /* Sets */
 
-       pat set defined($1)                /* Create word with set bit */
-               leaving
-                       loc 1
-                       exg INT32
-                       sli INT32
+       pat set defined($1)                /* Create singleton set */
+               with GPR4 STACK
+                       kills ALL
+                       gen
+                               move {CONST, $1}, R3
+                               bl {LABEL, ".set"}
 
-       pat set !defined($1)               /* Create structure with set bit (variable) */
+       /* Create set (variable), used in lang/m2/libm2/LtoUset.e */
+       pat set !defined($1)
                with GPR3 GPR4 STACK
+                       kills ALL
                        gen
                                bl {LABEL, ".set"}
 
@@ -1649,7 +1676,6 @@ PATTERNS
                                bl {LABEL, ".inn"}
 
 
-
 /* Boolean resolutions */
 
        pat teq                            /* top = (top == 0) */
@@ -1806,6 +1832,13 @@ PATTERNS
                leaving
                        cmi INT32
 
+       pat cms defined($1)
+               with STACK
+                       kills ALL
+                       gen
+                               move {CONST, $1}, R3
+                               bl {LABEL, ".cms"}
+                       yields R3