crypto/hash.c \
crypto/aesb.c
if ARCH_x86
-minerd_SOURCES += sha2-x86.S scrypt-x86.S aesb-x86.S
+minerd_SOURCES += sha2-x86.S scrypt-x86.S aesb-x86.S crypto/aesb-x86-impl.c
endif
if ARCH_x86_64
minerd_SOURCES += sha2-x64.S scrypt-x64.S aesb-x64.S
fast_aesb_pseudo_round_mut:
_fast_aesb_pseudo_round_mut:
ret
-
- .text
- .globl mul128
- .globl _mul128
-mul128:
-_mul128:
-#if defined(_WIN32) || defined(__CYGWIN__)
- mov %rcx, %rax
- mul %rdx
- mov %r8, (%r8)
-#else
- mov %rdx, %r8
- mov %rdi, %rax
- mul %rsi
- mov %rdx, (%r8)
-#endif
- ret
--- /dev/null
+#pragma once
+
+uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) {
+ // multiplier = ab = a * 2^32 + b
+ // multiplicand = cd = c * 2^32 + d
+ // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d
+ uint64_t a = hi_dword(multiplier);
+ uint64_t b = lo_dword(multiplier);
+ uint64_t c = hi_dword(multiplicand);
+ uint64_t d = lo_dword(multiplicand);
+
+ uint64_t ac = a * c;
+ uint64_t ad = a * d;
+ uint64_t bc = b * c;
+ uint64_t bd = b * d;
+
+ uint64_t adbc = ad + bc;
+ uint64_t adbc_carry = adbc < ad ? 1 : 0;
+
+ // multiplier * multiplicand = product_hi * 2^64 + product_lo
+ uint64_t product_lo = bd + (adbc << 32);
+ uint64_t product_lo_carry = product_lo < bd ? 1 : 0;
+ *product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
+ assert(ac <= *product_hi);
+
+ return product_lo;
+}