aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mppa_k1c/PostpassSchedulingOracle.ml4
-rw-r--r--mppa_k1c/SelectOp.vp12
-rw-r--r--mppa_k1c/SelectOpproof.v18
-rw-r--r--runtime/Makefile5
-rw-r--r--runtime/mppa_k1c/i32_divmod.S120
-rw-r--r--runtime/mppa_k1c/i64_sdiv.c12
-rw-r--r--runtime/mppa_k1c/i64_smod.c40
-rw-r--r--runtime/mppa_k1c/vararg.S125
-rwxr-xr-xtest/monniaux/clean_benches.sh1
-rw-r--r--test/monniaux/division/sum_div.c18
10 files changed, 268 insertions, 87 deletions
diff --git a/mppa_k1c/PostpassSchedulingOracle.ml b/mppa_k1c/PostpassSchedulingOracle.ml
index 9067f8e1..7015fd5f 100644
--- a/mppa_k1c/PostpassSchedulingOracle.ml
+++ b/mppa_k1c/PostpassSchedulingOracle.ml
@@ -603,9 +603,9 @@ let rec_to_usage r =
| Some U27L5 | Some U27L10 -> mau_x
| Some E27U27L10 -> mau_y)
| Nop -> alu_nop
- | Sraw | Srlw | Srsw | Sllw | Srad | Srld | Slld -> (match encoding with None | Some U6 -> alu_tiny | _ -> raise InvalidEncoding)
+ | Sraw | Srlw | Sllw | Srad | Srld | Slld -> (match encoding with None | Some U6 -> alu_tiny | _ -> raise InvalidEncoding)
(* TODO: check *)
- | Srsd | Rorw -> (match encoding with None | Some U6 -> alu_lite | _ -> raise InvalidEncoding)
+ | Srsw | Srsd | Rorw -> (match encoding with None | Some U6 -> alu_lite | _ -> raise InvalidEncoding)
| Extfz | Extfs | Insf -> (match encoding with None -> alu_lite | _ -> raise InvalidEncoding)
| Fixeduwz | Fixedwz | Floatwz | Floatuwz | Fixeddz | Fixedudz | Floatdz | Floatudz -> mau
| Lbs | Lbz | Lhs | Lhz | Lws | Ld | Lq | Lo ->
diff --git a/mppa_k1c/SelectOp.vp b/mppa_k1c/SelectOp.vp
index aac3010e..6adcebe5 100644
--- a/mppa_k1c/SelectOp.vp
+++ b/mppa_k1c/SelectOp.vp
@@ -423,18 +423,10 @@ Definition mods_base (e1: expr) (e2: expr) :=
Eexternal i32_smod sig_ii_i (e1 ::: e2 ::: Enil).
Definition divu_base (e1: expr) (e2: expr) :=
- Eop Olowlong
- ((Eexternal i64_udiv sig_ll_l
- ((Eop Ocast32unsigned (e1 ::: Enil)):::
- (Eop Ocast32unsigned (e2 ::: Enil))::: Enil))
- :::Enil).
+ Eexternal i32_udiv sig_ii_i (e1 ::: e2 ::: Enil).
Definition modu_base (e1: expr) (e2: expr) :=
- Eop Olowlong
- ((Eexternal i64_umod sig_ll_l
- ((Eop Ocast32unsigned (e1 ::: Enil)):::
- (Eop Ocast32unsigned (e2 ::: Enil))::: Enil))
- :::Enil).
+ Eexternal i32_umod sig_ii_i (e1 ::: e2 ::: Enil).
Definition shrximm (e1: expr) (n2: int) :=
if Int.eq n2 Int.zero then e1 else Eop (Oshrximm n2) (e1:::Enil).
diff --git a/mppa_k1c/SelectOpproof.v b/mppa_k1c/SelectOpproof.v
index d22725d5..22eecfad 100644
--- a/mppa_k1c/SelectOpproof.v
+++ b/mppa_k1c/SelectOpproof.v
@@ -872,6 +872,12 @@ Theorem eval_divu_base:
Val.divu x y = Some z ->
exists v, eval_expr ge sp e m le (divu_base a b) v /\ Val.lessdef z v.
Proof.
+ intros; unfold divu_base.
+ econstructor; split. eapply eval_helper_2; eauto. DeclHelper. UseHelper. auto.
+Qed.
+
+(* For using 64-bit unsigned division for 32-bit
+
intros until z.
intros Hax Hby Hdiv. unfold divu_base.
pose proof (divu_is_divlu x y) as DIVU.
@@ -891,7 +897,8 @@ Proof.
}
congruence.
Qed.
-
+ *)
+
Theorem eval_modu_base:
forall le a b x y z,
eval_expr ge sp e m le a x ->
@@ -899,6 +906,12 @@ Theorem eval_modu_base:
Val.modu x y = Some z ->
exists v, eval_expr ge sp e m le (modu_base a b) v /\ Val.lessdef z v.
Proof.
+ intros; unfold modu_base.
+ econstructor; split. eapply eval_helper_2; eauto. DeclHelper. UseHelper. auto.
+Qed.
+
+(* for using 64-bit unsigned modulo for 32-bit
+
intros until z.
intros Hax Hby Hmod. unfold modu_base.
pose proof (modu_is_modlu x y) as MODU.
@@ -918,7 +931,8 @@ Proof.
}
congruence.
Qed.
-
+ *)
+
Theorem eval_shrximm:
forall le a n x z,
eval_expr ge sp e m le a x ->
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 892aac07..d1d268c4 100644
--- a/runtime/mppa_k1c/i64_sdiv.c
+++ b/runtime/mppa_k1c/i64_sdiv.c
@@ -1,15 +1,3 @@
-extern long __divdi3 (long a, long b);
-
-long i64_sdiv (long a, long b)
-{
- return __divdi3 (a, b);
-}
-
-int i32_sdiv (int a, int b)
-{
- return __divdi3 (a, b);
-}
-
#ifdef __K1C_COS__
#include <hal/cos_registers.h>
#define K1_SFR_CS_IO_MASK COS_SFR_CS_IO_MASK
diff --git a/runtime/mppa_k1c/i64_smod.c b/runtime/mppa_k1c/i64_smod.c
index 26ffb39b..e69de29b 100644
--- a/runtime/mppa_k1c/i64_smod.c
+++ b/runtime/mppa_k1c/i64_smod.c
@@ -1,40 +0,0 @@
-#if COMPLIQUE
-unsigned long long
-udivmoddi4(unsigned long long num, unsigned long long den, int modwanted);
-
-long long
-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;
-}
-
-#else
-extern long __moddi3 (long a, long b);
-
-long i64_smod (long a, long b)
-{
- return __moddi3 (a, b);
-}
-
-int i32_smod (int a, int b)
-{
- return __moddi3 (a, b);
-}
-#endif
diff --git a/runtime/mppa_k1c/vararg.S b/runtime/mppa_k1c/vararg.S
index 9e23e0b3..5804c707 100644
--- a/runtime/mppa_k1c/vararg.S
+++ b/runtime/mppa_k1c/vararg.S
@@ -52,3 +52,128 @@ __compcert_acswapw:
sq 0[$r0] = $r2r3
ret
;;
+
+ .globl __compcert_i32_sdiv
+ .globl __compcert_i32_smod
+ .globl __compcert_i32_udiv
+ .globl __compcert_i32_umod
+__compcert_i32_sdiv:
+ sxwd $r0 = $r0
+ sxwd $r1 = $r1
+ make $r2 = 0x3ff0000000000000
+ ;;
+ floatd.rn.s $r0 = $r0, 0
+ ;;
+ floatd.rn.s $r3 = $r1, 0
+ ;;
+ floatw.rn.s $r1 = $r1, 0
+ ;;
+ finvw $r1=$r1
+ ;;
+ fwidenlwd $r1 = $r1
+ ;;
+ fmuld $r0 = $r0, $r1
+ ;;
+ ffmsd $r2 = $r1, $r3
+ copyd $r1 = $r0
+ ;;
+ ffmad $r1 = $r2, $r0
+ ;;
+ ffmad $r0 = $r2, $r1
+ ;;
+ fixedd.rz $r0 = $r0, 0
+ ret
+ ;;
+
+__compcert_i32_smod:
+ sxwd $r4 = $r0
+ sxwd $r5 = $r1
+ make $r2 = 0x3ff0000000000000
+ ;;
+ copyd $r0 = $r4
+ copyd $r1 = $r5
+ floatd.rn.s $r4 = $r4, 0
+ ;;
+ floatd.rn.s $r3 = $r5, 0
+ ;;
+ floatw.rn.s $r5 = $r5, 0
+ ;;
+ finvw $r5=$r5
+ ;;
+ fwidenlwd $r5 = $r5
+ ;;
+ fmuld $r4 = $r4, $r5
+ ;;
+ ffmsd $r2 = $r5, $r3
+ copyd $r5 = $r4
+ ;;
+ ffmad $r5 = $r2, $r4
+ ;;
+ ffmad $r4 = $r2, $r5
+ ;;
+ fixedd.rz $r4 = $r4, 0
+ ;;
+ msbfd $r0 = $r1, $r4
+ ret
+ ;;
+
+__compcert_i32_udiv:
+ zxwd $r0 = $r0
+ zxwd $r1 = $r1
+ make $r2 = 0x3ff0000000000000
+ ;;
+ floatud.rn.s $r0 = $r0, 0
+ ;;
+ floatud.rn.s $r3 = $r1, 0
+ ;;
+ floatuw.rn.s $r1 = $r1, 0
+ ;;
+ finvw $r1=$r1
+ ;;
+ fwidenlwd $r1 = $r1
+ ;;
+ fmuld $r0 = $r0, $r1
+ ;;
+ ffmsd $r2 = $r1, $r3
+ copyd $r1 = $r0
+ ;;
+ ffmad $r1 = $r2, $r0
+ ;;
+ ffmad $r0 = $r2, $r1
+ ;;
+ fixedud.rz $r0 = $r0, 0
+ ;;
+ ret
+ ;;
+
+__compcert_i32_umod:
+ zxwd $r4 = $r0
+ zxwd $r5 = $r1
+ make $r2 = 0x3ff0000000000000
+ ;;
+ copyd $r0 = $r4
+ copyd $r1 = $r5
+ floatud.rn.s $r4 = $r4, 0
+ ;;
+ floatud.rn.s $r3 = $r5, 0
+ ;;
+ floatuw.rn.s $r5 = $r5, 0
+ ;;
+ finvw $r5=$r5
+ ;;
+ fwidenlwd $r5 = $r5
+ ;;
+ fmuld $r4 = $r4, $r5
+ ;;
+ ffmsd $r2 = $r5, $r3
+ copyd $r5 = $r4
+ ;;
+ ffmad $r5 = $r2, $r4
+ ;;
+ ffmad $r4 = $r2, $r5
+ ;;
+ fixedud.rz $r4 = $r4, 0
+ ;;
+ msbfd $r0 = $r1, $r4
+ ret
+ ;;
diff --git a/test/monniaux/clean_benches.sh b/test/monniaux/clean_benches.sh
index d246e110..c0a87ff9 100755
--- a/test/monniaux/clean_benches.sh
+++ b/test/monniaux/clean_benches.sh
@@ -5,3 +5,4 @@ rm -f commands.txt
for bench in $benches; do
(cd $bench && make clean)
done
+rm -f *.o
diff --git a/test/monniaux/division/sum_div.c b/test/monniaux/division/sum_div.c
deleted file mode 100644
index 87256922..00000000
--- a/test/monniaux/division/sum_div.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include "../clock.h"
-
-int main(int argc, char **argv) {
- unsigned modulus = argc < 2 ? 3371 : atoi(argv[1]);
- clock_prepare();
- clock_start();
- unsigned total=0, total_mod=0;
- for(int i=0; i<1000; i++) {
- total += i;
- total_mod = (total_mod + i)%modulus;
- }
- clock_stop();
- print_total_clock();
- printf("%u %u %d\n", total, total_mod, total%modulus == total_mod);
- return 0;
-}