#216 Added ARMv7 support.

This commit is contained in:
XMRig 2017-11-26 22:23:23 +03:00
parent 9100e3fb65
commit aa4f8b6fa7
9 changed files with 74 additions and 16 deletions

View file

@ -64,8 +64,8 @@ set(HEADERS_CRYPTO
src/crypto/soft_aes.h src/crypto/soft_aes.h
) )
if (XMRIG_ARM64) if (XMRIG_ARM)
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_arm64.h) set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_arm.h)
else() else()
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_x86.h) set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_x86.h)
endif() endif()
@ -168,7 +168,7 @@ if (WITH_LIBCPUID)
else() else()
add_definitions(/DXMRIG_NO_LIBCPUID) add_definitions(/DXMRIG_NO_LIBCPUID)
if (XMRIG_ARM64) if (XMRIG_ARM)
set(SOURCES_CPUID src/Cpu_arm.cpp) set(SOURCES_CPUID src/Cpu_arm.cpp)
else() else()
set(SOURCES_CPUID src/Cpu_stub.cpp) set(SOURCES_CPUID src/Cpu_stub.cpp)

View file

@ -9,8 +9,17 @@ endif()
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64)$") if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64)$")
set(XMRIG_ARM64 ON) set(XMRIG_ARM ON)
set(XMRIG_ARMv8 ON)
set(WITH_LIBCPUID OFF) set(WITH_LIBCPUID OFF)
add_definitions(/DXMRIG_ARM) add_definitions(/DXMRIG_ARM)
add_definitions(/DXMRIG_ARMv8)
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7|armv7f|armv7s|armv7k|armv7-a|armv7l)$")
set(XMRIG_ARM ON)
set(XMRIG_ARMv7 ON)
set(WITH_LIBCPUID OFF)
add_definitions(/DXMRIG_ARM)
add_definitions(/DXMRIG_ARMv7)
endif() endif()

View file

@ -14,9 +14,12 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
if (CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) if (XMRIG_ARMv8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crypto -flax-vector-conversions") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crypto -flax-vector-conversions")
elseif (XMRIG_ARMv7)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -flax-vector-conversions")
else() else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
@ -52,9 +55,12 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-missing-braces") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-missing-braces")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
if (CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) if (XMRIG_ARMv8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crypto") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crypto")
elseif (XMRIG_ARMv7)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -march=${CMAKE_SYSTEM_PROCESSOR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -march=${CMAKE_SYSTEM_PROCESSOR}")
else() else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")

View file

@ -47,6 +47,8 @@ void Cpu::initCommon()
{ {
memcpy(m_brand, "Unknown", 7); memcpy(m_brand, "Unknown", 7);
# if defined(XMRIG_ARMv8)
m_flags |= X86_64; m_flags |= X86_64;
m_flags |= AES; m_flags |= AES;
# endif
} }

View file

@ -24,8 +24,8 @@
#include "crypto/CryptoNight.h" #include "crypto/CryptoNight.h"
#if defined(__aarch64__) #if defined(XMRIG_ARM)
# include "crypto/CryptoNight_arm64.h" # include "crypto/CryptoNight_arm.h"
#else #else
# include "crypto/CryptoNight_x86.h" # include "crypto/CryptoNight_x86.h"
#endif #endif
@ -40,12 +40,16 @@ void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, crypt
static void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { static void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) {
# if !defined(XMRIG_ARMv7)
cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx); cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx);
# endif
} }
static void cryptonight_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) { static void cryptonight_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
# if !defined(XMRIG_ARMv7)
cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx); cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx);
# endif
} }
@ -61,12 +65,16 @@ static void cryptonight_av4_softaes_double(const void *input, size_t size, void
#ifndef XMRIG_NO_AEON #ifndef XMRIG_NO_AEON
static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx) { static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
# if !defined(XMRIG_ARMv7)
cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx); cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx);
#endif
} }
static void cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) { static void cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) {
# if !defined(XMRIG_ARMv7)
cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx); cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx);
# endif
} }

View file

