[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/2] Add fallback for divi_u
From: |
Paul Cercueil |
Subject: |
[PATCH 1/2] Add fallback for divi_u |
Date: |
Wed, 23 Oct 2024 13:07:08 +0200 |
Add a fallback for divi_u that does the division using a multiplication.
This is useful on architectures with a very slow integer division (e.g.
SH4).
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
lib/jit_fallback.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/lib/jit_fallback.c b/lib/jit_fallback.c
index 3a471eb..ce7bffd 100644
--- a/lib/jit_fallback.c
+++ b/lib/jit_fallback.c
@@ -302,6 +302,10 @@ static void
_fallback_unsti_x(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
# define fallback_patch_bmsi(inst, lbl) \
patch_at(inst, lbl)
# endif
+# if __WORDSIZE == 32
+# define fallback_divi_u(r0,r1,i0) _fallback_divi_u(_jit,r0,r1,i0)
+static void _fallback_divi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
+# endif
#endif
#if CODE
@@ -4241,4 +4245,31 @@ _fallback_unsti_x(jit_state_t *_jit,
jit_unget_reg(t0);
}
# endif
+
+# if __WORDSIZE == 32
+static void _fallback_divi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t
r1, jit_word_t i0)
+{
+ jit_int32_t t0;
+ unsigned int p, m;
+
+ if (i0 == 1) {
+ movr(r0, r1);
+ } else if (i0 >= 0x80000001) {
+ gei_u(r0, r1, i0);
+ } else {
+ p = 31 - __builtin_clz(i0) + !!(i0 & (i0 - 1));
+ m = (unsigned int)(((0x1ull << (32 + p)) + i0 - 1) / (unsigned long
long)i0);
+
+ t0 = fallback_jit_get_reg(jit_class_gpr);
+
+ hmuli_u(rn(t0), r1, m);
+ subr(r0, r1, rn(t0));
+ rshi_u(r0, r0, 1);
+ addr(r0, r0, rn(t0));
+ rshi_u(r0, r0, p - 1);
+
+ jit_unget_reg(t0);
+ }
+}
+# endif
#endif
--
2.45.2