uint2048& operator+=(uint2048& operand_a, uint64_t operand_b){
	uint64_t a;
	uint64_t* b;
	uint8_t carry_flag = 0u;

	a = operand_a.parts_[0u];
	b = &(operand_a.parts_[0u]);

	// intrinsic function
	// adcx instruction
	// *c = a + b + carry
	// carry_flag is set to 1 if there is a carry bit
	carry_flag = _addcarry_u64(carry_flag, a, operand_b, b);

	if (carry_flag){
		for (auto i = 1u; i < 32u; ++i){
			a = operand_a.parts_[i];
			b = &(operand_a.parts_[i]);

			// intrinsic function
			// adcx instruction
			// *c = a + b + carry
			carry_flag = _addcarry_u64(carry_flag, a, 0, b);

			if (!carry_flag) break;
		}
	}

	return operand_a;
}
Exemple #2
0
static void
adx_test (void)
{
  volatile unsigned char c;
  unsigned long long x;
  volatile unsigned long long y, sum_ref;

  c = 0;
  x = y = 0xFFFFFFFFFFFFFFFFLL;
  sum_ref = 0xFFFFFFFFFFFFFFFELL;

  /* X = 0xFFFFFFFFFFFFFFFF, Y = 0xFFFFFFFFFFFFFFFF, C = 0.  */
  c = _addcarryx_u64 (c, x, y, &x);
  /* X = 0xFFFFFFFFFFFFFFFE, Y = 0xFFFFFFFFFFFFFFFF, C = 1.  */
  c = _addcarryx_u64 (c, x, y, &x);
  /* X = 0xFFFFFFFFFFFFFFFE, Y = 0xFFFFFFFFFFFFFFFF, C = 1.  */

  if (x != sum_ref)
    abort ();

  c = 0;
  x = y = 0xFFFFFFFFFFFFFFFFLL;
  sum_ref = 0xFFFFFFFFFFFFFFFELL;

  /* X = 0xFFFFFFFFFFFFFFFF, Y = 0xFFFFFFFFFFFFFFFF, C = 0.  */
  c = _addcarry_u64 (c, x, y, &x);
  /* X = 0xFFFFFFFFFFFFFFFE, Y = 0xFFFFFFFFFFFFFFFF, C = 1.  */
  c = _addcarry_u64 (c, x, y, &x);
  /* X = 0xFFFFFFFFFFFFFFFE, Y = 0xFFFFFFFFFFFFFFFF, C = 1.  */

  if (x != sum_ref)
    abort ();

  c = 0;
  x = 1LL;
  y = 0LL;
  sum_ref = 0x0LL;

  /* X = 0x0000000000000001, Y = 0x0000000000000000, C = 0.  */
  c = _subborrow_u64 (c, x, y, &x);
  /* X = 0xFFFFFFFFFFFFFFFF, Y = 0x0000000000000000, C = 1.  */
  c = _subborrow_u64 (c, x, y, &x);
  /* X = 0x0000000000000000, Y = 0x0000000000000000, C = 1.  */

  if (x != sum_ref)
    abort ();
}
uint2048& operator+=(uint2048& operand_a, const uint2048& operand_b){
	uint64_t a, b;
	uint64_t* c;
	uint8_t carry_flag = 0u;

	for (auto i = 0u; i < 32u; ++i){
		a = operand_a.parts_[i];
		b = operand_b.parts_[i];
		c = &(operand_a.parts_[i]);

		// intrinsic function
		// adcx instruction
		// *c = a + b + carry
		// carry_flag is set to 1 if there is a carry bit
		carry_flag = _addcarry_u64(carry_flag, a, b, c);
	}

	return operand_a;
}