From 8605a2fcfc0439aeb92f75a66664a9fa885e5000 Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sat, 10 Dec 2016 12:23:07 -0500 Subject: [PATCH] Add Modula-2 set operations to PowerPC ncg. 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 | 24 +++++++++++++++ mach/powerpc/libem/build.lua | 2 +- mach/powerpc/libem/cms.s | 32 ++++++++++++++++++++ mach/powerpc/libem/com.s | 20 +++++++++++++ mach/powerpc/libem/ior.s | 24 +++++++++++++++ mach/powerpc/libem/set.s | 29 ++++++++++++++++++ mach/powerpc/libem/xor.s | 24 +++++++++++++++ mach/powerpc/libem/zer.s | 21 +++++++++++++ mach/powerpc/ncg/table | 57 ++++++++++++++++++++++++++++-------- 9 files changed, 220 insertions(+), 13 deletions(-) create mode 100644 mach/powerpc/libem/and.s create mode 100644 mach/powerpc/libem/cms.s create mode 100644 mach/powerpc/libem/com.s create mode 100644 mach/powerpc/libem/ior.s create mode 100644 mach/powerpc/libem/set.s create mode 100644 mach/powerpc/libem/xor.s create mode 100644 mach/powerpc/libem/zer.s diff --git a/mach/powerpc/libem/and.s b/mach/powerpc/libem/and.s new file mode 100644 index 000000000..4a1a81c04 --- /dev/null +++ b/mach/powerpc/libem/and.s @@ -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 diff --git a/mach/powerpc/libem/build.lua b/mach/powerpc/libem/build.lua index 318be381d..786be4e11 100644 --- a/mach/powerpc/libem/build.lua +++ b/mach/powerpc/libem/build.lua @@ -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 index 000000000..53cb65691 --- /dev/null +++ b/mach/powerpc/libem/cms.s @@ -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 index 000000000..8b7082332 --- /dev/null +++ b/mach/powerpc/libem/com.s @@ -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 index 000000000..61e099934 --- /dev/null +++ b/mach/powerpc/libem/ior.s @@ -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 index 000000000..18ad877e8 --- /dev/null +++ b/mach/powerpc/libem/set.s @@ -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 index 000000000..9d4bc76b9 --- /dev/null +++ b/mach/powerpc/libem/xor.s @@ -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 index 000000000..ba978ba3e --- /dev/null +++ b/mach/powerpc/libem/zer.s @@ -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 diff --git a/mach/powerpc/ncg/table b/mach/powerpc/ncg/table index a6859ca14..adb0db2c8 100644 --- a/mach/powerpc/ncg/table +++ b/mach/powerpc/ncg/table @@ -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 -- 2.34.1