(no commit message)
authorlkcl <lkcl@web>
Sun, 17 Apr 2022 11:23:13 +0000 (12:23 +0100)
committerIkiWiki <ikiwiki.info>
Sun, 17 Apr 2022 11:23:13 +0000 (12:23 +0100)
openpower/sv/bitmanip/appendix.mdwn

index 2796d7b40fbb7291287636db0e2f9d9948cc82b9..ed6092ecc3a00c9fef2b50b1199480ce8e7c9b74 100644 (file)
@@ -34,3 +34,30 @@ void div(uint32_t *n, uint32_t *d, uint32_t* q, int n_bytes, int d_bytes) {
     // now remainder is in n and quotient is in q
 }
 ```
+
+```
+On Sat, Apr 16, 2022, 22:06 Jacob Lifshay <programmerjake@gmail.com> wrote:
+and a mrsubcarry (the one actually needed by bigint division):
+# for big_c - big_a * word_b
+result <- RC + ~(RA * RB) + CARRY # this expression is wrong, needs further thought
+CARRY <- HIGH_HALF(result)
+RT <- LOW_HALF(result)
+
+turns out, after some checking with 4-bit words, afaict the correct algorithm for mrsubcarry is:
+# for big_c - big_a * word_b
+result <- RC + ~(RA * RB) + CARRY
+result_high <- HIGH_HALF(result)
+if CARRY <= 1 then # unsigned comparison
+    result_high <- result_high + 1
+end
+CARRY <- result_high
+RT <- LOW_HALF(result)
+
+afaict, that'll make the following algorithm work:
+
+so the inner loop in the bigint division algorithm would end up being (assuming n, d, and q all fit in registers):
+li r3, 1 # carry in for subtraction
+mtspr CARRY, r3 # init carry spr
+setvl loop_count
+sv.mrsubcarry rn.v, rd.v, rq.s, rn.v
+```