예제 #1
0
	MPuint MPuint::operator-(const MPuint& mpu)
	{
		MPuint out;
		LPuint *a1 = m_data->A, *a2 = mpu.m_data->A, *a3 = out.m_data->A;
		int l1 = m_data->len, l2 = mpu.m_data->len;
		
		out.m_data->len = l1;
		unsigned char rem = 0;
		for (int i = 0; i < l2; i++)
		{
			rem = _subborrow_u64(rem, a1[i], a2[i], a3 + i);
		}
		if (rem == 0)
			memcpy(a3 + l2, a1 + l2, (l1 - l2) * sizeof(LPuint));
		else
		{
			for (int i = l2; i < l1; i++)
			{
				rem = _subborrow_u64(rem, a1[i], 0, a3 + i);
			}
		}
		while (a3[out.m_data->len - 1] == 0)
			out.m_data->len--;
		return out;
	}
예제 #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 ();
}
예제 #3
0
uint2048& operator-=(uint2048& operand_a, const uint2048& operand_b){
	uint64_t a, b;
	uint64_t* c;
	uint8_t borrow_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
		// sbb instruction
		// *c = a - (b + borrow)
		// borrow_flag is set to 1 if (a < (b + borrow))
		borrow_flag = _subborrow_u64(borrow_flag, a, b, c);
	}
	return operand_a;
}