Page 231 - ARM 64 Bit Assembly Language
P. 231
Integer mathematics 219
244 bigint r = bigint_copy(b);
245 for (int i = 0; i < r->size; i++)
246 r->blks[i] ^= CHUNKMASK;
247 return r;
248 }
249
250 /* The sub function gets the 1’s complement of r, and adds it to l
251 with an initial carry of 1. The initial carry is equivalent to
252 adding 1 to the 1’s complement to create the 2’s complement.
253 */
254 bigint bigint_sub(bigint l, bigint r) {
255 bigint tmp1, tmp2;
256 tmp1 = bigint_complement(r);
257 tmp2 = bigint_adc(l, tmp1, 1);
258 bigint_free(tmp1);
259 return tmp2;
260 }
261
262 /* The mul_uint function multiplies a bigint by an unsigned chunk */
263 static bigint bigint_mul_uint(bigint l, chunk r) {
264 int i, negative = 0;
265 bigchunk tmpchunk;
266 bigint sum = bigint_from_int(0);
267 bigint tmp1, tmp2;
268 /* make sure the left operand is not negative */
269 if (l->blks[l->size-1] & ((bigchunk)1<<(BITSPERCHUNK-1))) {
270 negative ^= 1;
271 l = bigint_negate(l);
272 }
273 /* Perform the multiply (See section 7.2.5) */
274 for (i = 0; i < l->size; i++) {
275 tmpchunk = (bigchunk)l->blks[i] * r;
276 tmp1 = bigint_alloc(3);
277 tmp1->blks[0] = tmpchunk & CHUNKMASK;
278 tmp1->blks[1] = (tmpchunk>>BITSPERCHUNK) & CHUNKMASK;
279 tmp1->blks[2] = 0;
280 tmp2 = bigint_shift_left_chunk(tmp1, i);
281 bigint_free(tmp1);
282 tmp1 = bigint_adc(sum, tmp2, 0);
283 bigint_free(sum);
284 bigint_free(tmp2);
285 sum = tmp1;
286 }
287 /* result may need to be negated */
288 if (negative) {
289 tmp1 = sum;
290 sum = bigint_negate(sum);
291 bigint_free(tmp1);
292 bigint_free(l);