Page 230 - ARM 64 Bit Assembly Language
P. 230
218 Chapter 7
195 void bigint_free(bigint b) {
196 if (b != NULL) {
197 if (b->blks != NULL)
198 free(b->blks);
199 free(b);
200 }
201 }
202
203 /******************************************************************/
204 /* Mathematical operations */
205 /******************************************************************/
206
207 /* this is the internal add function. It includes a */
208 /* carry. Several other functions use it. */
209 static bigint bigint_adc(bigint l, bigint r, chunk carry) {
210 bigint sum, tmpl, tmpr;
211 int i, nchunks;
212 bigchunk tmpsum;
213 /* allocate one extra chunk to make sure overflow
214 cannot occur */
215 nchunks = MAX(l->size, r->size) + 1;
216 /* make sure both operands are the same size */
217 tmpl = bigint_extend(l, nchunks);
218 tmpr = bigint_extend(r, nchunks);
219 /* allocate space for the result */
220 sum = bigint_alloc(nchunks);
221 /* perform the addition */
222 for (i = 0; i < nchunks; i++) {
223 /* add the current block of bits */
224 tmpsum = (bigchunk)tmpl->blks[i] + (bigchunk)tmpr->blks[i] + (bigchunk)carry;
225 sum->blks[i] = tmpsum & CHUNKMASK;
226 /* calculate the carry bit for the next block */
227 carry = (tmpsum >> BITSPERCHUNK) & CHUNKMASK;
228 }
229 bigint_free(tmpl);
230 bigint_free(tmpr);
231 tmpl = bigint_trim(sum);
232 bigint_free(sum);
233 return tmpl;
234 }
235
236 /* The add function calls adc to perform an add with */
237 /* initial carry of zero */
238 bigint bigint_add(bigint l, bigint r) {
239 return bigint_adc(l, r, 0);
240 }
241
242 /* The complement function returns the 1’s complement */
243 bigint bigint_complement(bigint b) {