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) {
   225   226   227   228   229   230   231   232   233   234   235