From b0ec7472890babc8c439984d75c14f2b4486416a Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Tue, 21 May 2019 15:32:45 +0200 Subject: new routines for 32-bit division --- runtime/Makefile | 5 +- runtime/mppa_k1c/i32_divmod.S | 120 ++++++++++++++++++++++++++++++++++++++++++ runtime/mppa_k1c/i64_sdiv.c | 2 - 3 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 runtime/mppa_k1c/i32_divmod.S (limited to 'runtime') 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 /* DM FIXME this is for floating point */ -- cgit