add trunc_div and trunch_rem to decoder helpers
[soc.git] / src / soc / decoder / helpers.py
index e8fd6cb7e1a5c7ca2c535a6213e2a791684577ee..ef6610e5c89d7d0e0316c216bf51faf8486f46df 100644 (file)
@@ -1,11 +1,38 @@
 import unittest
 from soc.decoder.selectable_int import SelectableInt
 
+"""
+Links:
+* https://bugs.libre-soc.org/show_bug.cgi?id=324 - add trunc_div and trunc_rem
+"""
 
 def exts(value, bits):
     sign = 1 << (bits - 1)
     return (value & (sign - 1)) - (value & sign)
 
+def trunc_div(n, d):
+    f = getattr(n, "trunc_div", None)
+    if f is not None:
+        return f(d)
+    fr = getattr(d, "rtrunc_div", None)
+    if fr is not None:
+        return fr(n)
+    abs_n = abs(n)
+    abs_d = abs(d)
+    abs_q = n // d
+    if (n < 0) == (d < 0):
+        return abs_q
+    return -abs_q
+
+def trunc_rem(n, d):
+    f = getattr(n, "trunc_rem", None)
+    if f is not None:
+        return f(d)
+    fr = getattr(d, "rtrunc_rem", None)
+    if fr is not None:
+        return fr(n)
+    return n - d * trunc_div(n, d)
+
 
 def EXTS(value):
     """ extends sign bit out from current MSB to all 256 bits