--- /dev/null
+#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
acklibrary {
name = "lib_"..plat,
srcs = {
- "./*.s",
+ "./*.s", -- zer.s
"./*.e",
},
vars = { plat = plat },
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
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 */
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"}
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 */
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
-
/* 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"}
bl {LABEL, ".inn"}
-
/* Boolean resolutions */
pat teq /* top = (top == 0) */
leaving
cmi INT32
+ pat cms defined($1)
+ with STACK
+ kills ALL
+ gen
+ move {CONST, $1}, R3
+ bl {LABEL, ".cms"}
+ yields R3