@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CRYPTONIGHT_ARM64_H__ #ifndef __CRYPTONIGHT_ARM_H__
#define __CRYPTONIGHT_ARM64_H__ #define __CRYPTONIGHT_ARM_H__
#if defined(XMRIG_ARM) && !defined(__clang__) #if defined(XMRIG_ARM) && !defined(__clang__)
@ -86,12 +86,39 @@ static inline __attribute__((always_inline)) uint64_t _mm_cvtsi128_si64(__m128i
#define EXTRACT64(X) _mm_cvtsi128_si64(X) #define EXTRACT64(X) _mm_cvtsi128_si64(X)
#if defined(XMRIG_ARMv8)
static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi) static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi)
{ {
unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b; unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b;
*hi = r >> 64; *hi = r >> 64;
return (uint64_t) r; return (uint64_t) r;
} }
#else
static inline uint64_t __umul128(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 = multiplier >> 32;
uint64_t b = multiplier & 0xFFFFFFFF;
uint64_t c = multiplicand >> 32;
uint64_t d = multiplicand & 0xFFFFFFFF;
//uint64_t ac = a * c;
uint64_t ad = a * d;
//uint64_t bc = b * c;
uint64_t bd = b * d;
uint64_t adbc = ad + (b * c);
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 = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;
return product_lo;
}
#endif
// This will shift and xor tmp1 into itself as 4 32-bit vals such as // This will shift and xor tmp1 into itself as 4 32-bit vals such as
@ -176,6 +203,7 @@ static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2,
*x6 = soft_aesenc(*x6, key); *x6 = soft_aesenc(*x6, key);
*x7 = soft_aesenc(*x7, key); *x7 = soft_aesenc(*x7, key);
} }
# ifndef XMRIG_ARMv7
else { else {
*x0 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x0), key)); *x0 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x0), key));
*x1 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x1), key)); *x1 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x1), key));
@ -186,6 +214,7 @@ static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2,
*x6 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x6), key)); *x6 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x6), key));
*x7 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x7), key)); *x7 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x7), key));
} }
# endif
} }
@ -338,7 +367,9 @@ inline void cryptonight_hash(const void *__restrict__ input, size_t size, void *
cx = soft_aesenc(cx, _mm_set_epi64x(ah0, al0)); cx = soft_aesenc(cx, _mm_set_epi64x(ah0, al0));
} }
else { else {
# ifndef XMRIG_ARMv7
cx = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0); cx = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
# endif
} }
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
@ -402,8 +433,10 @@ inline void cryptonight_double_hash(const void *__restrict__ input, size_t size,
cx1 = soft_aesenc(cx1, _mm_set_epi64x(ah1, al1)); cx1 = soft_aesenc(cx1, _mm_set_epi64x(ah1, al1));
} }
else { else {
# ifndef XMRIG_ARMv7
cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0); cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0);
cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1); cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1);
# endif
} }
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
@ -455,4 +488,4 @@ inline void cryptonight_double_hash(const void *__restrict__ input, size_t size,
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, static_cast<char*>(output) + 32); extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, static_cast<char*>(output) + 32);
} }
#endif /* __CRYPTONIGHT_ARM64_H__ */ #endif /* __CRYPTONIGHT_ARM_H__ */

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CRYPTONIGHT_P_H__ #ifndef __CRYPTONIGHT_X86_H__
#define __CRYPTONIGHT_P_H__ #define __CRYPTONIGHT_X86_H__
#ifdef __GNUC__ #ifdef __GNUC__
@ -448,4 +448,4 @@ inline void cryptonight_double_hash(const void *__restrict__ input, size_t size,
extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, static_cast<char*>(output) + 32); extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, static_cast<char*>(output) + 32);
} }
#endif /* __CRYPTONIGHT_P_H__ */ #endif /* __CRYPTONIGHT_X86_H__ */

View file

@ -27,7 +27,7 @@
#pragma once #pragma once
#if defined(__aarch64__) #if defined(XMRIG_ARM)
# include "crypto/SSE2NEON.h" # include "crypto/SSE2NEON.h"
#elif defined(__GNUC__) #elif defined(__GNUC__)
# include <x86intrin.h> # include <x86intrin.h>

View file

@ -145,7 +145,7 @@ void ConsoleLog::print(va_list args)
} }
if (!isWritable()) { if (!isWritable()) {
fprintf(stdout, m_buf); fputs(m_buf, stdout);
fflush(stdout); fflush(stdout);
} }
else { else {