aboutsummaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorCyril SIX <cyril.six@kalray.eu>2018-05-21 16:34:36 +0200
committerCyril SIX <cyril.six@kalray.eu>2018-05-21 16:39:48 +0200
commit479aacd0254605942a3f48c3b8053af4d07f0f6c (patch)
tree7ddbddf078b86a30e693ae35721e08f54a0af11e /runtime
parentb81dbb863781a5f450cad0b01f90f729fb1a2244 (diff)
downloadcompcert-kvx-479aacd0254605942a3f48c3b8053af4d07f0f6c.tar.gz
compcert-kvx-479aacd0254605942a3f48c3b8053af4d07f0f6c.zip
MPPA - Added modulo and division 64 bits. Non certified
32 bits version are not yet there. Right now the code is directly from libgcc, compiled with k1-gcc because of builtins.
Diffstat (limited to 'runtime')
-rw-r--r--runtime/Makefile5
-rw-r--r--runtime/mppa_k1c/Makefile8
-rw-r--r--runtime/mppa_k1c/i32_udivmod.S187
-rw-r--r--runtime/mppa_k1c/i32_udivmod.c89
-rw-r--r--runtime/mppa_k1c/i64_sdiv.S50
-rw-r--r--runtime/mppa_k1c/i64_sdiv.c29
-rw-r--r--runtime/mppa_k1c/i64_smod.S46
-rw-r--r--runtime/mppa_k1c/i64_smod.c25
-rw-r--r--runtime/mppa_k1c/i64_udiv.S11
-rw-r--r--runtime/mppa_k1c/i64_udiv.c9
-rw-r--r--runtime/mppa_k1c/i64_udivmod.S58
-rw-r--r--runtime/mppa_k1c/i64_udivmod.c58
-rw-r--r--runtime/mppa_k1c/i64_umod.S11
-rw-r--r--runtime/mppa_k1c/i64_umod.c9
14 files changed, 595 insertions, 0 deletions
diff --git a/runtime/Makefile b/runtime/Makefile
index 27ad6e8c..0d130ca2 100644
--- a/runtime/Makefile
+++ b/runtime/Makefile
@@ -22,6 +22,8 @@ ifeq ($(ARCH),x86_64)
OBJS=i64_dtou.o i64_utod.o i64_utof.o vararg.o
else ifeq ($(ARCH),powerpc64)
OBJS=i64_dtou.o i64_stof.o i64_utod.o i64_utof.o vararg.o
+else ifeq ($(ARCH),mppa_k1c)
+OBJS=i64_umod.o i64_udiv.o i64_udivmod.o i64_sdiv.o i64_smod.o
else
OBJS=i64_dtos.o i64_dtou.o i64_sar.o i64_sdiv.o i64_shl.o \
i64_shr.o i64_smod.o i64_stod.o i64_stof.o \
@@ -40,6 +42,9 @@ VPATH=$(ARCH)
ifeq ($(strip $(HAS_RUNTIME_LIB)),true)
all: $(LIB)
+ifeq ($(ARCH),mppa_k1c)
+ (cd mppa_k1c && make)
+endif
else
all:
endif
diff --git a/runtime/mppa_k1c/Makefile b/runtime/mppa_k1c/Makefile
new file mode 100644
index 00000000..d447d35b
--- /dev/null
+++ b/runtime/mppa_k1c/Makefile
@@ -0,0 +1,8 @@
+CFILES=$(wildcard *.c)
+SFILES=$(subst .c,.s,$(CFILES))
+
+all: $(SFILES)
+
+.SECONDARY:
+%.S: %.c
+ k1-gcc -O2 -S $< -o $@
diff --git a/runtime/mppa_k1c/i32_udivmod.S b/runtime/mppa_k1c/i32_udivmod.S
new file mode 100644
index 00000000..b2923024
--- /dev/null
+++ b/runtime/mppa_k1c/i32_udivmod.S
@@ -0,0 +1,187 @@
+ .text
+
+ .align 8
+ .type udivmodsi4, @function
+udivmodsi4:
+ zxwd $r0 = $r0
+ ;; /* Can't issue next in the same bundle */
+ zxwd $r1 = $r1
+ ;; /* Can't issue next in the same bundle */
+ sxwd $r2 = $r2
+ make $r4 = 0
+ ;;
+ compw.ltu $r3 = $r0, $r1
+ ;;
+ cb.weqz $r3? .L14
+ ;;
+.L2:
+ cmoved.deqz $r2? $r0 = $r4
+ ret
+ ;;
+.L14:
+ clzw $r3 = $r1
+ clzw $r5 = $r0
+ ;;
+ sbfw $r5 = $r5, $r3
+ ;;
+ sllw $r1 = $r1,$r5
+ zxwd $r3 = $r5
+ ;;
+ compw.ltu $r6 = $r0, $r1
+ ;;
+ cb.wnez $r6? .L3
+ ;;
+ make $r4 = 1
+ sbfw $r0 = $r1, $r0
+ ;;
+ sllw $r4 = $r4,$r5
+ ;;
+ zxwd $r4 = $r4
+ ;;
+.L3:
+ cb.deqz $r3? .L2
+ ;;
+ srlw $r1 = $r1,1
+ copyd $r3 = $r5
+ ;;
+ loopgtz $r3, .L15
+ ;;
+.L4:
+ stsuw $r0 = $r1, $r0
+ ;;
+ zxwd $r0 = $r0
+ ;;
+.L15:
+ # HW loop end
+ ;;
+ srlw $r1 = $r0,$r5
+ addw $r4 = $r0, $r4
+ ;;
+ sllw $r5 = $r1,$r5
+ zxwd $r0 = $r1
+ ;;
+ sbfw $r4 = $r5, $r4
+ ;;
+ cmoved.deqz $r2? $r0 = $r4
+ ret
+ ;;
+ .size udivmodsi4, .-udivmodsi4
+
+ .align 8
+ .globl __udivsi3
+ .type __udivsi3, @function
+__udivsi3:
+ make $r2 = 0
+ goto udivmodsi4
+ ;;
+ .size __udivsi3, .-__udivsi3
+
+ .align 8
+ .globl __umodsi3
+ .type __umodsi3, @function
+__umodsi3:
+ make $r2 = 1
+ goto udivmodsi4
+ ;;
+ .size __umodsi3, .-__umodsi3
+
+ .align 8
+ .globl __divsi3
+ .type __divsi3, @function
+__divsi3:
+ addw $r12 = $r12, -16
+ get $r8 = $ra
+ sxwd $r0 = $r0
+ ;;
+ sxwd $r1 = $r1
+ sd 20[$r12] = $r10
+ make $r10 = 0
+ ;;
+ sw 16[$r12] = $r8
+ ;;
+ cb.wltz $r0? .L22
+ ;;
+ cb.wltz $r1? .L23
+ ;;
+.L20:
+ make $r2 = 0
+ call udivmodsi4
+ ;;
+ lwz $r8 = 16[$r12]
+ negw $r1 = $r10
+ ;;
+ xorw $r0 = $r1, $r0
+ ;;
+ addw $r0 = $r0, $r10
+ ld $r10 = 20[$r12]
+ addw $r12 = $r12, 16
+ ;;
+ set $ra = $r8
+ ;; /* Can't issue next in the same bundle */
+ ret
+ ;;
+.L22:
+ negw $r0 = $r0
+ make $r10 = 1
+ ;;
+ sxwd $r0 = $r0
+ ;; /* Can't issue next in the same bundle */
+ cb.wgez $r1? .L20
+ ;;
+.L23:
+ negw $r1 = $r1
+ xorw $r10 = $r10, 1
+ ;;
+ sxwd $r1 = $r1
+ sxwd $r10 = $r10
+ goto .L20
+ ;;
+ .size __divsi3, .-__divsi3
+
+ .align 8
+ .globl __modsi3
+ .type __modsi3, @function
+__modsi3:
+ addw $r12 = $r12, -24
+ get $r8 = $ra
+ sxwd $r0 = $r0
+ ;;
+ sd 16[$r12] = $r15
+ make $r15 = 0
+ sxwd $r1 = $r1
+ ;;
+ sd 28[$r12] = $r10
+ copyd $r10 = $r15
+ ;;
+ sw 24[$r12] = $r8
+ ;;
+ cb.wltz $r0? .L27
+ ;;
+.L25:
+ absw $r1 = $r1
+ make $r2 = 1
+ call udivmodsi4
+ ;;
+ lwz $r8 = 24[$r12]
+ xorw $r0 = $r0, $r10
+ ;;
+ addw $r0 = $r0, $r15
+ ld $r10 = 28[$r12]
+ ;;
+ ld $r15 = 16[$r12]
+ addw $r12 = $r12, 24
+ ;;
+ set $ra = $r8
+ ;; /* Can't issue next in the same bundle */
+ ret
+ ;;
+.L27:
+ negw $r2 = $r0
+ make $r15 = 1
+ make $r10 = -1
+ ;;
+ sxwd $r0 = $r2
+ goto .L25
+ ;;
+ .size __modsi3, .-__modsi3
+ .ident "GCC: (GNU) 4.9.4"
diff --git a/runtime/mppa_k1c/i32_udivmod.c b/runtime/mppa_k1c/i32_udivmod.c
new file mode 100644
index 00000000..e66496af
--- /dev/null
+++ b/runtime/mppa_k1c/i32_udivmod.c
@@ -0,0 +1,89 @@
+
+static unsigned int
+udivmodsi4(unsigned int num, unsigned int den, int modwanted)
+{
+ unsigned r = num, q = 0;
+
+ if(den <= r) {
+ unsigned k = __builtin_k1_clz (den) - __builtin_k1_clz (r);
+ den = den << k;
+ if(r >= den) {
+ r = r - den;
+ q = 1 << k;
+ }
+ if(k != 0) {
+ unsigned i = k;
+ den = den >> 1;
+ do {
+ r = __builtin_k1_stsu (den, r);
+ i--;
+ } while (i!= 0);
+ q = q + r;
+ r = r >> k;
+ q = q - (r << k);
+ }
+ }
+
+ return modwanted ? r : q;
+}
+
+unsigned int
+__udivsi3 (unsigned int a, unsigned int b)
+{
+ return udivmodsi4 (a, b, 0);
+}
+
+unsigned int
+__umodsi3 (unsigned int a, unsigned int b)
+{
+ return udivmodsi4 (a, b, 1);
+}
+
+int
+__divsi3 (int a, int b)
+{
+ int neg = 0;
+ int res;
+
+ if (a < 0)
+ {
+ a = -a;
+ neg = !neg;
+ }
+
+ if (b < 0)
+ {
+ b = -b;
+ neg = !neg;
+ }
+
+ res = udivmodsi4 (a, b, 0);
+
+ if (neg)
+ res = -res;
+
+ return res;
+}
+
+int
+__modsi3 (int a, int b)
+{
+ int neg = 0;
+ int res;
+
+ if (a < 0)
+ {
+ a = -a;
+ neg = 1;
+ }
+
+ if (b < 0)
+ b = -b;
+
+ res = udivmodsi4 (a, b, 1);
+
+ if (neg)
+ res = -res;
+
+ return res;
+}
diff --git a/runtime/mppa_k1c/i64_sdiv.S b/runtime/mppa_k1c/i64_sdiv.S
new file mode 100644
index 00000000..6cc712ee
--- /dev/null
+++ b/runtime/mppa_k1c/i64_sdiv.S
@@ -0,0 +1,50 @@
+ .text
+
+ .align 8
+ .globl __compcert_i64_sdiv
+ .type __compcert_i64_sdiv, @function
+__compcert_i64_sdiv:
+ addw $r12 = $r12, -16
+ get $r8 = $ra
+ ;;
+ sd 20[$r12] = $r10
+ make $r10 = 0
+ ;;
+ sw 16[$r12] = $r8
+ ;;
+ cb.dltz $r0? .L6
+ ;;
+ cb.dltz $r1? .L7
+ ;;
+.L3:
+ make $r2 = 0
+ call udivmoddi4
+ ;;
+ lwz $r8 = 16[$r12]
+ negd $r1 = $r10
+ ;;
+ xord $r0 = $r1, $r0
+ ;;
+ addd $r0 = $r0, $r10
+ ld $r10 = 20[$r12]
+ addw $r12 = $r12, 16
+ ;;
+ set $ra = $r8
+ ;; /* Can't issue next in the same bundle */
+ ret
+ ;;
+.L6:
+ negd $r0 = $r0
+ make $r10 = 1
+ ;; /* Can't issue next in the same bundle */
+ cb.dgez $r1? .L3
+ ;;
+.L7:
+ xorw $r10 = $r10, 1
+ negd $r1 = $r1
+ ;;
+ sxwd $r10 = $r10
+ goto .L3
+ ;;
+ .size __compcert_i64_sdiv, .-__compcert_i64_sdiv
+ .ident "GCC: (GNU) 4.9.4"
diff --git a/runtime/mppa_k1c/i64_sdiv.c b/runtime/mppa_k1c/i64_sdiv.c
new file mode 100644
index 00000000..97b3cd2f
--- /dev/null
+++ b/runtime/mppa_k1c/i64_sdiv.c
@@ -0,0 +1,29 @@
+unsigned long long
+udivmoddi4(unsigned long long num, unsigned long long den, int modwanted);
+
+long long
+__compcert_i64_sdiv (long long a, long long b)
+{
+ int neg = 0;
+ long long res;
+
+ if (a < 0)
+ {
+ a = -a;
+ neg = !neg;
+ }
+
+ if (b < 0)
+ {
+ b = -b;
+ neg = !neg;
+ }
+
+ res = udivmoddi4 (a, b, 0);
+
+ if (neg)
+ res = -res;
+
+ return res;
+}
+
diff --git a/runtime/mppa_k1c/i64_smod.S b/runtime/mppa_k1c/i64_smod.S
new file mode 100644
index 00000000..9a62b63d
--- /dev/null
+++ b/runtime/mppa_k1c/i64_smod.S
@@ -0,0 +1,46 @@
+ .text
+
+ .align 8
+ .globl __compcert_i64_smod
+ .type __compcert_i64_smod, @function
+__compcert_i64_smod:
+ addw $r12 = $r12, -24
+ get $r8 = $ra
+ ;;
+ sd 16[$r12] = $r15
+ make $r15 = 0
+ ;;
+ sd 28[$r12] = $r10
+ copyd $r10 = $r15
+ ;;
+ sw 24[$r12] = $r8
+ ;;
+ cb.dltz $r0? .L5
+ ;;
+.L2:
+ absd $r1 = $r1
+ ;; /* Can't issue next in the same bundle */
+ make $r2 = 1
+ call udivmoddi4
+ ;;
+ lwz $r8 = 24[$r12]
+ xord $r0 = $r0, $r10
+ ;;
+ addd $r0 = $r15, $r0
+ ld $r10 = 28[$r12]
+ ;;
+ ld $r15 = 16[$r12]
+ addw $r12 = $r12, 24
+ ;;
+ set $ra = $r8
+ ;; /* Can't issue next in the same bundle */
+ ret
+ ;;
+.L5:
+ negd $r0 = $r0
+ make $r15 = 1
+ make $r10 = -1
+ goto .L2
+ ;;
+ .size __compcert_i64_smod, .-__compcert_i64_smod
+ .ident "GCC: (GNU) 4.9.4"
diff --git a/runtime/mppa_k1c/i64_smod.c b/runtime/mppa_k1c/i64_smod.c
new file mode 100644
index 00000000..d48f9e19
--- /dev/null
+++ b/runtime/mppa_k1c/i64_smod.c
@@ -0,0 +1,25 @@
+unsigned long long
+udivmoddi4(unsigned long long num, unsigned long long den, int modwanted);
+
+long long
+__compcert_i64_smod (long long a, long long b)
+{
+ int neg = 0;
+ long long res;
+
+ if (a < 0)
+ {
+ a = -a;
+ neg = 1;
+ }
+
+ if (b < 0)
+ b = -b;
+
+ res = udivmoddi4 (a, b, 1);
+
+ if (neg)
+ res = -res;
+
+ return res;
+}
diff --git a/runtime/mppa_k1c/i64_udiv.S b/runtime/mppa_k1c/i64_udiv.S
new file mode 100644
index 00000000..f5f50ce7
--- /dev/null
+++ b/runtime/mppa_k1c/i64_udiv.S
@@ -0,0 +1,11 @@
+ .text
+
+ .align 8
+ .globl __compcert_i64_udiv
+ .type __compcert_i64_udiv, @function
+__compcert_i64_udiv:
+ make $r2 = 0
+ goto udivmoddi4
+ ;;
+ .size __compcert_i64_udiv, .-__compcert_i64_udiv
+ .ident "GCC: (GNU) 4.9.4"
diff --git a/runtime/mppa_k1c/i64_udiv.c b/runtime/mppa_k1c/i64_udiv.c
new file mode 100644
index 00000000..2838f21b
--- /dev/null
+++ b/runtime/mppa_k1c/i64_udiv.c
@@ -0,0 +1,9 @@
+unsigned long long
+udivmoddi4(unsigned long long num, unsigned long long den, int modwanted);
+
+unsigned long long
+__compcert_i64_udiv (unsigned long long a, unsigned long long b)
+{
+ return udivmoddi4 (a, b, 0);
+}
+
diff --git a/runtime/mppa_k1c/i64_udivmod.S b/runtime/mppa_k1c/i64_udivmod.S
new file mode 100644
index 00000000..cdb0e978
--- /dev/null
+++ b/runtime/mppa_k1c/i64_udivmod.S
@@ -0,0 +1,58 @@
+ .text
+
+ .align 8
+ .globl udivmoddi4
+ .type udivmoddi4, @function
+udivmoddi4:
+ compd.ltu $r3 = $r0, $r1
+ ;; /* Can't issue next in the same bundle */
+ sxwd $r2 = $r2
+ make $r5 = 0
+ ;;
+ cb.dnez $r3? .L2
+ ;;
+ clzd $r3 = $r1
+ ;; /* Can't issue next in the same bundle */
+ clzd $r4 = $r0
+ ;;
+ sbfw $r4 = $r4, $r3
+ ;;
+ slld $r1 = $r1,$r4
+ zxwd $r3 = $r4
+ ;;
+ compd.ltu $r6 = $r0, $r1
+ ;;
+ cb.dnez $r6? .L3
+ ;;
+ make $r5 = 1
+ sbfd $r0 = $r1, $r0
+ ;;
+ slld $r5 = $r5,$r4
+ ;;
+.L3:
+ cb.deqz $r3? .L2
+ ;;
+ srld $r1 = $r1,1
+ copyd $r3 = $r4
+ ;;
+ loopgtz $r3, .L14
+ ;;
+.L4:
+ stsud $r0 = $r1, $r0
+ ;;
+.L14:
+ # HW loop end
+ ;;
+ addd $r5 = $r0, $r5
+ srld $r0 = $r0,$r4
+ ;;
+ slld $r4 = $r0,$r4
+ ;;
+ sbfd $r5 = $r4, $r5
+ ;;
+.L2:
+ cmoved.deqz $r2? $r0 = $r5
+ ret
+ ;;
+ .size udivmoddi4, .-udivmoddi4
+ .ident "GCC: (GNU) 4.9.4"
diff --git a/runtime/mppa_k1c/i64_udivmod.c b/runtime/mppa_k1c/i64_udivmod.c
new file mode 100644
index 00000000..20d8c976
--- /dev/null
+++ b/runtime/mppa_k1c/i64_udivmod.c
@@ -0,0 +1,58 @@
+#ifdef __K1_TINYK1__
+unsigned long long
+udivmoddi4(unsigned long long num, unsigned long long den, int modwanted)
+{
+ unsigned long long bit = 1;
+ unsigned long long res = 0;
+
+ while (den < num && bit && !(den & (1L<<31)))
+ {
+ den <<=1;
+ bit <<=1;
+ }
+ while (bit)
+ {
+ if (num >= den)
+ {
+ num -= den;
+ res |= bit;
+ }
+ bit >>=1;
+ den >>=1;
+ }
+ if (modwanted) return num;
+ return res;
+}
+
+#else
+
+/* THIS IS THE PREVIOUS VERSION, USED ON BOSTAN AND ANDEY */
+unsigned long long
+udivmoddi4(unsigned long long num, unsigned long long den, int modwanted)
+{
+ unsigned long long r = num, q = 0;
+
+ if(den <= r) {
+ unsigned k = __builtin_clzll (den) - __builtin_clzll (r);
+ den = den << k;
+ if(r >= den) {
+ r = r - den;
+ q = 1LL << k;
+ }
+ if(k != 0) {
+ unsigned i = k;
+ den = den >> 1;
+ do {
+ r = __builtin_k1_stsud (den, r);
+ i--;
+ } while (i!= 0);
+ q = q + r;
+ r = r >> k;
+ q = q - (r << k);
+ }
+ }
+
+ return modwanted ? r : q;
+}
+#endif /* __K1_TINYK1__ */
+
diff --git a/runtime/mppa_k1c/i64_umod.S b/runtime/mppa_k1c/i64_umod.S
new file mode 100644
index 00000000..63cfafc2
--- /dev/null
+++ b/runtime/mppa_k1c/i64_umod.S
@@ -0,0 +1,11 @@
+ .text
+
+ .align 8
+ .globl __compcert_i64_umod
+ .type __compcert_i64_umod, @function
+__compcert_i64_umod:
+ make $r2 = 1
+ goto udivmoddi4
+ ;;
+ .size __compcert_i64_umod, .-__compcert_i64_umod
+ .ident "GCC: (GNU) 4.9.4"
diff --git a/runtime/mppa_k1c/i64_umod.c b/runtime/mppa_k1c/i64_umod.c
new file mode 100644
index 00000000..41d985a6
--- /dev/null
+++ b/runtime/mppa_k1c/i64_umod.c
@@ -0,0 +1,9 @@
+unsigned long long
+udivmoddi4(unsigned long long num, unsigned long long den, int modwanted);
+
+unsigned long long
+__compcert_i64_umod (unsigned long long a, unsigned long long b)
+{
+ return udivmoddi4 (a, b, 1);
+}
+