aboutsummaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorDavid Monniaux <david.monniaux@univ-grenoble-alpes.fr>2019-05-21 15:32:45 +0200
committerDavid Monniaux <david.monniaux@univ-grenoble-alpes.fr>2019-05-21 15:32:45 +0200
commitb0ec7472890babc8c439984d75c14f2b4486416a (patch)
tree4cd65ccb63d454204470c58bc81c7fd1ba7e00a7 /runtime
parent6e331ae1185694e1ca542db00445968c107c26b9 (diff)
downloadcompcert-kvx-b0ec7472890babc8c439984d75c14f2b4486416a.tar.gz
compcert-kvx-b0ec7472890babc8c439984d75c14f2b4486416a.zip
new routines for 32-bit division
Diffstat (limited to 'runtime')
-rw-r--r--runtime/Makefile5
-rw-r--r--runtime/mppa_k1c/i32_divmod.S120
-rw-r--r--runtime/mppa_k1c/i64_sdiv.c2
3 files changed, 122 insertions, 5 deletions
diff --git a/runtime/Makefile b/runtime/Makefile
index 1258d941..2448279e 100644
--- a/runtime/Makefile
+++ b/runtime/Makefile
@@ -23,9 +23,8 @@ 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 vararg.o\
- i64_dtos.o i64_dtou.o i64_utod.o i64_utof.o i64_stod.o i64_stof.o\
- i64_shl.o i64_shr.o
+OBJS=i64_umod.o i64_udiv.o i64_udivmod.o i64_sdiv.o i64_smod.o i32_divmod.o \
+ vararg.o
# Missing: i64_utod.o i64_utof.o i64_stod.o i64_stof.o
DOMAKE:=$(shell (cd mppa_k1c && make))
else
diff --git a/runtime/mppa_k1c/i32_divmod.S b/runtime/mppa_k1c/i32_divmod.S
new file mode 100644
index 00000000..d5a4c2ca
--- /dev/null
+++ b/runtime/mppa_k1c/i32_divmod.S
@@ -0,0 +1,120 @@
+/* K1C
+32-bit unsigned/signed integer division/modulo (udiv5)
+
+D. Monniaux, CNRS, VERIMAG */
+
+
+ .globl __compcert_i32_sdiv
+__compcert_i32_sdiv:
+ compw.lt $r2 = $r0, 0
+ compw.lt $r3 = $r1, 0
+ absw $r0 = $r0
+ absw $r1 = $r1
+ ;;
+ xord $r2 = $r2, $r3
+ make $r3 = 0
+ goto __compcert_i32_divmod
+ ;;
+
+ .globl __compcert_i32_smod
+__compcert_i32_smod:
+ compw.lt $r2 = $r0, 0
+ absw $r0 = $r0
+ absw $r1 = $r1
+ make $r3 = 1
+ goto __compcert_i32_divmod
+ ;;
+
+ .globl __compcert_i32_umod
+__compcert_i32_umod:
+ make $r2 = 0
+ make $r3 = 1
+ goto __compcert_i32_divmod
+ ;;
+
+ .globl __compcert_i32_udiv
+__compcert_i32_udiv:
+ make $r2 = 0
+ make $r3 = 0
+ ;;
+
+/*
+r0 : a
+r1 : b
+r2 : negate result?
+r3 : return mod?
+*/
+
+ .globl __compcert_i32_divmod
+__compcert_i32_divmod:
+ zxwd $r7 = $r1
+ zxwd $r1 = $r0
+#ifndef NO_SHORTCUT
+ compw.ltu $r8 = $r0, $r1
+ cb.weqz $r1? .ERR # return 0 if divide by 0
+#endif
+ ;;
+# a in r1, b in r7
+ floatud.rn $r5 = $r7, 0
+#ifndef NO_SHORTCUT
+ compd.eq $r8 = $r7, 1
+ cb.wnez $r8? .LESS # shortcut if a < b
+#endif
+ ;;
+# b (double) in r5
+ make $r6 = 0x3ff0000000000000 # 1.0
+ fnarrowdw.rn $r11 = $r5
+# cb.wnez $r8, .RET1 # if b=1
+ ;;
+# b (single) in r11
+ floatud.rn $r10 = $r1, 0
+ finvw.rn $r11 = $r11
+ ;;
+ fwidenlwd $r11 = $r11
+ ;;
+# invb0 in r11
+ copyd $r9 = $r11
+ ffmsd.rn $r6 = $r11, $r5
+# alpha in r6
+ ;;
+ ffmad.rn $r9 = $r11, $r6
+# 1/b in r9
+ ;;
+ fmuld.rn $r0 = $r10, $r9
+# a/b in r1
+ ;;
+ fixedud.rn $r0 = $r0, 0
+ ;;
+ msbfd $r1 = $r0, $r7
+ ;;
+ addd $r6 = $r0, -1
+ addd $r8 = $r1, $r7
+ ;;
+ cmoved.dltz $r1? $r0 = $r6
+ cmoved.dltz $r1? $r1 = $r8
+ ;;
+ negw $r4 = $r0
+ negw $r5 = $r1
+ ;;
+ cmoved.wnez $r2? $r0 = $r4
+ cmoved.wnez $r2? $r1 = $r5
+ ;;
+.END:
+ cmoved.wnez $r3? $r0 = $r1
+ ret
+ ;;
+#ifndef NO_SHORTCUT
+
+.LESS:
+ make $r0 = 0
+ negw $r5 = $r1
+ ;;
+ cmoved.wnez $r2? $r1 = $r5
+ goto .END
+ ;;
+
+.ERR:
+ make $r0 = 0
+ ret
+ ;;
+#endif
diff --git a/runtime/mppa_k1c/i64_sdiv.c b/runtime/mppa_k1c/i64_sdiv.c
index 809f2b1c..18a2c46c 100644
--- a/runtime/mppa_k1c/i64_sdiv.c
+++ b/runtime/mppa_k1c/i64_sdiv.c
@@ -1,5 +1,3 @@
-extern long __divdi3 (long a, long b);
-
#include <mppa_bare_runtime/k1c/registers.h>
/* DM FIXME this is for floating point */