aboutsummaryrefslogtreecommitdiffstats
path: root/runtime/mppa_k1c/i32_divmod.S
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/mppa_k1c/i32_divmod.S')
-rw-r--r--runtime/mppa_k1c/i32_divmod.S120
1 files changed, 120 insertions, 0 deletions
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