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;
   229   230   231   232   233   234   235   236   237   238   239