Page 234 - ARM 64 Bit Assembly Language
P. 234
222 Chapter 7
391 }
392 bigint_free(rt);
393 bigint_free(lt);
394 return q;
395 }
396
397 /* The C version of bigint_negate is very short, because it uses
398 existing functions. However, it is not very efficient. We also
399 have an assembly version of the negate function. The #ifndef
400 allows us to use the assembly version. When USE_ASM is defined,
401 the C version will not be compiled. */
402
403 #ifndef USE_ASM
404 bigint bigint_negate(bigint b) {
405 bigint r = bigint_complement(b); /* get 1’s complement */
406 bigint tmp1 = bigint_from_int(0); /* create zero */
407 bigint tmp2 = bigint_adc(r, tmp1, 1); /* add with an initial carry */
408 bigint_free(tmp1);
409 bigint_free(r);
410 return tmp2;
411 }
412 #endif
413
414 /* The add function calls adc to perform an add with */
415 /* initial carry of zero */
416 bigint bigint_abs(bigint b) {
417 if (b->blks[b->size-1] & ((bigchunk)1<<(BITSPERCHUNK-1)))
418 return bigint_negate(b);
419 else
420 return bigint_copy(b);
421 }
422
423 /* The sqrt function returns floor(sqrt(b)) using the digit-by-digit
424 algorithm. There are better square root algorithms... */
425 bigint bigint_sqrt(bigint b) {
426 bigint r = bigint_from_int(0), zero = bigint_from_int(0);
427 bigint num = bigint_copy(b), tmp, resplusbit, bit;
428 if (b->blks[b->size-1] & ((bigchunk)1<<(BITSPERCHUNK-1))) {
429 fprintf(stderr,
430 "Cannot compute square root of negative number.\n");
431 exit(1);
432 }
433 /* initialize bit to the largest power of 4 that is <= b */
434 bit = bigint_alloc(b->size);
435 bit->blks[bit->size-1] = ((bigchunk)1<<(BITSPERCHUNK-2));
436 for (int i = 0; i < bit->size-1; i++)
437 bit->blks[i] = 0;
438 while (bit->blks[bit->size-1] > b->blks[b->size-1])
439 bit->blks[bit->size-1] >>= 2;