compiler/ lib/ examples/ std/ arch/ rv64/ tests/ abi.sizes.rad 3.4 KiB aggregate.return.rad 4.0 KiB arith.assignment.rad 580 B arith.basic.rad 176 B arith.modulo.rad 96 B arith.subword.rad 3.8 KiB arith.sum.rad 177 B arith.w64.rad 4.1 KiB array.assign.rad 221 B array.bounds.check.rad 321 B array.index.assign.rad 367 B array.index.rad 249 B array.length.rad 262 B array.math.rad 1.2 KiB array.nested.assign.rad 319 B array.nested.rad 325 B array.record.elements.rad 1.7 KiB array.repeat.edge.rad 548 B array.repeat.rad 828 B array.return.rad 330 B array.slice.empty.rad 108 B array.slice.gen.end.rad 126 B array.slice.gen.index.rad 139 B array.slice.gen.open.rad 125 B array.slice.gen.start.end.rad 127 B array.slice.gen.start.rad 126 B array.slice.rad 759 B as.precedence.rad 212 B assert.basic.rad 387 B assert.fail.rad 138 B assert.false.rad 140 B assert.true.rad 100 B assign.mutable.rad 6.1 KiB assign.rad 129 B assign.shadow.mutable.rad 461 B binop.bitwise.rad 1.2 KiB binop.cmp.rad 426 B bool.comparison.array.rad 688 B bool.comparison.nested.gen.rad 1.0 KiB bool.comparison.opt.rad 905 B bool.comparison.record.gen.rad 1.0 KiB bool.comparison.record.rad 1.1 KiB bool.comparison.slice.gen.rad 157 B bool.comparison.slice.rad 4.1 KiB bool.comparison.slice.record.gen.rad 2.0 KiB bool.comparison.slice.union.gen.rad 2.5 KiB bool.comparison.union.ctor.rad 690 B bool.comparison.union.gen.rad 1.2 KiB bool.comparison.union.record.gen.rad 1.5 KiB bool.comparison.union.simple.gen.rad 281 B bool.operators.complex.rad 384 B bool.operators.rad 831 B bool.short.circuit.rad 2.3 KiB bool.simple.rad 194 B bool.values.rad 772 B builtin.size.align.rad 1.3 KiB builtin.sliceof.mut.rad 606 B builtin.sliceof.rad 505 B call.arg.clobber.rad 717 B call.basic.rad 241 B call.clobber.rad 462 B cast.same.size.rad 1.0 KiB casting.numbers.rad 1.5 KiB char.literal.rad 165 B compound.assign.field.rad 285 B compound.assign.rad 1.1 KiB cond.assign.rad 723 B cond.expr.aggregate.rad 1.1 KiB cond.expr.rad 1.8 KiB cond.for.else.break.rad 326 B cond.for.indexed.rad 238 B cond.for.rad 165 B cond.for.range.indexed.rad 526 B cond.for.range.rad 171 B cond.for.unsigned.range.rad 644 B cond.forever.break.continue.rad 182 B cond.forever.break.rad 232 B cond.fused.rad 926 B cond.if.case.rad 2.2 KiB cond.if.else.min.rad 143 B cond.if.else.rad 225 B cond.if.elseif.rad 420 B cond.if.noelse.rad 120 B cond.if.rad 865 B cond.match.fallthrough.rad 369 B cond.match.guard.rad 1.4 KiB cond.match.guard.regalloc.rad 1.3 KiB cond.while.else.break.rad 282 B cond.while.rad 119 B const.array.copy.mutate.rad 386 B const.array.rad 195 B const.basic.rad 325 B const.char.rad 159 B const.fn.array.rad 664 B const.record.array.rad 1.2 KiB const.record.array.simple.rad 523 B const.record.ctor.rad 170 B const.record.fn.rad 353 B const.record.rad 182 B const.slice.param.rad 333 B const.union.payload.ctor.rad 349 B const.union.record.literal.rad 359 B data.array.rad 767 B data.bool.rad 216 B data.i16.rad 261 B data.i32.rad 281 B data.i8.rad 248 B data.record.rad 561 B data.simple.rad 436 B data.u16.rad 220 B data.u32.rad 240 B data.u8.rad 208 B data.union.rad 886 B debug.tag.rad 557 B edge.cases.2.rad 337 B edge.cases.3.rad 594 B edge.cases.4.rad 1.2 KiB edge.cases.5.rad 1.0 KiB edge.cases.6.rad 2.6 KiB edge.cases.7.addr.bug.rad 224 B edge.cases.8.bug.rad 508 B edge.cases.rad 223 B error.basic.rad 159 B error.catch.rad 1.6 KiB error.division.zero.rad 164 B error.modulo.zero.rad 162 B error.multi.basic.rad 672 B error.multi.catch.rad 772 B error.multi.catch.typed.binding.rad 791 B error.multi.catch.typed.catchall.rad 1.0 KiB error.multi.catch.typed.rad 1.1 KiB error.multi.propagate.multi.rad 953 B error.multi.propagate.rad 825 B error.multi.try.optional.rad 507 B error.slice.bounds.rad 219 B error.try.bang.success.rad 370 B error.try.catch.binding.rad 2.0 KiB error.try.optional.rad 1.8 KiB error.try.rad 4.0 KiB fn.block.scope.rad 508 B fn.callback.nested.rad 1.2 KiB fn.default.rad 131 B fn.local.rad 140 B fn.recursion.2.rad 239 B fn.void.rad 150 B for.else.continue.rad 1.1 KiB frame.large.rad 567 B if-let-mut.rad 1.1 KiB iflet.shadow.leak.rad 317 B integer.bitwise.basic.rad 693 B integer.overflow.rad 1.8 KiB large.blit.store.rad 2.1 KiB let.guard.rad 1.9 KiB literal.w64.rad 1.7 KiB loc.addr.offset.bug.rad 410 B loc.addr.opt.to.opt.rad 433 B loc.addr.optional.assign.rad 408 B loc.addr.record.assign.rad 443 B loop.complex.flow.rad 1007 B loop.sealblock.rad 911 B match.array.rad 3.4 KiB match.char.rad 1.6 KiB match.multi.seal.rad 987 B match.multi.survive.rad 1.6 KiB match.mutref.push.rad 1.0 KiB match.mutref.union.rad 662 B match.nested.call.rad 1.7 KiB match.nested.deep.rad 2.2 KiB match.nested.deref.rad 3.7 KiB match.nested.guard.rad 1.6 KiB match.nested.iflet.guard.rad 1.6 KiB match.nested.iflet.rad 1.4 KiB match.nested.letelse.rad 813 B match.nested.letelse.union.rad 1.3 KiB match.nested.literal.rad 3.1 KiB match.nested.multi.rad 2.4 KiB match.nested.pattern.rad 5.2 KiB match.nested.record.rad 2.0 KiB match.nested.union.rad 2.3 KiB match.nested.whilelet.rad 2.4 KiB match.string.rad 1.8 KiB match.value.copy.rad 2.0 KiB match.void.then.or.rad 1.6 KiB memzero.result.bug.rad 806 B memzero.union.bug.rad 576 B mutref.loop.bug.rad 1.8 KiB opt.assignment.bug.rad 1.3 KiB opt.bug.test.rad 1.4 KiB opt.if.let.complex.rad 6.2 KiB opt.if.let.guard.rad 809 B opt.if.let.rad 956 B opt.nil.check.rad 1.5 KiB opt.record.eq.rad 842 B opt.record.rad 655 B opt.return.array.rad 289 B opt.return.nested.rad 797 B opt.return.record.rad 344 B opt.slice.npo.rad 2.8 KiB opt.type.rad 200 B opt.while.let.complex.rad 404 B panic.rad 111 B placeholder.basic.rad 133 B placeholder.comprehensive.rad 562 B pointer.copy.edge.case.rad 1.3 KiB pointer.slice.index.rad 269 B pointer.slice.store.rad 881 B prog.ackermann.rad 5.0 KiB prog.bignum.rad 9.4 KiB prog.binsearch.rad 2.4 KiB prog.bubblesort.rad 2.0 KiB prog.cordic.rad 6.9 KiB prog.crc32.rad 2.7 KiB prog.dijkstra.rad 7.7 KiB prog.eval.rad 6.2 KiB prog.hanoi.rad 3.8 KiB prog.huffman.rad 9.3 KiB prog.hybridsort.rad 3.0 KiB prog.linkedlist.rad 5.8 KiB prog.lzw.rad 6.7 KiB prog.matmul.rad 2.9 KiB prog.mersenne.rad 5.2 KiB prog.nqueens.rad 3.4 KiB prog.rbtree.rad 8.2 KiB prog.regex.rad 10.2 KiB prog.sha256.rad 7.0 KiB prog.sieve.rad 2.8 KiB prog.symtab.rad 10.1 KiB prog.tokenizer.rad 13.8 KiB prog.vm.rad 17.4 KiB ptr.assign.rad 137 B ptr.deref.rad 622 B ptr.eq.rad 966 B ptr.mutate.rad 244 B ptr.opaque.rad 1.4 KiB record.access.rad 285 B record.alignment.rad 179 B record.array.elements.rad 1.7 KiB record.copy.rad 2.0 KiB record.field.assign.rad 184 B record.nested.calls.2.rad 612 B record.nested.calls.3.rad 734 B record.param.lit.rad 353 B record.ptr.access.rad 227 B record.ptr.mutate.rad 243 B record.shorthand.rad 1.5 KiB record.unlabeled.rad 407 B ref.if.bug.rad 519 B ref.immut.loop.bug.rad 670 B ref.mut.ptr.rad 261 B regalloc.callee.save.rad 1.5 KiB regalloc.spill.reuse.rad 473 B reserve.loop.rad 392 B result.void.success.rad 716 B slice.alloc.loop.rad 788 B slice.append.rad 3.3 KiB slice.cap.rad 941 B slice.delete.rad 971 B slice.of.rad 460 B slice.subslice.rad 1.4 KiB spill.blockarg.clobber.rad 3.5 KiB spill.loop.rad 1.6 KiB stack.local.corrupt.rad 320 B static.array.mutate.rad 387 B static.basic.rad 327 B static.fn.array.rad 628 B static.record.array.rad 503 B static.slice.index.assign.rad 408 B static.slice.offset.rad 668 B string.basic.rad 149 B string.escape.rad 349 B string.index.rad 116 B switch.blockargs.clobber.rad 1.3 KiB trait.aggregate.ret.rad 1.5 KiB trait.array.optional.rad 1.7 KiB trait.basic.rad 565 B trait.control.flow.rad 1.1 KiB trait.fn.param.rad 1.6 KiB trait.multiple.methods.rad 1.2 KiB trait.multiple.traits.rad 1.2 KiB trait.multiple.types.rad 1.3 KiB trait.supertrait.rad 2.5 KiB trait.throws.rad 1.0 KiB trait.writer.rad 2.6 KiB type.unify.rad 4.5 KiB undefined.rad 417 B union-tag.rad 911 B union.bitfield.rad 1.2 KiB union.discriminant.cast.rad 389 B union.edge.case.2.rad 679 B union.edge.case.3.rad 608 B union.mixed.assign.rad 977 B union.payload.mutref.rad 1.4 KiB union.payload.rad 580 B union.record.forward.rad 1.3 KiB union.void.match.rad 403 B union.void.rad 824 B unsigned.compare.rad 1.9 KiB var.align.rad 1013 B var.infer.rad 549 B decode.rad 14.6 KiB emit.rad 24.4 KiB encode.rad 19.9 KiB isel.rad 41.1 KiB printer.rad 13.0 KiB tests.rad 15.7 KiB rv64.rad 13.0 KiB collections/ lang/ sys/ arch.rad 65 B collections.rad 36 B fmt.rad 3.8 KiB intrinsics.rad 206 B io.rad 1.2 KiB lang.rad 222 B mem.rad 2.2 KiB sys.rad 167 B testing.rad 2.4 KiB tests.rad 11.6 KiB vec.rad 3.1 KiB std.rad 231 B scripts/ seed/ test/ vim/ .gitignore 353 B .gitsigners 112 B LICENSE 1.1 KiB Makefile 3.1 KiB README 2.5 KiB std.lib 987 B std.lib.test 252 B
lib/std/arch/rv64/tests/prog.bignum.rad 9.4 KiB raw
1
//! Big number arithmetic.
2
//! Implement multi-word unsigned integer arithmetic using arrays of u32 limbs
3
//! (little-endian). Operations: add, subtract, multiply, compare, shift.
4
//! Verify using known large-number identities and cross-checks.
5
6
/// Number of limbs per big number (128 bits = 4 x 32-bit words).
7
const LIMBS: u32 = 4;
8
9
/// Set a big number to a u32 value.
10
fn bnFromU32(dst: *mut [u32], val: u32) {
11
    dst[0] = val;
12
    let mut i: u32 = 1;
13
    while i < LIMBS {
14
        dst[i] = 0;
15
        i += 1;
16
    }
17
}
18
19
/// Set a big number to zero.
20
fn bnZero(dst: *mut [u32]) {
21
    let mut i: u32 = 0;
22
    while i < LIMBS {
23
        dst[i] = 0;
24
        i += 1;
25
    }
26
}
27
28
/// Copy src to dst.
29
fn bnCopy(dst: *mut [u32], src: *[u32]) {
30
    let mut i: u32 = 0;
31
    while i < LIMBS {
32
        dst[i] = src[i];
33
        i += 1;
34
    }
35
}
36
37
/// Compare two big numbers. Returns 0 if equal, 1 if a > b, -1 if a < b.
38
fn bnCmp(a: *[u32], b: *[u32]) -> i32 {
39
    let mut i: i32 = LIMBS as i32 - 1;
40
    while i >= 0 {
41
        if a[i as u32] > b[i as u32] {
42
            return 1;
43
        }
44
        if a[i as u32] < b[i as u32] {
45
            return -1;
46
        }
47
        if i == 0 {
48
            break;
49
        }
50
        i -= 1;
51
    }
52
    return 0;
53
}
54
55
/// Add two big numbers: dst = a + b. Returns carry (0 or 1).
56
fn bnAdd(dst: *mut [u32], a: *[u32], b: *[u32]) -> u32 {
57
    let mut carry: u32 = 0;
58
    let mut i: u32 = 0;
59
    while i < LIMBS {
60
        let sumLo: u32 = a[i] + b[i];
61
        let mut carry1: u32 = 0;
62
        if sumLo < a[i] {
63
            carry1 = 1;
64
        }
65
        let sum: u32 = sumLo + carry;
66
        let mut carry2: u32 = 0;
67
        if sum < sumLo {
68
            carry2 = 1;
69
        }
70
        dst[i] = sum;
71
        carry = carry1 + carry2;
72
        i += 1;
73
    }
74
    return carry;
75
}
76
77
/// Subtract two big numbers: dst = a - b. Returns borrow (0 or 1).
78
fn bnSub(dst: *mut [u32], a: *[u32], b: *[u32]) -> u32 {
79
    let mut borrow: u32 = 0;
80
    let mut i: u32 = 0;
81
    while i < LIMBS {
82
        let diff: u32 = a[i] - b[i];
83
        let mut borrow1: u32 = 0;
84
        if diff > a[i] {
85
            borrow1 = 1;
86
        }
87
        let result: u32 = diff - borrow;
88
        let mut borrow2: u32 = 0;
89
        if result > diff {
90
            borrow2 = 1;
91
        }
92
        dst[i] = result;
93
        borrow = borrow1 + borrow2;
94
        i += 1;
95
    }
96
    return borrow;
97
}
98
99
/// Multiply two LIMBS-word numbers, producing a 2*LIMBS-word result in wide.
100
fn bnMul(wide: *mut [u32], a: *[u32], b: *[u32]) {
101
    let mut i: u32 = 0;
102
    while i < LIMBS * 2 {
103
        wide[i] = 0;
104
        i += 1;
105
    }
106
107
    i = 0;
108
    while i < LIMBS {
109
        let mut carry: u32 = 0;
110
        let mut j: u32 = 0;
111
        while j < LIMBS {
112
            let al: u32 = a[i] & 0xFFFF;
113
            let ah: u32 = a[i] >> 16;
114
            let bl: u32 = b[j] & 0xFFFF;
115
            let bh: u32 = b[j] >> 16;
116
117
            let ll: u32 = al * bl;
118
            let lh: u32 = al * bh;
119
            let hl: u32 = ah * bl;
120
            let hh: u32 = ah * bh;
121
122
            let mid: u32 = lh + hl;
123
            let mut midCarry: u32 = 0;
124
            if mid < lh {
125
                midCarry = 1;
126
            }
127
128
            let lo: u32 = ll + (mid << 16);
129
            let mut loCarry: u32 = 0;
130
            if lo < ll {
131
                loCarry = 1;
132
            }
133
            let hi: u32 = hh + (mid >> 16) + (midCarry << 16) + loCarry;
134
135
            let sum1: u32 = wide[i + j] + lo;
136
            let mut c1: u32 = 0;
137
            if sum1 < wide[i + j] {
138
                c1 = 1;
139
            }
140
            let sum2: u32 = sum1 + carry;
141
            let mut c2: u32 = 0;
142
            if sum2 < sum1 {
143
                c2 = 1;
144
            }
145
            wide[i + j] = sum2;
146
            carry = hi + c1 + c2;
147
148
            j += 1;
149
        }
150
        wide[i + LIMBS] += carry;
151
        i += 1;
152
    }
153
}
154
155
/// Left shift a big number by 1 bit.
156
fn bnShl1(dst: *mut [u32], src: *[u32]) {
157
    let mut carry: u32 = 0;
158
    let mut i: u32 = 0;
159
    while i < LIMBS {
160
        let newCarry: u32 = src[i] >> 31;
161
        dst[i] = (src[i] << 1) | carry;
162
        carry = newCarry;
163
        i += 1;
164
    }
165
}
166
167
/// Right shift a big number by 1 bit.
168
fn bnShr1(dst: *mut [u32], src: *[u32]) {
169
    let mut carry: u32 = 0;
170
    let mut i: u32 = LIMBS;
171
    while i > 0 {
172
        i -= 1;
173
        let newCarry: u32 = src[i] & 1;
174
        dst[i] = (src[i] >> 1) | (carry << 31);
175
        carry = newCarry;
176
    }
177
}
178
179
/// Test basic addition.
180
fn testAdd() -> i32 {
181
    let mut a: [u32; 4] = [0; 4];
182
    let mut b: [u32; 4] = [0; 4];
183
    let mut c: [u32; 4] = [0; 4];
184
    let mut d: [u32; 4] = [0; 4];
185
186
    bnFromU32(&mut a[..], 0xFFFFFFFF);
187
    bnFromU32(&mut b[..], 1);
188
    let carry: u32 = bnAdd(&mut c[..], &a[..], &b[..]);
189
190
    assert carry == 0;
191
    assert c[0] == 0;
192
    assert c[1] == 1;
193
194
    bnFromU32(&mut b[..], 0xFFFFFFFF);
195
    let carry2: u32 = bnAdd(&mut d[..], &c[..], &b[..]);
196
    assert carry2 == 0;
197
    assert d[0] == 0xFFFFFFFF;
198
    assert d[1] == 1;
199
200
    return 0;
201
}
202
203
/// Test subtraction.
204
fn testSub() -> i32 {
205
    let mut a: [u32; 4] = [0; 4];
206
    let mut b: [u32; 4] = [0; 4];
207
    let mut c: [u32; 4] = [0; 4];
208
209
    bnZero(&mut a[..]);
210
    a[1] = 1;
211
    bnFromU32(&mut b[..], 1);
212
    let borrow: u32 = bnSub(&mut c[..], &a[..], &b[..]);
213
214
    assert borrow == 0;
215
    assert c[0] == 0xFFFFFFFF;
216
    assert c[1] == 0;
217
218
    return 0;
219
}
220
221
/// Test multiplication.
222
fn testMul() -> i32 {
223
    let mut a: [u32; 4] = [0; 4];
224
    let mut b: [u32; 4] = [0; 4];
225
    let mut wide: [u32; 8] = [0; 8];
226
227
    bnFromU32(&mut a[..], 12345);
228
    bnFromU32(&mut b[..], 67890);
229
    bnMul(&mut wide[..], &a[..], &b[..]);
230
231
    assert wide[0] == 838102050;
232
    assert wide[1] == 0;
233
234
    bnFromU32(&mut a[..], 0xFFFFFFFF);
235
    bnFromU32(&mut b[..], 0xFFFFFFFF);
236
    bnMul(&mut wide[..], &a[..], &b[..]);
237
238
    assert wide[0] == 0x00000001;
239
    assert wide[1] == 0xFFFFFFFE;
240
241
    return 0;
242
}
243
244
/// Test the identity a + b - b = a.
245
fn testAddSubIdentity() -> i32 {
246
    let mut a: [u32; 4] = [0; 4];
247
    let mut b: [u32; 4] = [0; 4];
248
    let mut c: [u32; 4] = [0; 4];
249
    let mut d: [u32; 4] = [0; 4];
250
251
    a[0] = 0x12345678;
252
    a[1] = 0xABCDEF01;
253
    a[2] = 0x9876FEDC;
254
    a[3] = 0x01020304;
255
256
    b[0] = 0xFEDCBA98;
257
    b[1] = 0x76543210;
258
    b[2] = 0x11223344;
259
    b[3] = 0x00AABB00;
260
261
    bnAdd(&mut c[..], &a[..], &b[..]);
262
    bnSub(&mut d[..], &c[..], &b[..]);
263
264
    assert bnCmp(&d[..], &a[..]) == 0;
265
266
    bnSub(&mut d[..], &c[..], &a[..]);
267
    assert bnCmp(&d[..], &b[..]) == 0;
268
269
    return 0;
270
}
271
272
/// Test shift operations.
273
fn testShift() -> i32 {
274
    let mut a: [u32; 4] = [0; 4];
275
    let mut b: [u32; 4] = [0; 4];
276
    let mut c: [u32; 4] = [0; 4];
277
278
    bnFromU32(&mut a[..], 1);
279
    bnShl1(&mut b[..], &a[..]);
280
    assert b[0] == 2;
281
282
    bnFromU32(&mut a[..], 0x80000000);
283
    bnShl1(&mut b[..], &a[..]);
284
    assert b[0] == 0;
285
    assert b[1] == 1;
286
287
    bnShr1(&mut c[..], &b[..]);
288
    assert c[0] == 0x80000000;
289
    assert c[1] == 0;
290
291
    return 0;
292
}
293
294
/// Test large multiply.
295
fn testLargeMultiply() -> i32 {
296
    let mut a: [u32; 4] = [0; 4];
297
    let mut b: [u32; 4] = [0; 4];
298
    let mut wide: [u32; 8] = [0; 8];
299
300
    a[0] = 0xFFFFFFFF;
301
    a[1] = 0xFFFFFFFF;
302
    a[2] = 0;
303
    a[3] = 0;
304
305
    bnFromU32(&mut b[..], 1);
306
    bnMul(&mut wide[..], &a[..], &b[..]);
307
    assert wide[0] == 0xFFFFFFFF;
308
    assert wide[1] == 0xFFFFFFFF;
309
    assert wide[2] == 0;
310
311
    bnZero(&mut a[..]);
312
    a[1] = 1;
313
    bnZero(&mut b[..]);
314
    b[1] = 1;
315
    bnMul(&mut wide[..], &a[..], &b[..]);
316
    assert wide[0] == 0;
317
    assert wide[1] == 0;
318
    assert wide[2] == 1;
319
    assert wide[3] == 0;
320
321
    return 0;
322
}
323
324
/// Test Fibonacci sequence with big numbers.
325
fn testFibonacci() -> i32 {
326
    let mut fibA: [u32; 4] = [0; 4];
327
    let mut fibB: [u32; 4] = [0; 4];
328
    let mut fibC: [u32; 4] = [0; 4];
329
330
    fibA[0] = 0;
331
    fibB[0] = 1;
332
333
    let mut i: u32 = 2;
334
    while i <= 48 {
335
        bnAdd(&mut fibC[..], &fibA[..], &fibB[..]);
336
        bnCopy(&mut fibA[..], &fibB[..]);
337
        bnCopy(&mut fibB[..], &fibC[..]);
338
        i += 1;
339
    }
340
341
    assert fibB[0] == 0x1E8D0A40;
342
    assert fibB[1] == 0x01;
343
344
    let mut fa: [u32; 4] = [0; 4];
345
    let mut fb: [u32; 4] = [0; 4];
346
    let mut fc: [u32; 4] = [0; 4];
347
    fa[0] = 0;
348
    fb[0] = 1;
349
    i = 2;
350
    while i <= 47 {
351
        bnAdd(&mut fc[..], &fa[..], &fb[..]);
352
        bnCopy(&mut fa[..], &fb[..]);
353
        bnCopy(&mut fb[..], &fc[..]);
354
        i += 1;
355
    }
356
    bnAdd(&mut fc[..], &fa[..], &fb[..]);
357
    assert bnCmp(&fc[..], &fibB[..]) == 0;
358
359
    return 0;
360
}
361
362
/// Test compare function.
363
fn testCompare() -> i32 {
364
    let mut a: [u32; 4] = [0; 4];
365
    let mut b: [u32; 4] = [0; 4];
366
367
    bnFromU32(&mut a[..], 100);
368
    bnFromU32(&mut b[..], 200);
369
370
    assert bnCmp(&a[..], &b[..]) == -1;
371
    assert bnCmp(&b[..], &a[..]) == 1;
372
    assert bnCmp(&a[..], &a[..]) == 0;
373
374
    bnZero(&mut a[..]);
375
    bnZero(&mut b[..]);
376
    a[3] = 1;
377
    b[0] = 0xFFFFFFFF;
378
    b[1] = 0xFFFFFFFF;
379
    b[2] = 0xFFFFFFFF;
380
    assert bnCmp(&a[..], &b[..]) == 1;
381
382
    return 0;
383
}
384
385
@default fn main() -> i32 {
386
    let r1: i32 = testAdd();
387
    if r1 != 0 {
388
        return 10 + r1;
389
    }
390
391
    let r2: i32 = testSub();
392
    if r2 != 0 {
393
        return 20 + r2;
394
    }
395
396
    let r3: i32 = testMul();
397
    if r3 != 0 {
398
        return 30 + r3;
399
    }
400
401
    let r4: i32 = testAddSubIdentity();
402
    if r4 != 0 {
403
        return 40 + r4;
404
    }
405
406
    let r5: i32 = testShift();
407
    if r5 != 0 {
408
        return 50 + r5;
409
    }
410
411
    let r6: i32 = testLargeMultiply();
412
    if r6 != 0 {
413
        return 60 + r6;
414
    }
415
416
    let r7: i32 = testFibonacci();
417
    if r7 != 0 {
418
        return 70 + r7;
419
    }
420
421
    let r8: i32 = testCompare();
422
    if r8 != 0 {
423
        return 80 + r8;
424
    }
425
426
    return 0;
427
}