Skip to content

Commit a83d702

Browse files
committed
GR support
1 parent 14980d8 commit a83d702

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

xmrig/base/tools/cryptonote/umul128.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* This program is free software: you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation, either version 3 of the License, or
5+
* any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
14+
*
15+
* Additional permission under GNU GPL version 3 section 7
16+
*
17+
* If you modify this Program, or any covered work, by linking or combining
18+
* it with OpenSSL (or a modified version of that library), containing parts
19+
* covered by the terms of OpenSSL License and SSLeay License, the licensors
20+
* of this Program grant you additional permission to convey the resulting work.
21+
*
22+
*/
23+
24+
#pragma once
25+
26+
27+
#include <cstdint>
28+
29+
#ifdef XMRIG_64_BIT
30+
# ifdef _MSC_VER
31+
# include <intrin.h>
32+
# pragma intrinsic(_umul128)
33+
# define __umul128 _umul128
34+
# elif defined __GNUC__
35+
static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi)
36+
{
37+
unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b;
38+
*hi = r >> 64;
39+
return (uint64_t) r;
40+
}
41+
# define __umul128 _umul128
42+
# endif
43+
#else
44+
static inline uint64_t __umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) {
45+
// multiplier = ab = a * 2^32 + b
46+
// multiplicand = cd = c * 2^32 + d
47+
// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
48+
uint64_t a = multiplier >> 32;
49+
uint64_t b = multiplier & 0xFFFFFFFF;
50+
uint64_t c = multiplicand >> 32;
51+
uint64_t d = multiplicand & 0xFFFFFFFF;
52+
53+
//uint64_t ac = a * c;
54+
uint64_t ad = a * d;
55+
//uint64_t bc = b * c;
56+
uint64_t bd = b * d;
57+
58+
uint64_t adbc = ad + (b * c);
59+
uint64_t adbc_carry = adbc < ad ? 1 : 0;
60+
61+
// multiplier * multiplicand = product_hi * 2^64 + product_lo
62+
uint64_t product_lo = bd + (adbc << 32);
63+
uint64_t product_lo_carry = product_lo < bd ? 1 : 0;
64+
*product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
65+
66+
return product_lo;
67+
}
68+
#endif

0 commit comments

Comments
 (0)