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