From 4c1d16153f318c1fbf17c3f050ba5f7f64ff5bbe Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Mon, 14 Mar 2022 21:56:03 -0700 Subject: [PATCH] add WIP cldivrem -- see if [[!inline ...]] works --- openpower/sv/bitmanip.mdwn | 7 +++++ openpower/sv/bitmanip_inlines/cldivrem.py | 34 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 openpower/sv/bitmanip_inlines/cldivrem.py diff --git a/openpower/sv/bitmanip.mdwn b/openpower/sv/bitmanip.mdwn index 3923c0bef..bf65a028a 100644 --- a/openpower/sv/bitmanip.mdwn +++ b/openpower/sv/bitmanip.mdwn @@ -627,6 +627,13 @@ temp = clmul((RA), (RB)) ^ (RC) (RS) = temp ``` +## `cldivrem` Carry-less Division and Remainder + +`cldivrem` isn't an actual instruction, but is just used in the pseudo-code +for other instructions. + +[[!inline pages="bitmanip_inlines/cldivrem.py" raw="true"]] + ## `cldiv` Carry-less Division ``` diff --git a/openpower/sv/bitmanip_inlines/cldivrem.py b/openpower/sv/bitmanip_inlines/cldivrem.py new file mode 100644 index 000000000..5bf49b120 --- /dev/null +++ b/openpower/sv/bitmanip_inlines/cldivrem.py @@ -0,0 +1,34 @@ +def cldivrem(n, d, width): + """ Carry-less Division and Remainder. + `n` and `d` are integers, `width` is the number of bits needed to hold + each input/output. + Returns a tuple `q, r` of the quotient and remainder. + """ + assert d != 0, "TODO: decide what happens on division by zero" + assert 0 <= n < 1 << width, f"bad n (doesn't fit in {width}-bit uint)" + assert 0 <= d < 1 << width, f"bad d (doesn't fit in {width}-bit uint)" + r = n + q = 0 + r_shift = 0 + d_shift = 0 + msb = 1 << (width - 1) + for _ in range(width): + if r & msb: + if d & msb: + r ^= d + q |= 1 + else: + d <<= 1 + d_shift += 1 + else: + if d & msb: + r <<= 1 + q <<= 1 + r_shift += 1 + else: + r <<= 1 + r_shift += 1 + d <<= 1 + d_shift += 1 + r >>= r_shift + return q, r -- 2.30.2