diff --git a/CHANGELOG.md b/CHANGELOG.md index 53e24f85..8dc3b169 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,167 +1,213 @@ -# v2.6.0-beta3 -- [#563](https://github.com/xmrig/xmrig/issues/563) **Added [advanced threads mode](https://github.com/xmrig/xmrig/issues/563), now possible configure each thread individually.** -- [#255](https://github.com/xmrig/xmrig/issues/563) Low power mode extended to **triple**, **quard** and **penta** modes. -- [#519](https://github.com/xmrig/xmrig/issues/519) Fixed high donation levels, improved donation start time randomization. -- [#554](https://github.com/xmrig/xmrig/issues/554) Fixed regression with `print-time` option. - -# v2.6.0-beta2 -- Improved performance for `cryptonight v7` especially in double hash mode. -- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was causing issues on some systems. -- Added short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`. -- Fixed regressions (v2.6.0-beta1 affected) - - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. - - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. - - Fixed nonce calculation for `--av 4` (software AES, double hash) was causing reduction of effective hashrate and rejected shares on nicehash. - -# v2.6.0-beta1 - - [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.** - - HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization. - - Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested. - - Added API endpoint `PUT /1/config` to update current config. - - Added API endpoint `GET /1/config` to get current active config. - - Added API endpoint `GET /1/threads` to get current active threads configuration. - - API endpoint `GET /` now deprecated, use `GET /1/summary` instead. - - Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API. - - Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified. - -# v2.5.3 -- Fixed critical bug, in some cases miner was can't recovery connection and switch to failover pool, version 2.5.2 affected. If you use v2.6.0-beta3 this issue doesn't concern you. -- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 support disabled for internal HTTP API. -- Added workaround for nicehash.com if you use `cryptonightv7..nicehash.com` option `variant=1` will be set automatically. - -# v2.5.2 -- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect. - -# v2.5.1 -- [#454](https://github.com/xmrig/xmrig/issues/454) Fixed build with libmicrohttpd version below v0.9.35. -- [#456](https://github.com/xmrig/xmrig/issues/459) Verbose errors related to donation pool was not fully silenced. -- [#459](https://github.com/xmrig/xmrig/issues/459) Fixed regression (version 2.5.0 affected) with connection to **xmr.f2pool.com**. - -# v2.5.0 -- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.** -- Added full IPv6 support. -- Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option. -- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly. -- [#428](https://github.com/xmrig/xmrig/issues/428) Fixed regression (version 2.4.5 affected) with CPU cache size detection. - -# v2.4.5 -- [#324](https://github.com/xmrig/xmrig/pull/324) Fixed build without libmicrohttpd (CMake cache issue). -- [#341](https://github.com/xmrig/xmrig/issues/341) Fixed wrong exit code and added command line option `--dry-run`. -- [#385](https://github.com/xmrig/xmrig/pull/385) Up to 20% performance increase for non-AES CPU and fixed Intel Core 2 cache detection. - -# v2.4.4 - - Added libmicrohttpd version to --version output. - - Fixed bug in singal handler, in some cases miner wasn't shutdown properly. - - Fixed recent MSVC 2017 version detection. - - [#279](https://github.com/xmrig/xmrig/pull/279) Fixed build on some macOS versions. - -# v2.4.3 - - [#94](https://github.com/xmrig/xmrig/issues/94#issuecomment-342019257) [#216](https://github.com/xmrig/xmrig/issues/216) Added **ARMv8** and **ARMv7** support. Hardware AES supported, thanks [Imran Yusuff](https://github.com/imranyusuff). - - [#157](https://github.com/xmrig/xmrig/issues/157) [#196](https://github.com/xmrig/xmrig/issues/196) Fixed Linux compile issues. - - [#184](https://github.com/xmrig/xmrig/issues/184) Fixed cache size detection for CPUs with disabled Hyper-Threading. - - [#200](https://github.com/xmrig/xmrig/issues/200) In some cases miner was doesn't write log to stdout. - -# v2.4.2 - - [#60](https://github.com/xmrig/xmrig/issues/60) Added FreeBSD support, thanks [vcambur](https://github.com/vcambur). - - [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com. - -# v2.4.1 - - [#147](https://github.com/xmrig/xmrig/issues/147) Fixed comparability with monero-stratum. - -# v2.4.0 - - Added [HTTP API](https://github.com/xmrig/xmrig/wiki/API). - - Added comments support in config file. - - libjansson replaced to rapidjson. - - [#98](https://github.com/xmrig/xmrig/issues/98) Ignore `keepalive` option with minergate.com and nicehash.com. - - [#101](https://github.com/xmrig/xmrig/issues/101) Fixed MSVC 2017 (15.3) compile time version detection. - - [#108](https://github.com/xmrig/xmrig/issues/108) Silently ignore invalid values for `donate-level` option. - - [#111](https://github.com/xmrig/xmrig/issues/111) Fixed build without AEON support. - -# v2.3.1 -- [#68](https://github.com/xmrig/xmrig/issues/68) Fixed compatibility with Docker containers, was nothing print on console. - -# v2.3.0 -- Added `--cpu-priority` option (0 idle, 2 normal to 5 highest). -- Added `--user-agent` option, to set custom user-agent string for pool. For example `cpuminer-multi/0.1`. -- Added `--no-huge-pages` option, to disable huge pages support. -- [#62](https://github.com/xmrig/xmrig/issues/62) Don't send the login to the dev pool. -- Force reconnect if pool block miner IP address. helps switch to backup pool. -- Fixed: failed open default config file if path contains non English characters. -- Fixed: error occurred if try use unavailable stdin or stdout, regression since version 2.2.0. -- Fixed: message about huge pages support successfully enabled on Windows was not shown in release builds. - -# v2.2.1 -- Fixed [terminal issues](https://github.com/xmrig/xmrig-proxy/issues/2#issuecomment-319914085) after exit on Linux and OS X. - -# v2.2.0 -- [#46](https://github.com/xmrig/xmrig/issues/46) Restored config file support. Now possible use multiple config files and combine with command line options also added support for default config. -- Improved colors support on Windows, now used uv_tty, legacy code removed. -- QuickEdit Mode now disabled on Windows. -- Added interactive commands in console window:: **h**ashrate, **p**ause, **r**esume. -- Fixed autoconf mode for AMD FX CPUs. - -# v2.1.0 -- [#40](https://github.com/xmrig/xmrig/issues/40) -Improved miner shutdown, fixed crash on exit for Linux and OS X. -- Fixed, login request was contain malformed JSON if username or password has some special characters for example `\`. -- [#220](https://github.com/fireice-uk/xmr-stak-cpu/pull/220) Better support for Round Robin DNS, IP address now always chosen randomly instead of stuck on first one. -- Changed donation address, new [xmrig-proxy](https://github.com/xmrig/xmrig-proxy) is coming soon. - -# v2.0.2 -- Better deal with possible duplicate jobs from pool, show warning and ignore duplicates. -- For Windows builds libuv updated to version 1.13.1 and gcc to 7.1.0. - -# v2.0.1 - - [#27](https://github.com/xmrig/xmrig/issues/27) Fixed possibility crash on 32bit systems. - -# v2.0.0 - - Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3` - - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-l, --log-file=FILE` to write log to file. - - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-S, --syslog` to use syslog for logging, Linux only. - - [#18](https://github.com/xmrig/xmrig/issues/18) Added nice messages for accepted/rejected shares with diff and network latency. - - [#20](https://github.com/xmrig/xmrig/issues/20) Fixed `--cpu-affinity` for more than 32 threads. - - Fixed Windows XP support. - - Fixed regression, option `--no-color` was not fully disable colored output. - - Show resolved pool IP address in miner output. - -# v1.0.1 -- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected. - -# v1.0.0 -- Miner complete rewritten in C++ with libuv. -- This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions. -- This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new). -- Added new option `--print-time=N`, print hashrate report every N seconds. -- New hashrate reports, by default every 60 secons. -- Added Microsoft Visual C++ 2015 and 2017 support. -- Removed dependency on libcurl. -- To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch. - -# v0.8.2 -- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). - -# v0.8.2 -- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). -- Fixed gcc 7.1 support. - -# v0.8.1 -- Added nicehash support, detects automaticaly by pool URL, for example `cryptonight.eu.nicehash.com:3355` or manually via option `--nicehash`. - -# v0.8.0 -- Added double hash mode, also known as lower power mode. `--av=2` and `--av=4`. -- Added smart automatic CPU configuration. Default threads count now depends on size of the L3 cache of CPU. -- Added CryptoNight-Lite support for AEON `-a cryptonight-lite`. -- Added `--max-cpu-usage` option for auto CPU configuration mode. -- Added `--safe` option for adjust threads and algorithm variations to current CPU. -- No more manual steps to enable huge pages on Windows. XMRig will do it automatically. -- Removed BMI2 algorithm variation. -- Removed default pool URL. - -# v0.6.0 -- Added automatic cryptonight self test. -- New software AES algorithm variation. Will be automatically selected if cpu not support AES-NI. -- Added 32 bit builds. -- Documented [algorithm variations](https://github.com/xmrig/xmrig#algorithm-variations). - -# v0.5.0 -- Initial public release. +# v2.8.1 +- [#768](https://github.com/xmrig/xmrig/issues/768) Fixed build with Visual Studio 2015. +- [#769](https://github.com/xmrig/xmrig/issues/769) Fixed regression, some ANSI escape sequences was in log with disabled colors. +- [#777](https://github.com/xmrig/xmrig/issues/777) Better report about pool connection issues. +- Simplified checks for ASM auto detection, only AES support necessary. +- Added missing options to `--help` output. + +# v2.8.0 +- **[#753](https://github.com/xmrig/xmrig/issues/753) Added new algorithm [CryptoNight variant 2](https://github.com/xmrig/xmrig/issues/753) for Monero fork, thanks [@SChernykh](https://github.com/SChernykh).** + - Added global and per thread option `"asm"` and and command line equivalent. +- **[#758](https://github.com/xmrig/xmrig/issues/758) Added SSL/TLS support for secure connections to pools.** + - Added per pool options `"tls"` and `"tls-fingerprint"` and command line equivalents. +- [#767](https://github.com/xmrig/xmrig/issues/767) Added config autosave feature, same with GPU miners. +- [#245](https://github.com/xmrig/xmrig-proxy/issues/245) Fixed API ID collision when run multiple miners on same machine. +- [#757](https://github.com/xmrig/xmrig/issues/757) Fixed send buffer overflow. + +# v2.6.4 +- [#700](https://github.com/xmrig/xmrig/issues/700) `cryptonight-lite/ipbc` replaced to `cryptonight-heavy/tube` for **Bittube (TUBE)**. +- Added `cryptonight/rto` (cryptonight variant 1 with IPBC/TUBE mod) variant for **Arto (RTO)** coin. +- Added `cryptonight/xao` (original cryptonight with bigger iteration count) variant for **Alloy (XAO)** coin. +- Better variant detection for **nicehash.com** and **minergate.com**. +- [#692](https://github.com/xmrig/xmrig/issues/692) Added support for specify both algorithm and variant via single `algo` option. + +# v2.6.3 +- **Added support for new cryptonight-heavy variant xhv** (`cn-heavy/xhv`) for upcoming Haven Protocol fork. +- **Added support for new cryptonight variant msr** (`cn/msr`) also known as `cryptonight-fast` for upcoming Masari fork. +- Added new detailed hashrate report. +- [#446](https://github.com/xmrig/xmrig/issues/446) Likely fixed SIGBUS error on 32 bit ARM CPUs. +- [#551](https://github.com/xmrig/xmrig/issues/551) Fixed `cn-heavy` algorithm on ARMv8. +- [#614](https://github.com/xmrig/xmrig/issues/614) Fixed display issue with huge pages percentage when colors disabled. +- [#615](https://github.com/xmrig/xmrig/issues/615) Fixed build without libcpuid. +- [#629](https://github.com/xmrig/xmrig/pull/629) Fixed file logging with non-seekable files. +- [#672](https://github.com/xmrig/xmrig/pull/672) Reverted back `cryptonight-light` and exit if no valid algorithm specified. + +# v2.6.2 + - [#607](https://github.com/xmrig/xmrig/issues/607) Fixed donation bug. + - [#610](https://github.com/xmrig/xmrig/issues/610) Fixed ARM build. + +# v2.6.1 + - [#168](https://github.com/xmrig/xmrig-proxy/issues/168) Added support for [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/blob/dev/doc/STRATUM_EXT.md#1-mining-algorithm-negotiation). + - Added IPBC coin support, base algorithm `cn-lite` variant `ipbc`. + - [#581](https://github.com/xmrig/xmrig/issues/581) Added support for upcoming Stellite (XTL) fork, base algorithm `cn` variant `xtl`, variant can set now, no need do it after fork. + - Added support for **rig-id** stratum protocol extensions, compatible with xmr-stak. + - Changed behavior for option `variant=-1` for `cryptonight`, now variant is `1` by default, if you mine old coins need change `variant` to `0`. + - A lot of small fixes and better unification with proxy code. + +# v2.6.0-beta3 +- [#563](https://github.com/xmrig/xmrig/issues/563) **Added [advanced threads mode](https://github.com/xmrig/xmrig/issues/563), now possible configure each thread individually.** +- [#255](https://github.com/xmrig/xmrig/issues/563) Low power mode extended to **triple**, **quard** and **penta** modes. +- [#519](https://github.com/xmrig/xmrig/issues/519) Fixed high donation levels, improved donation start time randomization. +- [#554](https://github.com/xmrig/xmrig/issues/554) Fixed regression with `print-time` option. + +# v2.6.0-beta2 +- Improved performance for `cryptonight v7` especially in double hash mode. +- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was causing issues on some systems. +- Added short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`. +- Fixed regressions (v2.6.0-beta1 affected) + - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. + - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. + - Fixed nonce calculation for `--av 4` (software AES, double hash) was causing reduction of effective hashrate and rejected shares on nicehash. + +# v2.6.0-beta1 + - [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.** + - HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization. + - Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested. + - Added API endpoint `PUT /1/config` to update current config. + - Added API endpoint `GET /1/config` to get current active config. + - Added API endpoint `GET /1/threads` to get current active threads configuration. + - API endpoint `GET /` now deprecated, use `GET /1/summary` instead. + - Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API. + - Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified. + +# v2.5.3 +- Fixed critical bug, in some cases miner was can't recovery connection and switch to failover pool, version 2.5.2 affected. If you use v2.6.0-beta3 this issue doesn't concern you. +- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 support disabled for internal HTTP API. +- Added workaround for nicehash.com if you use `cryptonightv7..nicehash.com` option `variant=1` will be set automatically. + +# v2.5.2 +- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect. + +# v2.5.1 +- [#454](https://github.com/xmrig/xmrig/issues/454) Fixed build with libmicrohttpd version below v0.9.35. +- [#456](https://github.com/xmrig/xmrig/issues/459) Verbose errors related to donation pool was not fully silenced. +- [#459](https://github.com/xmrig/xmrig/issues/459) Fixed regression (version 2.5.0 affected) with connection to **xmr.f2pool.com**. + +# v2.5.0 +- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.** +- Added full IPv6 support. +- Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option. +- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly. +- [#428](https://github.com/xmrig/xmrig/issues/428) Fixed regression (version 2.4.5 affected) with CPU cache size detection. + +# v2.4.5 +- [#324](https://github.com/xmrig/xmrig/pull/324) Fixed build without libmicrohttpd (CMake cache issue). +- [#341](https://github.com/xmrig/xmrig/issues/341) Fixed wrong exit code and added command line option `--dry-run`. +- [#385](https://github.com/xmrig/xmrig/pull/385) Up to 20% performance increase for non-AES CPU and fixed Intel Core 2 cache detection. + +# v2.4.4 + - Added libmicrohttpd version to --version output. + - Fixed bug in singal handler, in some cases miner wasn't shutdown properly. + - Fixed recent MSVC 2017 version detection. + - [#279](https://github.com/xmrig/xmrig/pull/279) Fixed build on some macOS versions. + +# v2.4.3 + - [#94](https://github.com/xmrig/xmrig/issues/94#issuecomment-342019257) [#216](https://github.com/xmrig/xmrig/issues/216) Added **ARMv8** and **ARMv7** support. Hardware AES supported, thanks [Imran Yusuff](https://github.com/imranyusuff). + - [#157](https://github.com/xmrig/xmrig/issues/157) [#196](https://github.com/xmrig/xmrig/issues/196) Fixed Linux compile issues. + - [#184](https://github.com/xmrig/xmrig/issues/184) Fixed cache size detection for CPUs with disabled Hyper-Threading. + - [#200](https://github.com/xmrig/xmrig/issues/200) In some cases miner was doesn't write log to stdout. + +# v2.4.2 + - [#60](https://github.com/xmrig/xmrig/issues/60) Added FreeBSD support, thanks [vcambur](https://github.com/vcambur). + - [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com. + +# v2.4.1 + - [#147](https://github.com/xmrig/xmrig/issues/147) Fixed comparability with monero-stratum. + +# v2.4.0 + - Added [HTTP API](https://github.com/xmrig/xmrig/wiki/API). + - Added comments support in config file. + - libjansson replaced to rapidjson. + - [#98](https://github.com/xmrig/xmrig/issues/98) Ignore `keepalive` option with minergate.com and nicehash.com. + - [#101](https://github.com/xmrig/xmrig/issues/101) Fixed MSVC 2017 (15.3) compile time version detection. + - [#108](https://github.com/xmrig/xmrig/issues/108) Silently ignore invalid values for `donate-level` option. + - [#111](https://github.com/xmrig/xmrig/issues/111) Fixed build without AEON support. + +# v2.3.1 +- [#68](https://github.com/xmrig/xmrig/issues/68) Fixed compatibility with Docker containers, was nothing print on console. + +# v2.3.0 +- Added `--cpu-priority` option (0 idle, 2 normal to 5 highest). +- Added `--user-agent` option, to set custom user-agent string for pool. For example `cpuminer-multi/0.1`. +- Added `--no-huge-pages` option, to disable huge pages support. +- [#62](https://github.com/xmrig/xmrig/issues/62) Don't send the login to the dev pool. +- Force reconnect if pool block miner IP address. helps switch to backup pool. +- Fixed: failed open default config file if path contains non English characters. +- Fixed: error occurred if try use unavailable stdin or stdout, regression since version 2.2.0. +- Fixed: message about huge pages support successfully enabled on Windows was not shown in release builds. + +# v2.2.1 +- Fixed [terminal issues](https://github.com/xmrig/xmrig-proxy/issues/2#issuecomment-319914085) after exit on Linux and OS X. + +# v2.2.0 +- [#46](https://github.com/xmrig/xmrig/issues/46) Restored config file support. Now possible use multiple config files and combine with command line options also added support for default config. +- Improved colors support on Windows, now used uv_tty, legacy code removed. +- QuickEdit Mode now disabled on Windows. +- Added interactive commands in console window:: **h**ashrate, **p**ause, **r**esume. +- Fixed autoconf mode for AMD FX CPUs. + +# v2.1.0 +- [#40](https://github.com/xmrig/xmrig/issues/40) +Improved miner shutdown, fixed crash on exit for Linux and OS X. +- Fixed, login request was contain malformed JSON if username or password has some special characters for example `\`. +- [#220](https://github.com/fireice-uk/xmr-stak-cpu/pull/220) Better support for Round Robin DNS, IP address now always chosen randomly instead of stuck on first one. +- Changed donation address, new [xmrig-proxy](https://github.com/xmrig/xmrig-proxy) is coming soon. + +# v2.0.2 +- Better deal with possible duplicate jobs from pool, show warning and ignore duplicates. +- For Windows builds libuv updated to version 1.13.1 and gcc to 7.1.0. + +# v2.0.1 + - [#27](https://github.com/xmrig/xmrig/issues/27) Fixed possibility crash on 32bit systems. + +# v2.0.0 + - Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3` + - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-l, --log-file=FILE` to write log to file. + - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-S, --syslog` to use syslog for logging, Linux only. + - [#18](https://github.com/xmrig/xmrig/issues/18) Added nice messages for accepted/rejected shares with diff and network latency. + - [#20](https://github.com/xmrig/xmrig/issues/20) Fixed `--cpu-affinity` for more than 32 threads. + - Fixed Windows XP support. + - Fixed regression, option `--no-color` was not fully disable colored output. + - Show resolved pool IP address in miner output. + +# v1.0.1 +- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected. + +# v1.0.0 +- Miner complete rewritten in C++ with libuv. +- This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions. +- This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new). +- Added new option `--print-time=N`, print hashrate report every N seconds. +- New hashrate reports, by default every 60 secons. +- Added Microsoft Visual C++ 2015 and 2017 support. +- Removed dependency on libcurl. +- To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch. + +# v0.8.2 +- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). + +# v0.8.2 +- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). +- Fixed gcc 7.1 support. + +# v0.8.1 +- Added nicehash support, detects automaticaly by pool URL, for example `cryptonight.eu.nicehash.com:3355` or manually via option `--nicehash`. + +# v0.8.0 +- Added double hash mode, also known as lower power mode. `--av=2` and `--av=4`. +- Added smart automatic CPU configuration. Default threads count now depends on size of the L3 cache of CPU. +- Added CryptoNight-Lite support for AEON `-a cryptonight-lite`. +- Added `--max-cpu-usage` option for auto CPU configuration mode. +- Added `--safe` option for adjust threads and algorithm variations to current CPU. +- No more manual steps to enable huge pages on Windows. XMRig will do it automatically. +- Removed BMI2 algorithm variation. +- Removed default pool URL. + +# v0.6.0 +- Added automatic cryptonight self test. +- New software AES algorithm variation. Will be automatically selected if cpu not support AES-NI. +- Added 32 bit builds. +- Documented [algorithm variations](https://github.com/xmrig/xmrig#algorithm-variations). + +# v0.5.0 +- Initial public release. diff --git a/CMakeLists.txt b/CMakeLists.txt index b26b1d93..1becac5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,14 @@ cmake_minimum_required(VERSION 2.8) project(xmrig) -option(WITH_LIBCPUID "Use Libcpuid" ON) -option(WITH_AEON "CryptoNight-Lite support" ON) -option(WITH_SUMO "CryptoNight-Heavy support" ON) -option(WITH_IPBC "CryptoNight-IPBC support" ON) -option(WITH_HTTPD "HTTP REST API" ON) -option(BUILD_STATIC "Build static binary" OFF) +option(WITH_LIBCPUID "Use Libcpuid" ON) +option(WITH_AEON "CryptoNight-Lite support" ON) +option(WITH_SUMO "CryptoNight-Heavy support" ON) +option(WITH_HTTPD "HTTP REST API" ON) +option(WITH_DEBUG_LOG "Enable debug log output" OFF) +option(WITH_TLS "Enable OpenSSL support" ON) +option(WITH_ASM "Enable ASM PoW implementations" ON) +option(BUILD_STATIC "Build static binary" OFF) include (CheckIncludeFile) include (cmake/cpu.cmake) @@ -19,8 +21,20 @@ set(HEADERS src/common/config/ConfigLoader.h src/common/config/ConfigWatcher.h src/common/Console.h + src/common/cpu/Cpu.h src/common/crypto/Algorithm.h src/common/crypto/keccak.h + src/common/interfaces/IClientListener.h + src/common/interfaces/IConfig.h + src/common/interfaces/IConfigCreator.h + src/common/interfaces/IConsoleListener.h + src/common/interfaces/IControllerListener.h + src/common/interfaces/ICpuInfo.h + src/common/interfaces/ILogBackend.h + src/common/interfaces/IStrategy.h + src/common/interfaces/IStrategyListener.h + src/common/interfaces/IWatcherListener.h + src/common/log/BasicLog.h src/common/log/ConsoleLog.h src/common/log/FileLog.h src/common/log/Log.h @@ -36,21 +50,10 @@ set(HEADERS src/common/utils/c_str.h src/common/utils/mm_malloc.h src/common/xmrig.h - src/core/Config.cpp src/core/ConfigLoader_platform.h src/core/Controller.h - src/Cpu.h - src/interfaces/IClientListener.h - src/interfaces/IConfig.h - src/interfaces/IConfigCreator.h - src/interfaces/IConsoleListener.h - src/interfaces/IControllerListener.h src/interfaces/IJobResultListener.h - src/interfaces/ILogBackend.h - src/interfaces/IStrategy.h - src/interfaces/IStrategyListener.h src/interfaces/IThread.h - src/interfaces/IWatcherListener.h src/interfaces/IWorker.h src/Mem.h src/net/JobResult.h @@ -96,6 +99,7 @@ set(SOURCES src/common/Console.cpp src/common/crypto/Algorithm.cpp src/common/crypto/keccak.cpp + src/common/log/BasicLog.cpp src/common/log/ConsoleLog.cpp src/common/log/FileLog.cpp src/common/log/Log.cpp @@ -133,7 +137,6 @@ if (WIN32) res/app.rc src/App_win.cpp src/common/Platform_win.cpp - src/Cpu_win.cpp src/Mem_win.cpp ) @@ -143,18 +146,16 @@ elseif (APPLE) set(SOURCES_OS src/App_unix.cpp src/common/Platform_mac.cpp - src/Cpu_mac.cpp src/Mem_unix.cpp ) else() set(SOURCES_OS src/App_unix.cpp src/common/Platform_unix.cpp - src/Cpu_unix.cpp src/Mem_unix.cpp ) - set(EXTRA_LIBS pthread rt) + set(EXTRA_LIBS pthread rt dl) endif() if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD) @@ -170,7 +171,6 @@ endif() add_definitions(/D__STDC_FORMAT_MACROS) add_definitions(/DUNICODE) -#add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") @@ -183,17 +183,21 @@ if (WITH_LIBCPUID) include_directories(src/3rdparty/libcpuid) set(CPUID_LIB cpuid) - set(SOURCES_CPUID src/Cpu.cpp) + set(SOURCES_CPUID src/core/cpu/AdvancedCpuInfo.h src/core/cpu/AdvancedCpuInfo.cpp src/core/cpu/Cpu.cpp) else() add_definitions(/DXMRIG_NO_LIBCPUID) + set(SOURCES_CPUID src/common/cpu/BasicCpuInfo.h src/common/cpu/Cpu.cpp) if (XMRIG_ARM) - set(SOURCES_CPUID src/Cpu_arm.cpp) + set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo_arm.cpp) else() - set(SOURCES_CPUID src/Cpu_stub.cpp) + set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo.cpp) endif() endif() +include(cmake/OpenSSL.cmake) +include(cmake/asm.cmake) + CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H) if (HAVE_SYSLOG_H) add_definitions(/DHAVE_SYSLOG_H) @@ -233,6 +237,7 @@ if (WITH_HTTPD) message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support") endif() else() + set(HTTPD_SOURCES "") set(MHD_LIBRARY "") add_definitions(/DXMRIG_NO_HTTPD) add_definitions(/DXMRIG_NO_API) @@ -246,5 +251,9 @@ if (BUILD_STATIC) set(CMAKE_EXE_LINKER_FLAGS " -static") endif() -add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES}) -target_link_libraries(xmrig ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB}) +if (WITH_DEBUG_LOG) + add_definitions(/DAPP_DEBUG) +endif() + +add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES}) +target_link_libraries(${PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB}) diff --git a/README.md b/README.md index 3d438c5a..9ad83679 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # XMRig -:warning: **You must update miners to version 2.5 before April 6 due [Monero PoW change](https://getmonero.org/2018/02/11/PoW-change-and-key-reuse.html).** +:warning: **[Monero will change PoW algorithm on October 18](https://github.com/xmrig/xmrig/issues/753), all miners and proxy should be updated to [v2.8+](https://github.com/xmrig/xmrig/releases/tag/v2.8.1)** :warning: [![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases) [![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases) @@ -52,14 +52,21 @@ Use [config.xmrig.com](https://config.xmrig.com/xmrig) to generate, edit or shar ### Options ``` - -a, --algo=ALGO cryptonight (default) or cryptonight-lite + -a, --algo=ALGO specify the algorithm to use + cryptonight + cryptonight-lite + cryptonight-heavy -o, --url=URL URL of mining server -O, --userpass=U:P username:password pair for mining server -u, --user=USERNAME username for mining server -p, --pass=PASSWORD password for mining server + --rig-id=ID rig identifier for pool-side statistics (needs pool support) -t, --threads=N number of miner threads -v, --av=N algorithm variation, 0 auto select - -k, --keepalive send keepalived for prevent timeout (need pool support) + -k, --keepalive send keepalived packet for prevent timeout (needs pool support) + --nicehash enable nicehash.com support + --tls enable SSL/TLS support (needs pool support) + --tls-fingerprint=F pool TLS certificate fingerprint, if set enable strict certificate pinning -r, --retries=N number of times to retry before switch to backup server (default: 5) -R, --retry-pause=N time to pause between retries (default: 5) --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1 @@ -75,23 +82,38 @@ Use [config.xmrig.com](https://config.xmrig.com/xmrig) to generate, edit or shar -S, --syslog use system log for output messages --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75) --safe safe adjust threads and av settings for current CPU - --nicehash enable nicehash/xmrig-proxy support + --asm=ASM ASM code for cn/2, possible values: auto, none, intel, ryzen. --print-time=N print hashrate report every N seconds --api-port=N port for the miner API --api-access-token=T access token for API --api-worker-id=ID custom worker-id for API + --api-id=ID custom instance ID for API + --api-ipv6 enable IPv6 support for API + --api-no-restricted enable full remote access (only if API token set) + --dry-run test configuration and exit -h, --help display this help and exit -V, --version output version information and exit ``` -Also you can use configuration via config file, default **config.json**. You can load multiple config files and combine it with command line options. +Also you can use configuration via config file, default name **config.json**. Some options available only via config file: [`autosave`](https://github.com/xmrig/xmrig/issues/767), [`hw-aes`](https://github.com/xmrig/xmrig/issues/563). `watch` option currently not implemented in miners only in proxy. ## Algorithm variations -Since version 0.8.0. -* `--av=1` For CPUs with hardware AES. -* `--av=2` Lower power mode (double hash) of `1`. -* `--av=3` Software AES implementation. -* `--av=4` Lower power mode (double hash) of `3`. + +- `av` option used for automatic and simple threads mode (when you specify only threads count). +- For [advanced threads mode](https://github.com/xmrig/xmrig/issues/563) each thread configured individually and `av` option not used. + +| av | Hashes per round | Hardware AES | +|----|------------------|--------------| +| 1 | 1 (Single) | yes | +| 2 | 2 (Double) | yes | +| 3 | 1 (Single) | no | +| 4 | 2 (Double) | no | +| 5 | 3 (Triple) | yes | +| 6 | 4 (Quard) | yes | +| 7 | 5 (Penta) | yes | +| 8 | 3 (Triple) | no | +| 9 | 4 (Quard) | no | +| 10 | 5 (Penta) | no | ## Common Issues ### HUGE PAGES unavailable @@ -100,8 +122,7 @@ Since version 0.8.0. ## Other information * No HTTP support, only stratum protocol support. -* No TLS support. -* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`. +* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via option `donate-level`. ### CPU mining performance @@ -124,12 +145,17 @@ Please note performance is highly dependent on system load. The numbers above ar ## Release checksums ### SHA-256 ``` -6b32fefb356b27caa2180be17755d09639f0654096a1a0c61e8f10f4f2ac1626 xmrig-2.6.0-beta3-xenial-amd64.tar.gz/xmrig-2.6.0-beta3/xmrig -c8b40f4d7aac9d0cc7c3d02cadeac91b0bdb034aae2fb6b415d503272eabb987 xmrig-2.6.0-beta3-gcc-win32.zip/xmrig.exe -32cf7958f97a23296186e38a4addb9cf234adcbd9c7914b15e4209a87fe272e7 xmrig-2.6.0-beta3-gcc-win64.zip/xmrig.exe -4f176ee4c4be52701edc0d573cf9647c4aacbb4ff14975b80b98e6fe63068542 xmrig-2.6.0-beta3-msvc-win64.zip/xmrig.exe +fd909cef75c65c1ee8facd78e968c359e4ac4d2f0b2aaef8c6d3e0138979d0ea xmrig-2.8.1-xenial-amd64.tar.gz/xmrig-2.8.1/xmrig +e4987eaec57c1784c423e03978e22262adf070ab3ad7b2a6ce8d0d0626db4cbd xmrig-2.8.1-xenial-amd64.tar.gz/xmrig-2.8.1/xmrig-notls +4ebf6053513c8b72b46f54481f33367aae6356fc5f271c9236d708a34cd16e2a xmrig-2.8.1-gcc-win32.zip/xmrig.exe +f4ce5b76a611f6768c9a035eae1e49f61666f3e5370b54bd447ecc3b0098efcb xmrig-2.8.1-gcc-win32.zip/xmrig-notls.exe +39259979b4228899c0ef985bcfc283e169afd44323eedb0341144dbc0c0f30e9 xmrig-2.8.1-gcc-win64.zip/xmrig.exe +68af0f11b29b9b67414d0b661446baa0ad6020598c04c5d0cf24797167753117 xmrig-2.8.1-gcc-win64.zip/xmrig-notls.exe +5d8b94157ebb4a7729f0eb8622945c266b756c994c60f91514b329edeb287867 xmrig-2.8.1-msvc-win64.zip/xmrig.exe +d97c691d6044f916b9253820832f1a08402bb63aa75fb146ea8c31f51cebe974 xmrig-2.8.1-msvc-win64.zip/xmrig-notls.exe ``` ## Contacts * support@xmrig.com * [reddit](https://www.reddit.com/user/XMRig/) +* [twitter](https://twitter.com/xmrig_dev) diff --git a/cmake/OpenSSL.cmake b/cmake/OpenSSL.cmake new file mode 100644 index 00000000..ed287e7e --- /dev/null +++ b/cmake/OpenSSL.cmake @@ -0,0 +1,23 @@ +if (WITH_TLS) + set(OPENSSL_ROOT_DIR ${XMRIG_DEPS}) + + if (WIN32) + set(OPENSSL_USE_STATIC_LIBS TRUE) + set(OPENSSL_MSVC_STATIC_RT TRUE) + + set(EXTRA_LIBS ${EXTRA_LIBS} Crypt32) + endif() + + find_package(OpenSSL) + + if (OPENSSL_FOUND) + set(TLS_SOURCES src/common/net/Tls.h src/common/net/Tls.cpp) + include_directories(${OPENSSL_INCLUDE_DIR}) + else() + message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support") + endif() +else() + set(TLS_SOURCES "") + set(OPENSSL_LIBRARIES "") + add_definitions(/DXMRIG_NO_TLS) +endif() diff --git a/cmake/asm.cmake b/cmake/asm.cmake new file mode 100644 index 00000000..358d5666 --- /dev/null +++ b/cmake/asm.cmake @@ -0,0 +1,33 @@ +if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8) + set(XMRIG_ASM_LIBRARY "xmrig-asm") + + if (CMAKE_C_COMPILER_ID MATCHES MSVC) + enable_language(ASM_MASM) + + if (MSVC_TOOLSET_VERSION GREATER_EQUAL 141) + set(XMRIG_ASM_FILE "src/crypto/asm/cnv2_main_loop.asm") + else() + set(XMRIG_ASM_FILE "src/crypto/asm/win64/cnv2_main_loop.asm") + endif() + + set_property(SOURCE ${XMRIG_ASM_FILE} PROPERTY ASM_MASM) + else() + enable_language(ASM) + + if (WIN32 AND CMAKE_C_COMPILER_ID MATCHES GNU) + set(XMRIG_ASM_FILE "src/crypto/asm/win64/cnv2_main_loop.S") + else() + set(XMRIG_ASM_FILE "src/crypto/asm/cnv2_main_loop.S") + endif() + + set_property(SOURCE ${XMRIG_ASM_FILE} PROPERTY C) + endif() + + add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILE}) + set(XMRIG_ASM_SOURCES src/crypto/Asm.h src/crypto/Asm.cpp) + set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C) +else() + set(XMRIG_ASM_SOURCES "") + set(XMRIG_ASM_LIBRARY "") + add_definitions(/DXMRIG_NO_ASM) +endif() diff --git a/cmake/flags.cmake b/cmake/flags.cmake index 498f2165..8bc14804 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -15,7 +15,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-class-memaccess") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s") if (XMRIG_ARMv8) diff --git a/doc/ALGORITHMS.md b/doc/ALGORITHMS.md new file mode 100644 index 00000000..835a1d49 --- /dev/null +++ b/doc/ALGORITHMS.md @@ -0,0 +1,31 @@ +# Algorithms + +XMRig uses a different way to specify algorithms, compared to other miners. + +Algorithm selection splitted to 2 parts: + + * Global base algorithm per miner or proxy instance, `algo` option. Possible values: `cryptonight`, `cryptonight-lite`, `cryptonight-heavy`. + * Algorithm variant specified separately for each pool, `variant` option. + * [Full table for supported algorithm and variants.](https://github.com/xmrig/xmrig-proxy/blob/master/doc/STRATUM_EXT.md#14-algorithm-names-and-variants) + +#### Example +```json +{ + "algo": "cryptonight", + ... + "pools": [ + { + "url": "...", + "variant": 1, + ... + } + ], + ... +} +``` + +## Mining algorithm negotiation +If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) miner will choice proper variant automaticaly and if you choice wrong base algorithm you will see error message. + +Pools with mining algorithm negotiation support. + * [www.hashvault.pro](https://www.hashvault.pro/) diff --git a/res/app.rc b/res/app.rc index 800ce2dd..037d842a 100644 --- a/res/app.rc +++ b/res/app.rc @@ -4,8 +4,8 @@ IDI_ICON1 ICON DISCARDABLE "app.ico" VS_VERSION_INFO VERSIONINFO - FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_BUILD,APP_VER_REV - PRODUCTVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_BUILD,APP_VER_REV + FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0 + PRODUCTVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG diff --git a/src/3rdparty/libcpuid/asm-bits.c b/src/3rdparty/libcpuid/asm-bits.c index b8e32284..bfabd404 100644 --- a/src/3rdparty/libcpuid/asm-bits.c +++ b/src/3rdparty/libcpuid/asm-bits.c @@ -1,825 +1,836 @@ -/* - * Copyright 2008 Veselin Georgiev, - * anrieffNOSPAM @ mgail_DOT.com (convert to gmail) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "libcpuid.h" -#include "asm-bits.h" - -int cpuid_exists_by_eflags(void) -{ -#if defined(PLATFORM_X64) - return 1; /* CPUID is always present on the x86_64 */ -#elif defined(PLATFORM_X86) -# if defined(COMPILER_GCC) - int result; - __asm __volatile( - " pushfl\n" - " pop %%eax\n" - " mov %%eax, %%ecx\n" - " xor $0x200000, %%eax\n" - " push %%eax\n" - " popfl\n" - " pushfl\n" - " pop %%eax\n" - " xor %%ecx, %%eax\n" - " mov %%eax, %0\n" - " push %%ecx\n" - " popfl\n" - : "=m"(result) - : :"eax", "ecx", "memory"); - return (result != 0); -# elif defined(COMPILER_MICROSOFT) - int result; - __asm { - pushfd - pop eax - mov ecx, eax - xor eax, 0x200000 - push eax - popfd - pushfd - pop eax - xor eax, ecx - mov result, eax - push ecx - popfd - }; - return (result != 0); -# else - return 0; -# endif /* COMPILER_MICROSOFT */ -#else - return 0; -#endif /* PLATFORM_X86 */ -} - -#ifdef INLINE_ASM_SUPPORTED -/* - * with MSVC/AMD64, the exec_cpuid() and cpu_rdtsc() functions - * are implemented in separate .asm files. Otherwise, use inline assembly - */ -void exec_cpuid(uint32_t *regs) -{ -#ifdef COMPILER_GCC -# ifdef PLATFORM_X64 - __asm __volatile( - " mov %0, %%rdi\n" - - " push %%rbx\n" - " push %%rcx\n" - " push %%rdx\n" - - " mov (%%rdi), %%eax\n" - " mov 4(%%rdi), %%ebx\n" - " mov 8(%%rdi), %%ecx\n" - " mov 12(%%rdi), %%edx\n" - - " cpuid\n" - - " movl %%eax, (%%rdi)\n" - " movl %%ebx, 4(%%rdi)\n" - " movl %%ecx, 8(%%rdi)\n" - " movl %%edx, 12(%%rdi)\n" - " pop %%rdx\n" - " pop %%rcx\n" - " pop %%rbx\n" - : - :"m"(regs) - :"memory", "eax", "rdi" - ); -# else - __asm __volatile( - " mov %0, %%edi\n" - - " push %%ebx\n" - " push %%ecx\n" - " push %%edx\n" - - " mov (%%edi), %%eax\n" - " mov 4(%%edi), %%ebx\n" - " mov 8(%%edi), %%ecx\n" - " mov 12(%%edi), %%edx\n" - - " cpuid\n" - - " mov %%eax, (%%edi)\n" - " mov %%ebx, 4(%%edi)\n" - " mov %%ecx, 8(%%edi)\n" - " mov %%edx, 12(%%edi)\n" - " pop %%edx\n" - " pop %%ecx\n" - " pop %%ebx\n" - : - :"m"(regs) - :"memory", "eax", "edi" - ); -# endif /* COMPILER_GCC */ -#else -# ifdef COMPILER_MICROSOFT - __asm { - push ebx - push ecx - push edx - push edi - mov edi, regs - - mov eax, [edi] - mov ebx, [edi+4] - mov ecx, [edi+8] - mov edx, [edi+12] - - cpuid - - mov [edi], eax - mov [edi+4], ebx - mov [edi+8], ecx - mov [edi+12], edx - - pop edi - pop edx - pop ecx - pop ebx - } -# else -# error "Unsupported compiler" -# endif /* COMPILER_MICROSOFT */ -#endif -} -#endif /* INLINE_ASSEMBLY_SUPPORTED */ - -#ifdef INLINE_ASM_SUPPORTED -void cpu_rdtsc(uint64_t* result) -{ - uint32_t low_part, hi_part; -#ifdef COMPILER_GCC - __asm __volatile ( - " rdtsc\n" - " mov %%eax, %0\n" - " mov %%edx, %1\n" - :"=m"(low_part), "=m"(hi_part)::"memory", "eax", "edx" - ); -#else -# ifdef COMPILER_MICROSOFT - __asm { - rdtsc - mov low_part, eax - mov hi_part, edx - }; -# else -# error "Unsupported compiler" -# endif /* COMPILER_MICROSOFT */ -#endif /* COMPILER_GCC */ - *result = (uint64_t)low_part + (((uint64_t) hi_part) << 32); -} -#endif /* INLINE_ASM_SUPPORTED */ - -#ifdef INLINE_ASM_SUPPORTED -void busy_sse_loop(int cycles) -{ -#ifdef COMPILER_GCC -#ifndef __APPLE__ -# define XALIGN ".balign 16\n" -#else -# define XALIGN ".align 4\n" -#endif - __asm __volatile ( - " xorps %%xmm0, %%xmm0\n" - " xorps %%xmm1, %%xmm1\n" - " xorps %%xmm2, %%xmm2\n" - " xorps %%xmm3, %%xmm3\n" - " xorps %%xmm4, %%xmm4\n" - " xorps %%xmm5, %%xmm5\n" - " xorps %%xmm6, %%xmm6\n" - " xorps %%xmm7, %%xmm7\n" - XALIGN - /* ".bsLoop:\n" */ - "1:\n" - // 0: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - // 1: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - // 2: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - // 3: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - // 4: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - // 5: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - // 6: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - // 7: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - // 8: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - // 9: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //10: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //11: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //12: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //13: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //14: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //15: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //16: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //17: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //18: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //19: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //20: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //21: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //22: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //23: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //24: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //25: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //26: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //27: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //28: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //29: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //30: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - //31: - " addps %%xmm1, %%xmm0\n" - " addps %%xmm2, %%xmm1\n" - " addps %%xmm3, %%xmm2\n" - " addps %%xmm4, %%xmm3\n" - " addps %%xmm5, %%xmm4\n" - " addps %%xmm6, %%xmm5\n" - " addps %%xmm7, %%xmm6\n" - " addps %%xmm0, %%xmm7\n" - - " dec %%eax\n" - /* "jnz .bsLoop\n" */ - " jnz 1b\n" - ::"a"(cycles) - ); -#else -# ifdef COMPILER_MICROSOFT - __asm { - mov eax, cycles - xorps xmm0, xmm0 - xorps xmm1, xmm1 - xorps xmm2, xmm2 - xorps xmm3, xmm3 - xorps xmm4, xmm4 - xorps xmm5, xmm5 - xorps xmm6, xmm6 - xorps xmm7, xmm7 - //-- - align 16 -bsLoop: - // 0: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 1: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 2: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 3: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 4: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 5: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 6: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 7: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 8: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 9: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 10: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 11: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 12: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 13: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 14: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 15: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 16: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 17: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 18: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 19: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 20: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 21: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 22: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 23: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 24: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 25: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 26: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 27: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 28: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 29: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 30: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - // 31: - addps xmm0, xmm1 - addps xmm1, xmm2 - addps xmm2, xmm3 - addps xmm3, xmm4 - addps xmm4, xmm5 - addps xmm5, xmm6 - addps xmm6, xmm7 - addps xmm7, xmm0 - //---------------------- - dec eax - jnz bsLoop - } -# else -# error "Unsupported compiler" -# endif /* COMPILER_MICROSOFT */ -#endif /* COMPILER_GCC */ -} -#endif /* INLINE_ASSEMBLY_SUPPORTED */ +/* + * Copyright 2008 Veselin Georgiev, + * anrieffNOSPAM @ mgail_DOT.com (convert to gmail) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "libcpuid.h" +#include "asm-bits.h" + +int cpuid_exists_by_eflags(void) +{ +#if defined(PLATFORM_X64) + return 1; /* CPUID is always present on the x86_64 */ +#elif defined(PLATFORM_X86) +# if defined(COMPILER_GCC) || defined(COMPILER_CLANG) + int result; + __asm __volatile( + " pushfl\n" + " pop %%eax\n" + " mov %%eax, %%ecx\n" + " xor $0x200000, %%eax\n" + " push %%eax\n" + " popfl\n" + " pushfl\n" + " pop %%eax\n" + " xor %%ecx, %%eax\n" + " mov %%eax, %0\n" + " push %%ecx\n" + " popfl\n" + : "=m"(result) + : :"eax", "ecx", "memory"); + return (result != 0); +# elif defined(COMPILER_MICROSOFT) + int result; + __asm { + pushfd + pop eax + mov ecx, eax + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + xor eax, ecx + mov result, eax + push ecx + popfd + }; + return (result != 0); +# else + return 0; +# endif /* COMPILER_MICROSOFT */ +#elif defined(PLATFORM_ARM) + return 0; +#else + return 0; +#endif /* PLATFORM_X86 */ +} + +#ifdef INLINE_ASM_SUPPORTED +/* + * with MSVC/AMD64, the exec_cpuid() and cpu_rdtsc() functions + * are implemented in separate .asm files. Otherwise, use inline assembly + */ +void exec_cpuid(uint32_t *regs) +{ +# if defined(COMPILER_GCC) || defined(COMPILER_CLANG) +# ifdef PLATFORM_X64 + __asm __volatile( + " mov %0, %%rdi\n" + + " push %%rbx\n" + " push %%rcx\n" + " push %%rdx\n" + + " mov (%%rdi), %%eax\n" + " mov 4(%%rdi), %%ebx\n" + " mov 8(%%rdi), %%ecx\n" + " mov 12(%%rdi), %%edx\n" + + " cpuid\n" + + " movl %%eax, (%%rdi)\n" + " movl %%ebx, 4(%%rdi)\n" + " movl %%ecx, 8(%%rdi)\n" + " movl %%edx, 12(%%rdi)\n" + " pop %%rdx\n" + " pop %%rcx\n" + " pop %%rbx\n" + : + :"m"(regs) + :"memory", "eax", "rdi" + ); +# elif defined(PLATFORM_X86) + __asm __volatile( + " mov %0, %%edi\n" + + " push %%ebx\n" + " push %%ecx\n" + " push %%edx\n" + + " mov (%%edi), %%eax\n" + " mov 4(%%edi), %%ebx\n" + " mov 8(%%edi), %%ecx\n" + " mov 12(%%edi), %%edx\n" + + " cpuid\n" + + " mov %%eax, (%%edi)\n" + " mov %%ebx, 4(%%edi)\n" + " mov %%ecx, 8(%%edi)\n" + " mov %%edx, 12(%%edi)\n" + " pop %%edx\n" + " pop %%ecx\n" + " pop %%ebx\n" + : + :"m"(regs) + :"memory", "eax", "edi" + ); +# elif defined(PLATFORM_ARM) +# endif /* COMPILER_GCC */ +#else +# ifdef COMPILER_MICROSOFT + __asm { + push ebx + push ecx + push edx + push edi + mov edi, regs + + mov eax, [edi] + mov ebx, [edi+4] + mov ecx, [edi+8] + mov edx, [edi+12] + + cpuid + + mov [edi], eax + mov [edi+4], ebx + mov [edi+8], ecx + mov [edi+12], edx + + pop edi + pop edx + pop ecx + pop ebx + } +# else +# error "Unsupported compiler" +# endif /* COMPILER_MICROSOFT */ +#endif +} +#endif /* INLINE_ASSEMBLY_SUPPORTED */ + +#ifdef INLINE_ASM_SUPPORTED +void cpu_rdtsc(uint64_t* result) +{ + uint32_t low_part, hi_part; +#if defined(COMPILER_GCC) || defined(COMPILER_CLANG) +#ifdef PLATFORM_ARM + low_part = 0; + hi_part = 0; +#else + __asm __volatile ( + " rdtsc\n" + " mov %%eax, %0\n" + " mov %%edx, %1\n" + :"=m"(low_part), "=m"(hi_part)::"memory", "eax", "edx" + ); +#endif +#else +# ifdef COMPILER_MICROSOFT + __asm { + rdtsc + mov low_part, eax + mov hi_part, edx + }; +# else +# error "Unsupported compiler" +# endif /* COMPILER_MICROSOFT */ +#endif /* COMPILER_GCC */ + *result = (uint64_t)low_part + (((uint64_t) hi_part) << 32); +} +#endif /* INLINE_ASM_SUPPORTED */ + +#ifdef INLINE_ASM_SUPPORTED +void busy_sse_loop(int cycles) +{ +# if defined(COMPILER_GCC) || defined(COMPILER_CLANG) +#ifndef __APPLE__ +# define XALIGN ".balign 16\n" +#else +# define XALIGN ".align 4\n" +#endif +#ifdef PLATFORM_ARM +#else + __asm __volatile ( + " xorps %%xmm0, %%xmm0\n" + " xorps %%xmm1, %%xmm1\n" + " xorps %%xmm2, %%xmm2\n" + " xorps %%xmm3, %%xmm3\n" + " xorps %%xmm4, %%xmm4\n" + " xorps %%xmm5, %%xmm5\n" + " xorps %%xmm6, %%xmm6\n" + " xorps %%xmm7, %%xmm7\n" + XALIGN + /* ".bsLoop:\n" */ + "1:\n" + // 0: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + // 1: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + // 2: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + // 3: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + // 4: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + // 5: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + // 6: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + // 7: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + // 8: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + // 9: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //10: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //11: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //12: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //13: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //14: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //15: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //16: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //17: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //18: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //19: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //20: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //21: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //22: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //23: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //24: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //25: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //26: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //27: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //28: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //29: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //30: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + //31: + " addps %%xmm1, %%xmm0\n" + " addps %%xmm2, %%xmm1\n" + " addps %%xmm3, %%xmm2\n" + " addps %%xmm4, %%xmm3\n" + " addps %%xmm5, %%xmm4\n" + " addps %%xmm6, %%xmm5\n" + " addps %%xmm7, %%xmm6\n" + " addps %%xmm0, %%xmm7\n" + + " dec %%eax\n" + /* "jnz .bsLoop\n" */ + " jnz 1b\n" + ::"a"(cycles) + ); +#endif +#else +# ifdef COMPILER_MICROSOFT + __asm { + mov eax, cycles + xorps xmm0, xmm0 + xorps xmm1, xmm1 + xorps xmm2, xmm2 + xorps xmm3, xmm3 + xorps xmm4, xmm4 + xorps xmm5, xmm5 + xorps xmm6, xmm6 + xorps xmm7, xmm7 + //-- + align 16 +bsLoop: + // 0: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 1: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 2: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 3: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 4: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 5: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 6: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 7: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 8: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 9: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 10: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 11: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 12: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 13: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 14: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 15: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 16: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 17: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 18: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 19: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 20: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 21: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 22: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 23: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 24: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 25: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 26: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 27: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 28: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 29: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 30: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + // 31: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + //---------------------- + dec eax + jnz bsLoop + } +# else +# error "Unsupported compiler" +# endif /* COMPILER_MICROSOFT */ +#endif /* COMPILER_GCC */ +} +#endif /* INLINE_ASSEMBLY_SUPPORTED */ \ No newline at end of file diff --git a/src/3rdparty/libcpuid/asm-bits.h b/src/3rdparty/libcpuid/asm-bits.h index 3a03e11c..9049e2fe 100644 --- a/src/3rdparty/libcpuid/asm-bits.h +++ b/src/3rdparty/libcpuid/asm-bits.h @@ -1,53 +1,71 @@ -/* - * Copyright 2008 Veselin Georgiev, - * anrieffNOSPAM @ mgail_DOT.com (convert to gmail) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __ASM_BITS_H__ -#define __ASM_BITS_H__ -#include "libcpuid.h" - -/* Determine Compiler: */ -#if defined(_MSC_VER) -# define COMPILER_MICROSOFT -#elif defined(__GNUC__) -# define COMPILER_GCC -#endif - -/* Determine Platform */ -#if defined(__x86_64__) || defined(_M_AMD64) -# define PLATFORM_X64 -#elif defined(__i386__) || defined(_M_IX86) -# define PLATFORM_X86 -#endif - -/* Under Windows/AMD64 with MSVC, inline assembly isn't supported */ -#if (defined(COMPILER_GCC) && defined(PLATFORM_X64)) || defined(PLATFORM_X86) -# define INLINE_ASM_SUPPORTED -#endif - -int cpuid_exists_by_eflags(void); -void exec_cpuid(uint32_t *regs); -void busy_sse_loop(int cycles); - -#endif /* __ASM_BITS_H__ */ +/* + * Copyright 2008 Veselin Georgiev, + * anrieffNOSPAM @ mgail_DOT.com (convert to gmail) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __ASM_BITS_H__ +#define __ASM_BITS_H__ +#include "libcpuid.h" + +/* Determine Compiler: */ +#if defined(_MSC_VER) +#if !defined(COMPILER_MICROSOFT) +# define COMPILER_MICROSOFT +#endif +#elif defined(__GNUC__) +#if !defined(COMPILER_GCC) +# define COMPILER_GCC +#endif +#elif defined(__clang__) +#if !defined(COMPILER_CLANG) +# define COMPILER_CLANG +#endif +#endif + +/* Determine Platform */ +#if defined(__x86_64__) || defined(_M_AMD64) +#if !defined(PLATFORM_X64) +# define PLATFORM_X64 +#endif +#elif defined(__i386__) || defined(_M_IX86) +#if !defined(PLATFORM_X86) +# define PLATFORM_X86 +#endif +#elif defined(__ARMEL__) +#if !defined(PLATFORM_ARM) +# define PLATFORM_ARM +#endif +#endif + +/* Under Windows/AMD64 with MSVC, inline assembly isn't supported */ +#if (((defined(COMPILER_GCC) || defined(COMPILER_CLANG))) && \ + (defined(PLATFORM_X64) || defined(PLATFORM_X86) || defined(PLATFORM_ARM))) || \ + (defined(COMPILER_MICROSOFT) && defined(PLATFORM_X86)) +# define INLINE_ASM_SUPPORTED +#endif + +int cpuid_exists_by_eflags(void); +void exec_cpuid(uint32_t *regs); +void busy_sse_loop(int cycles); + +#endif /* __ASM_BITS_H__ */ diff --git a/src/3rdparty/libcpuid/cpuid_main.c b/src/3rdparty/libcpuid/cpuid_main.c index f22c7dd6..61cb638d 100644 --- a/src/3rdparty/libcpuid/cpuid_main.c +++ b/src/3rdparty/libcpuid/cpuid_main.c @@ -221,42 +221,42 @@ static void load_features_common(struct cpu_raw_data_t* raw, struct cpu_id_t* da static cpu_vendor_t cpuid_vendor_identify(const uint32_t *raw_vendor, char *vendor_str) { - int i; - cpu_vendor_t vendor = VENDOR_UNKNOWN; - const struct { cpu_vendor_t vendor; char match[16]; } - matchtable[NUM_CPU_VENDORS] = { - /* source: http://www.sandpile.org/ia32/cpuid.htm */ - { VENDOR_INTEL , "GenuineIntel" }, - { VENDOR_AMD , "AuthenticAMD" }, - { VENDOR_CYRIX , "CyrixInstead" }, - { VENDOR_NEXGEN , "NexGenDriven" }, - { VENDOR_TRANSMETA , "GenuineTMx86" }, - { VENDOR_UMC , "UMC UMC UMC " }, - { VENDOR_CENTAUR , "CentaurHauls" }, - { VENDOR_RISE , "RiseRiseRise" }, - { VENDOR_SIS , "SiS SiS SiS " }, - { VENDOR_NSC , "Geode by NSC" }, - }; + int i; + cpu_vendor_t vendor = VENDOR_UNKNOWN; + const struct { cpu_vendor_t vendor; char match[16]; } + matchtable[NUM_CPU_VENDORS] = { + /* source: http://www.sandpile.org/ia32/cpuid.htm */ + { VENDOR_INTEL , "GenuineIntel" }, + { VENDOR_AMD , "AuthenticAMD" }, + { VENDOR_CYRIX , "CyrixInstead" }, + { VENDOR_NEXGEN , "NexGenDriven" }, + { VENDOR_TRANSMETA , "GenuineTMx86" }, + { VENDOR_UMC , "UMC UMC UMC " }, + { VENDOR_CENTAUR , "CentaurHauls" }, + { VENDOR_RISE , "RiseRiseRise" }, + { VENDOR_SIS , "SiS SiS SiS " }, + { VENDOR_NSC , "Geode by NSC" }, + }; - memcpy(vendor_str + 0, &raw_vendor[1], 4); - memcpy(vendor_str + 4, &raw_vendor[3], 4); - memcpy(vendor_str + 8, &raw_vendor[2], 4); - vendor_str[12] = 0; + memcpy(vendor_str + 0, &raw_vendor[1], 4); + memcpy(vendor_str + 4, &raw_vendor[3], 4); + memcpy(vendor_str + 8, &raw_vendor[2], 4); + vendor_str[12] = 0; - /* Determine vendor: */ - for (i = 0; i < NUM_CPU_VENDORS; i++) - if (!strcmp(vendor_str, matchtable[i].match)) { - vendor = matchtable[i].vendor; - break; - } - return vendor; + /* Determine vendor: */ + for (i = 0; i < NUM_CPU_VENDORS; i++) + if (!strcmp(vendor_str, matchtable[i].match)) { + vendor = matchtable[i].vendor; + break; + } + return vendor; } static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) { int i, j, basic, xmodel, xfamily, ext; char brandstr[64] = {0}; - data->vendor = cpuid_vendor_identify(raw->basic_cpuid[0], data->vendor_str); + data->vendor = cpuid_vendor_identify(raw->basic_cpuid[0], data->vendor_str); if (data->vendor == VENDOR_UNKNOWN) return set_error(ERR_CPU_UNKN); diff --git a/src/3rdparty/libcpuid/libcpuid.h b/src/3rdparty/libcpuid/libcpuid.h index c44990c3..847e5a4a 100644 --- a/src/3rdparty/libcpuid/libcpuid.h +++ b/src/3rdparty/libcpuid/libcpuid.h @@ -60,7 +60,7 @@ */ /** @mainpage A simple libcpuid introduction - * + * * LibCPUID provides CPU identification and access to the CPUID and RDTSC * instructions on the x86. *

@@ -82,6 +82,7 @@ */ /** @defgroup libcpuid LibCPUID + * @brief LibCPUID provides CPU identification @{ */ /* Include some integer type specifications: */ @@ -535,23 +536,23 @@ typedef enum { * @brief Describes common library error codes */ typedef enum { - ERR_OK = 0, /*!< "No error" */ - ERR_NO_CPUID = -1, /*!< "CPUID instruction is not supported" */ - ERR_NO_RDTSC = -2, /*!< "RDTSC instruction is not supported" */ - ERR_NO_MEM = -3, /*!< "Memory allocation failed" */ - ERR_OPEN = -4, /*!< "File open operation failed" */ - ERR_BADFMT = -5, /*!< "Bad file format" */ - ERR_NOT_IMP = -6, /*!< "Not implemented" */ - ERR_CPU_UNKN = -7, /*!< "Unsupported processor" */ - ERR_NO_RDMSR = -8, /*!< "RDMSR instruction is not supported" */ - ERR_NO_DRIVER= -9, /*!< "RDMSR driver error (generic)" */ - ERR_NO_PERMS = -10, /*!< "No permissions to install RDMSR driver" */ - ERR_EXTRACT = -11, /*!< "Cannot extract RDMSR driver (read only media?)" */ - ERR_HANDLE = -12, /*!< "Bad handle" */ - ERR_INVMSR = -13, /*!< "Invalid MSR" */ - ERR_INVCNB = -14, /*!< "Invalid core number" */ - ERR_HANDLE_R = -15, /*!< "Error on handle read" */ - ERR_INVRANGE = -16, /*!< "Invalid given range" */ + ERR_OK = 0, /*!< No error */ + ERR_NO_CPUID = -1, /*!< CPUID instruction is not supported */ + ERR_NO_RDTSC = -2, /*!< RDTSC instruction is not supported */ + ERR_NO_MEM = -3, /*!< Memory allocation failed */ + ERR_OPEN = -4, /*!< File open operation failed */ + ERR_BADFMT = -5, /*!< Bad file format */ + ERR_NOT_IMP = -6, /*!< Not implemented */ + ERR_CPU_UNKN = -7, /*!< Unsupported processor */ + ERR_NO_RDMSR = -8, /*!< RDMSR instruction is not supported */ + ERR_NO_DRIVER= -9, /*!< RDMSR driver error (generic) */ + ERR_NO_PERMS = -10, /*!< No permissions to install RDMSR driver */ + ERR_EXTRACT = -11, /*!< Cannot extract RDMSR driver (read only media?) */ + ERR_HANDLE = -12, /*!< Bad handle */ + ERR_INVMSR = -13, /*!< Invalid MSR */ + ERR_INVCNB = -14, /*!< Invalid core number */ + ERR_HANDLE_R = -15, /*!< Error on handle read */ + ERR_INVRANGE = -16, /*!< Invalid given range */ } cpu_error_t; /** @@ -668,7 +669,7 @@ struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw); const char* cpuid_lib_version(void); #ifdef __cplusplus -}; /* extern "C" */ +} /* extern "C" */ #endif diff --git a/src/3rdparty/libcpuid/libcpuid_internal.h b/src/3rdparty/libcpuid/libcpuid_internal.h index 038aa209..64804616 100644 --- a/src/3rdparty/libcpuid/libcpuid_internal.h +++ b/src/3rdparty/libcpuid/libcpuid_internal.h @@ -75,8 +75,9 @@ enum _intel_bits_t { _3 = LBIT( 14 ), _5 = LBIT( 15 ), _7 = LBIT( 16 ), - XEON_ = LBIT( 17 ), - ATOM_ = LBIT( 18 ), + _9 = LBIT( 17 ), + XEON_ = LBIT( 18 ), + ATOM_ = LBIT( 19 ), }; typedef enum _intel_bits_t intel_bits_t; diff --git a/src/3rdparty/libcpuid/libcpuid_types.h b/src/3rdparty/libcpuid/libcpuid_types.h index 9e897275..0e667aa6 100644 --- a/src/3rdparty/libcpuid/libcpuid_types.h +++ b/src/3rdparty/libcpuid/libcpuid_types.h @@ -32,6 +32,32 @@ #ifndef __LIBCPUID_TYPES_H__ #define __LIBCPUID_TYPES_H__ -#include +#if !defined(_MSC_VER) || _MSC_VER >= 1600 +# include +#else +/* we have to provide our own: */ +# if !defined(__int32_t_defined) +typedef int int32_t; +# endif + +# if !defined(__uint32_t_defined) +typedef unsigned uint32_t; +# endif + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +#if (defined _MSC_VER) && (_MSC_VER <= 1300) + /* MSVC 6.0: no long longs ... */ + typedef signed __int64 int64_t; + typedef unsigned __int64 uint64_t; +#else + /* all other sane compilers: */ + typedef signed long long int64_t; + typedef unsigned long long uint64_t; +#endif + +#endif #endif /* __LIBCPUID_TYPES_H__ */ diff --git a/src/3rdparty/libcpuid/recog_amd.c b/src/3rdparty/libcpuid/recog_amd.c index 352d733b..4726f633 100644 --- a/src/3rdparty/libcpuid/recog_amd.c +++ b/src/3rdparty/libcpuid/recog_amd.c @@ -49,6 +49,10 @@ enum _amd_model_codes_t { _1400, _1500, _1600, + _1900, + _2400, + _2500, + _2700, }; static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data) diff --git a/src/3rdparty/libcpuid/recog_intel.c b/src/3rdparty/libcpuid/recog_intel.c index 5467c19f..397d750e 100644 --- a/src/3rdparty/libcpuid/recog_intel.c +++ b/src/3rdparty/libcpuid/recog_intel.c @@ -376,7 +376,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) bits |= bit_matchtable[i].bit; } - if ((i = match_pattern(bs, "Core(TM) [im][357]")) != 0) { + if ((i = match_pattern(bs, "Core(TM) [im][3579]")) != 0) { bits |= CORE_; i--; switch (bs[i + 9]) { @@ -387,6 +387,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) case '3': bits |= _3; break; case '5': bits |= _5; break; case '7': bits |= _7; break; + case '9': bits |= _9; break; } } for (i = 0; i < COUNT_OF(matchtable); i++) diff --git a/src/App.cpp b/src/App.cpp index adcc5752..134e4ef5 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -29,11 +29,11 @@ #include "api/Api.h" #include "App.h" #include "common/Console.h" +#include "common/cpu/Cpu.h" #include "common/log/Log.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" -#include "Cpu.h" #include "crypto/CryptoNight.h" #include "Mem.h" #include "net/Network.h" diff --git a/src/App.h b/src/App.h index 22269f67..964400e6 100644 --- a/src/App.h +++ b/src/App.h @@ -28,7 +28,7 @@ #include -#include "interfaces/IConsoleListener.h" +#include "common/interfaces/IConsoleListener.h" class Console; diff --git a/src/Summary.cpp b/src/Summary.cpp index e960dd8d..3c1d06a7 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -27,44 +27,41 @@ #include +#include "common/cpu/Cpu.h" #include "common/log/Log.h" #include "common/net/Pool.h" #include "core/Config.h" #include "core/Controller.h" -#include "Cpu.h" +#include "crypto/Asm.h" #include "Mem.h" #include "Summary.h" #include "version.h" -static void print_versions(xmrig::Config *config) +#ifndef XMRIG_NO_ASM +static const char *coloredAsmNames[] = { + "\x1B[1;31mnone\x1B[0m", + "auto", + "\x1B[1;32mintel\x1B[0m", + "\x1B[1;32mryzen\x1B[0m" +}; + + +inline static const char *asmName(xmrig::Assembly assembly, bool colors) { - char buf[16]; - -# if defined(__clang__) - snprintf(buf, 16, " clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__); -# elif defined(__GNUC__) - snprintf(buf, 16, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); -# elif defined(_MSC_VER) - snprintf(buf, 16, " MSVC/%d", MSVC_VERSION); -# else - buf[0] = '\0'; -# endif - - - Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" : " * VERSIONS: XMRig/%s libuv/%s%s", - APP_VERSION, uv_version_string(), buf); + return colors ? coloredAsmNames[assembly] : xmrig::Asm::toString(assembly); } +#endif static void print_memory(xmrig::Config *config) { # ifdef _WIN32 if (config->isColors()) { - Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s", - Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable"); + Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s", + "HUGE PAGES", Mem::isHugepagesAvailable() ? "\x1B[1;32mavailable" : "\x1B[01;31munavailable"); } else { - Log::i()->text(" * HUGE PAGES: %s", Mem::isHugepagesAvailable() ? "available" : "unavailable"); + Log::i()->text(" * %-13s%s", "HUGE PAGES", Mem::isHugepagesAvailable() ? "available" : "unavailable"); } # endif } @@ -72,20 +69,23 @@ static void print_memory(xmrig::Config *config) { static void print_cpu(xmrig::Config *config) { + using namespace xmrig; + if (config->isColors()) { - Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI", - Cpu::brand(), - Cpu::sockets(), - Cpu::isX64() ? "\x1B[01;32m" : "\x1B[01;31m-", - Cpu::hasAES() ? "\x1B[01;32m" : "\x1B[01;31m-"); + Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES", + "CPU", + Cpu::info()->brand(), + Cpu::info()->sockets(), + Cpu::info()->isX64() ? "\x1B[1;32m" : "\x1B[1;31m-", + Cpu::info()->hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-"); # ifndef XMRIG_NO_LIBCPUID - Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); + Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0); # endif } else { - Log::i()->text(" * CPU: %s (%d) %sx64 %sAES-NI", Cpu::brand(), Cpu::sockets(), Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-"); + Log::i()->text(" * %-13s%s (%d) %sx64 %sAES", "CPU", Cpu::info()->brand(), Cpu::info()->sockets(), Cpu::info()->isX64() ? "" : "-", Cpu::info()->hasAES() ? "" : "-"); # ifndef XMRIG_NO_LIBCPUID - Log::i()->text(" * CPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); + Log::i()->text(" * %-13s%.1f MB/%.1f MB", "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0); # endif } } @@ -94,87 +94,66 @@ static void print_cpu(xmrig::Config *config) static void print_threads(xmrig::Config *config) { if (config->threadsMode() != xmrig::Config::Advanced) { - char buf[32]; + char buf[32] = { 0 }; if (config->affinity() != -1L) { - snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity()); - } - else { - buf[0] = '\0'; + snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity()); } - Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", + Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, av=%d, %sdonate=%d%%") WHITE_BOLD("%s") + : " * %-13s%d, %s, av=%d, %sdonate=%d%%%s", + "THREADS", config->threadsCount(), config->algorithm().name(), config->algoVariant(), - config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", + config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "", config->donateLevel(), buf); } else { - Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, %sdonate=%d%%" : " * THREADS: %d, %s, %sdonate=%d%%", + Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, %sdonate=%d%%") + : " * %-13s%d, %s, %sdonate=%d%%", + "THREADS", config->threadsCount(), config->algorithm().name(), - config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", + config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "", config->donateLevel()); } -} +# ifndef XMRIG_NO_ASM + if (config->assembly() == xmrig::ASM_AUTO) { + const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly(); -static void print_pools(xmrig::Config *config) -{ - const std::vector &pools = config->pools(); - - for (size_t i = 0; i < pools.size(); ++i) { - Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s" : " * POOL #%d: %s", - i + 1, - pools[i].url() - ); + Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s") + : " * %-13sauto:%s", "ASSEMBLY", asmName(assembly, config->isColors())); } - -# ifdef APP_DEBUG - for (const Pool &pool : pools) { - pool.print(); + else { + Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s") : " * %-13s%s", "ASSEMBLY", asmName(config->assembly(), config->isColors())); } # endif } -#ifndef XMRIG_NO_API -static void print_api(xmrig::Config *config) -{ - const int port = config->apiPort(); - if (port == 0) { - return; - } - - Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mAPI BIND: \x1B[01;36m%s:%d" : " * API BIND: %s:%d", - config->isApiIPv6() ? "[::]" : "0.0.0.0", port); -} -#endif - - static void print_commands(xmrig::Config *config) { if (config->isColors()) { - Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mh\x1B[01;37mashrate, \x1B[01;35mp\x1B[01;37mause, \x1B[01;35mr\x1B[01;37mesume"); + Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ") + MAGENTA_BOLD("p") WHITE_BOLD("ause, ") + MAGENTA_BOLD("r") WHITE_BOLD("esume")); } else { - Log::i()->text(" * COMMANDS: 'h' hashrate, 'p' pause, 'r' resume"); + Log::i()->text(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume"); } } void Summary::print(xmrig::Controller *controller) { - print_versions(controller->config()); + controller->config()->printVersions(); print_memory(controller->config()); print_cpu(controller->config()); print_threads(controller->config()); - print_pools(controller->config()); - -# ifndef XMRIG_NO_API - print_api(controller->config()); -# endif + controller->config()->printPools(); + controller->config()->printAPI(); print_commands(controller->config()); } diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 07e425f1..dd7accf6 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -35,14 +35,13 @@ #include "api/ApiRouter.h" #include "common/api/HttpReply.h" #include "common/api/HttpRequest.h" +#include "common/cpu/Cpu.h" #include "common/crypto/keccak.h" #include "common/net/Job.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" -#include "Cpu.h" #include "interfaces/IThread.h" -#include "Mem.h" #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" #include "rapidjson/stringbuffer.h" @@ -67,7 +66,7 @@ ApiRouter::ApiRouter(xmrig::Controller *controller) : memset(m_workerId, 0, sizeof(m_workerId)); setWorkerId(controller->config()->apiWorkerId()); - genId(); + genId(controller->config()->apiId()); } @@ -145,10 +144,15 @@ void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) cons } -void ApiRouter::genId() +void ApiRouter::genId(const char *id) { memset(m_id, 0, sizeof(m_id)); + if (id && strlen(id) > 0) { + strncpy(m_id, id, sizeof(m_id) - 1); + return; + } + uv_interface_address_t *interfaces; int count = 0; @@ -160,11 +164,13 @@ void ApiRouter::genId() if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) { uint8_t hash[200]; const size_t addrSize = sizeof(interfaces[i].phys_addr); - const size_t inSize = strlen(APP_KIND) + addrSize; + const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t); + const uint16_t port = static_cast(m_controller->config()->apiPort()); uint8_t *input = new uint8_t[inSize](); - memcpy(input, interfaces[i].phys_addr, addrSize); - memcpy(input + addrSize, APP_KIND, strlen(APP_KIND)); + memcpy(input, &port, sizeof(uint16_t)); + memcpy(input + sizeof(uint16_t), interfaces[i].phys_addr, addrSize); + memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND)); xmrig::keccak(input, inSize, hash); Job::toHex(hash, 8, m_id); @@ -232,13 +238,14 @@ void ApiRouter::getIdentify(rapidjson::Document &doc) const void ApiRouter::getMiner(rapidjson::Document &doc) const { + using namespace xmrig; auto &allocator = doc.GetAllocator(); rapidjson::Value cpu(rapidjson::kObjectType); - cpu.AddMember("brand", rapidjson::StringRef(Cpu::brand()), allocator); - cpu.AddMember("aes", Cpu::hasAES(), allocator); - cpu.AddMember("x64", Cpu::isX64(), allocator); - cpu.AddMember("sockets", Cpu::sockets(), allocator); + cpu.AddMember("brand", rapidjson::StringRef(Cpu::info()->brand()), allocator); + cpu.AddMember("aes", Cpu::info()->hasAES(), allocator); + cpu.AddMember("x64", Cpu::info()->isX64(), allocator); + cpu.AddMember("sockets", Cpu::info()->sockets(), allocator); doc.AddMember("version", APP_VERSION, allocator); doc.AddMember("kind", APP_KIND, allocator); diff --git a/src/api/ApiRouter.h b/src/api/ApiRouter.h index 3ed458d4..b781d5a2 100644 --- a/src/api/ApiRouter.h +++ b/src/api/ApiRouter.h @@ -26,7 +26,7 @@ #include "api/NetworkState.h" -#include "interfaces/IControllerListener.h" +#include "common/interfaces/IControllerListener.h" #include "rapidjson/fwd.h" @@ -56,7 +56,7 @@ protected: private: void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const; - void genId(); + void genId(const char *id); void getConnection(rapidjson::Document &doc) const; void getHashrate(rapidjson::Document &doc) const; void getIdentify(rapidjson::Document &doc) const; @@ -66,7 +66,7 @@ private: void setWorkerId(const char *id); void updateWorkerId(const char *id, const char *previousId); - char m_id[17]; + char m_id[32]; char m_workerId[128]; NetworkState m_network; xmrig::Controller *m_controller; diff --git a/src/common/Platform.cpp b/src/common/Platform.cpp index 52b55987..a95f78e7 100644 --- a/src/common/Platform.cpp +++ b/src/common/Platform.cpp @@ -26,6 +26,12 @@ #include +#ifndef XMRIG_NO_TLS +# include +# include +#endif + + #include "Platform.h" @@ -61,3 +67,23 @@ const char *Platform::defaultConfigName() *m_defaultConfigName = '\0'; return nullptr; } + + +void Platform::init(const char *userAgent) +{ +# ifndef XMRIG_NO_TLS + SSL_library_init(); + SSL_load_error_strings(); + ERR_load_BIO_strings(); + ERR_load_crypto_strings(); + SSL_load_error_strings(); + OpenSSL_add_all_digests(); +# endif + + if (userAgent) { + m_userAgent = userAgent; + } + else { + m_userAgent = createUserAgent(); + } +} diff --git a/src/common/Platform.h b/src/common/Platform.h index 8704604a..5dfb9ff7 100644 --- a/src/common/Platform.h +++ b/src/common/Platform.h @@ -21,8 +21,8 @@ * along with this program. If not, see . */ -#ifndef __PLATFORM_H__ -#define __PLATFORM_H__ +#ifndef XMRIG_PLATFORM_H +#define XMRIG_PLATFORM_H #include @@ -43,9 +43,11 @@ public: static inline const char *userAgent() { return m_userAgent.data(); } private: + static char *createUserAgent(); + static char m_defaultConfigName[520]; static xmrig::c_str m_userAgent; }; -#endif /* __PLATFORM_H__ */ +#endif /* XMRIG_PLATFORM_H */ diff --git a/src/common/Platform_mac.cpp b/src/common/Platform_mac.cpp index b8181cc4..d0c533b0 100644 --- a/src/common/Platform_mac.cpp +++ b/src/common/Platform_mac.cpp @@ -38,7 +38,7 @@ #endif -static inline char *createUserAgent() +char *Platform::createUserAgent() { const size_t max = 160; @@ -65,17 +65,6 @@ bool Platform::setThreadAffinity(uint64_t cpu_id) } -void Platform::init(const char *userAgent) -{ - if (userAgent) { - m_userAgent = userAgent; - } - else { - m_userAgent = createUserAgent(); - } -} - - void Platform::setProcessPriority(int priority) { diff --git a/src/common/Platform_unix.cpp b/src/common/Platform_unix.cpp index 63cd1c8b..058920ec 100644 --- a/src/common/Platform_unix.cpp +++ b/src/common/Platform_unix.cpp @@ -29,11 +29,13 @@ #endif +#include #include #include #include #include #include +#include #include @@ -50,7 +52,7 @@ typedef cpuset_t cpu_set_t; #endif -static inline char *createUserAgent() +char *Platform::createUserAgent() { const size_t max = 160; @@ -90,23 +92,11 @@ bool Platform::setThreadAffinity(uint64_t cpu_id) } -void Platform::init(const char *userAgent) -{ - if (userAgent) { - m_userAgent = userAgent; - } - else { - m_userAgent = createUserAgent(); - } -} - - void Platform::setProcessPriority(int priority) { } - void Platform::setThreadPriority(int priority) { if (priority == -1) { diff --git a/src/common/Platform_win.cpp b/src/common/Platform_win.cpp index 47f41867..32b850d1 100644 --- a/src/common/Platform_win.cpp +++ b/src/common/Platform_win.cpp @@ -55,7 +55,7 @@ static inline OSVERSIONINFOEX winOsVersion() } -static inline char *createUserAgent() +char *Platform::createUserAgent() { const auto osver = winOsVersion(); const size_t max = 160; @@ -94,17 +94,6 @@ bool Platform::setThreadAffinity(uint64_t cpu_id) } -void Platform::init(const char *userAgent) -{ - if (userAgent) { - m_userAgent = userAgent; - } - else { - m_userAgent = createUserAgent(); - } -} - - void Platform::setProcessPriority(int priority) { if (priority == -1) { diff --git a/src/common/api/HttpRequest.cpp b/src/common/api/HttpRequest.cpp index 01245dfc..6898a385 100644 --- a/src/common/api/HttpRequest.cpp +++ b/src/common/api/HttpRequest.cpp @@ -147,7 +147,7 @@ int xmrig::HttpRequest::end(int status, MHD_Response *rsp) MHD_add_response_header(rsp, "Content-Type", "application/json"); MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*"); MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET, PUT"); - MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization"); + MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization, Content-Type"); const int ret = MHD_queue_response(m_connection, status, rsp); MHD_destroy_response(rsp); diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 5eaf68fd..beb2d0c9 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -29,20 +29,48 @@ #include +#ifndef XMRIG_NO_HTTPD +# include +#endif + + +#ifndef XMRIG_NO_TLS +# include +#endif + + +#ifdef XMRIG_AMD_PROJECT +# if defined(__APPLE__) +# include +# else +# include "3rdparty/CL/cl.h" +# endif +#endif + + +#ifdef XMRIG_NVIDIA_PROJECT +# include "nvidia/cryptonight.h" +#endif + + #include "common/config/CommonConfig.h" #include "common/log/Log.h" #include "donate.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" +#include "version.h" xmrig::CommonConfig::CommonConfig() : + m_algorithm(CRYPTONIGHT, VARIANT_AUTO), m_adjusted(false), m_apiIPv6(false), m_apiRestricted(true), + m_autoSave(true), m_background(false), m_colors(true), + m_dryRun(false), m_syslog(false), # ifdef XMRIG_PROXY_PROJECT @@ -67,8 +95,136 @@ xmrig::CommonConfig::CommonConfig() : } -xmrig::CommonConfig::~CommonConfig() +void xmrig::CommonConfig::printAPI() { +# ifndef XMRIG_NO_API + if (apiPort() == 0) { + return; + } + + Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN("%s:") CYAN_BOLD("%d") + : " * %-13s%s:%d", + "API BIND", isApiIPv6() ? "[::]" : "0.0.0.0", apiPort()); +# endif +} + + +void xmrig::CommonConfig::printPools() +{ + for (size_t i = 0; i < m_activePools.size(); ++i) { + if (!isColors()) { + Log::i()->text(" * POOL #%-7zu%s variant=%s, TLS=%d", + i + 1, + m_activePools[i].url(), + m_activePools[i].algorithm().variantName(), + static_cast(m_activePools[i].isTLS()) + ); + } + else { + Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") "\x1B[1;%dm%s\x1B[0m variant " WHITE_BOLD("%s"), + i + 1, + m_activePools[i].isTLS() ? 32 : 36, + m_activePools[i].url(), + m_activePools[i].algorithm().variantName() + ); + } + } + +# ifdef APP_DEBUG + LOG_NOTICE("POOLS --------------------------------------------------------------------"); + for (const Pool &pool : m_activePools) { + pool.print(); + } + LOG_NOTICE("--------------------------------------------------------------------------"); +# endif +} + + +void xmrig::CommonConfig::printVersions() +{ + char buf[256] = { 0 }; + +# if defined(__clang__) + snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__); +# elif defined(__GNUC__) + snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +# elif defined(_MSC_VER) + snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION); +# endif + + Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s") + : " * %-13s%s/%s %s", + "ABOUT", APP_NAME, APP_VERSION, buf); + +# if defined(XMRIG_AMD_PROJECT) +# if CL_VERSION_2_0 + const char *ocl = "2.0"; +# elif CL_VERSION_1_2 + const char *ocl = "1.2"; +# elif CL_VERSION_1_1 + const char *ocl = "1.1"; +# elif CL_VERSION_1_0 + const char *ocl = "1.0"; +# else + const char *ocl = "0.0"; +# endif + int length = snprintf(buf, sizeof buf, "OpenCL/%s ", ocl); +# elif defined(XMRIG_NVIDIA_PROJECT) + const int cudaVersion = cuda_get_runtime_version(); + int length = snprintf(buf, sizeof buf, "CUDA/%d.%d ", cudaVersion / 1000, cudaVersion % 100); +# else + memset(buf, 0, 16); + int length = 0; +# endif + +# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT) + { + constexpr const char *v = OPENSSL_VERSION_TEXT + 8; + length += snprintf(buf + length, (sizeof buf) - length, "OpenSSL/%.*s ", static_cast(strchr(v, ' ') - v), v); + } +# endif + +# ifndef XMRIG_NO_HTTPD + length += snprintf(buf + length, (sizeof buf) - length, "microhttpd/%s ", MHD_get_version()); +# endif + + Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s") + : " * %-13slibuv/%s %s", + "LIBS", uv_version_string(), buf); +} + + +bool xmrig::CommonConfig::save() +{ + if (m_fileName.isNull()) { + return false; + } + + uv_fs_t req; + const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName.data(), O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr); + if (fd < 0) { + return false; + } + + uv_fs_req_cleanup(&req); + + rapidjson::Document doc; + getJSON(doc); + + FILE *fp = fdopen(fd, "w"); + + char buf[4096]; + rapidjson::FileWriteStream os(fp, buf, sizeof(buf)); + rapidjson::PrettyWriter writer(os); + doc.Accept(writer); + + fflush(fp); + + uv_fs_close(uv_default_loop(), &req, fd, nullptr); + uv_fs_req_cleanup(&req); + + LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data()); + return true; } @@ -83,13 +239,19 @@ bool xmrig::CommonConfig::finalize() } if (!m_algorithm.isValid()) { - m_algorithm.setAlgo(CRYPTONIGHT); + return false; } for (Pool &pool : m_pools) { - pool.adjust(m_algorithm.algo()); + pool.adjust(m_algorithm); if (pool.isValid() && pool.algorithm().isValid()) { +# ifdef XMRIG_NO_TLS + if (pool.isTLS()) { + continue; + } +# endif + m_activePools.push_back(std::move(pool)); } } @@ -121,6 +283,10 @@ bool xmrig::CommonConfig::parseBoolean(int key, bool enable) m_pools.back().setKeepAlive(enable ? Pool::kKeepAliveTimeout : 0); break; + case TlsKey: /* --tls */ + m_pools.back().setTLS(enable); + break; + # ifndef XMRIG_PROXY_PROJECT case NicehashKey: /* --nicehash */ m_pools.back().setNicehash(enable); @@ -137,9 +303,19 @@ bool xmrig::CommonConfig::parseBoolean(int key, bool enable) case ApiIPv6Key: /* ipv6 */ m_apiIPv6 = enable; + break; case ApiRestrictedKey: /* restricted */ m_apiRestricted = enable; + break; + + case DryRunKey: /* --dry-run */ + m_dryRun = enable; + break; + + case AutoSaveKey: + m_autoSave = enable; + break; default: break; @@ -193,6 +369,10 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) m_pools.back().setRigId(arg); break; + case FingerprintKey: /* --tls-fingerprint */ + m_pools.back().setFingerprint(arg); + break; + case VariantKey: /* --variant */ m_pools.back().algorithm().parseVariant(arg); break; @@ -209,6 +389,10 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) m_apiWorkerId = arg; break; + case ApiIdKey: /* --api-id */ + m_apiId = arg; + break; + case UserAgentKey: /* --user-agent */ m_userAgent = arg; break; @@ -223,7 +407,9 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) case SyslogKey: /* --syslog */ case KeepAliveKey: /* --keepalive */ case NicehashKey: /* --nicehash */ + case TlsKey: /* --tls */ case ApiIPv6Key: /* --api-ipv6 */ + case DryRunKey: /* --dry-run */ return parseBoolean(key, true); case ColorKey: /* --no-color */ @@ -254,40 +440,6 @@ bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg) } -bool xmrig::CommonConfig::save() -{ - if (m_fileName.isNull()) { - return false; - } - - uv_fs_t req; - const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName.data(), O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr); - if (fd < 0) { - return false; - } - - uv_fs_req_cleanup(&req); - - rapidjson::Document doc; - getJSON(doc); - - FILE *fp = fdopen(fd, "w"); - - char buf[4096]; - rapidjson::FileWriteStream os(fp, buf, sizeof(buf)); - rapidjson::PrettyWriter writer(os); - doc.Accept(writer); - - fclose(fp); - - uv_fs_close(uv_default_loop(), &req, fd, nullptr); - uv_fs_req_cleanup(&req); - - LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data()); - return true; -} - - void xmrig::CommonConfig::setFileName(const char *fileName) { m_fileName = fileName; diff --git a/src/common/config/CommonConfig.h b/src/common/config/CommonConfig.h index d54afe3a..422a6bb2 100644 --- a/src/common/config/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -21,17 +21,17 @@ * along with this program. If not, see . */ -#ifndef __COMMONCONFIG_H__ -#define __COMMONCONFIG_H__ +#ifndef XMRIG_COMMONCONFIG_H +#define XMRIG_COMMONCONFIG_H #include +#include "common/interfaces/IConfig.h" #include "common/net/Pool.h" #include "common/utils/c_str.h" #include "common/xmrig.h" -#include "interfaces/IConfig.h" namespace xmrig { @@ -41,14 +41,15 @@ class CommonConfig : public IConfig { public: CommonConfig(); - ~CommonConfig(); inline bool isApiIPv6() const { return m_apiIPv6; } inline bool isApiRestricted() const { return m_apiRestricted; } + inline bool isAutoSave() const { return m_autoSave; } inline bool isBackground() const { return m_background; } inline bool isColors() const { return m_colors; } + inline bool isDryRun() const { return m_dryRun; } inline bool isSyslog() const { return m_syslog; } - inline const Algorithm &algorithm() const { return m_algorithm; } + inline const char *apiId() const { return m_apiId.data(); } inline const char *apiToken() const { return m_apiToken.data(); } inline const char *apiWorkerId() const { return m_apiWorkerId.data(); } inline const char *logFile() const { return m_logFile.data(); } @@ -61,8 +62,15 @@ public: inline int retryPause() const { return m_retryPause; } inline void setColors(bool colors) { m_colors = colors; } - inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); } - inline const char *fileName() const override { return m_fileName.data(); } + inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); } + inline const Algorithm &algorithm() const override { return m_algorithm; } + inline const char *fileName() const override { return m_fileName.data(); } + + bool save() override; + + void printAPI(); + void printPools(); + void printVersions(); protected: enum State { @@ -75,15 +83,16 @@ protected: bool parseBoolean(int key, bool enable) override; bool parseString(int key, const char *arg) override; bool parseUint64(int key, uint64_t arg) override; - bool save() override; void setFileName(const char *fileName) override; Algorithm m_algorithm; bool m_adjusted; bool m_apiIPv6; bool m_apiRestricted; + bool m_autoSave; bool m_background; bool m_colors; + bool m_dryRun; bool m_syslog; bool m_watch; int m_apiPort; @@ -94,6 +103,7 @@ protected: State m_state; std::vector m_activePools; std::vector m_pools; + xmrig::c_str m_apiId; xmrig::c_str m_apiToken; xmrig::c_str m_apiWorkerId; xmrig::c_str m_fileName; diff --git a/src/common/config/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp index 919ff00c..484c2f8f 100644 --- a/src/common/config/ConfigLoader.cpp +++ b/src/common/config/ConfigLoader.cpp @@ -32,14 +32,19 @@ #endif +#ifndef XMRIG_NO_TLS +# include +#endif + + #include "common/config/ConfigLoader.h" #include "common/config/ConfigWatcher.h" +#include "common/interfaces/IConfig.h" +#include "common/interfaces/IWatcherListener.h" #include "common/net/Pool.h" #include "common/Platform.h" #include "core/ConfigCreator.h" #include "core/ConfigLoader_platform.h" -#include "interfaces/IConfig.h" -#include "interfaces/IWatcherListener.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" #include "rapidjson/filereadstream.h" @@ -170,7 +175,13 @@ xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator } if (!config->finalize()) { - fprintf(stderr, "No valid configuration found. Exiting.\n"); + if (!config->algorithm().isValid()) { + fprintf(stderr, "No valid algorithm specified. Exiting.\n"); + } + else { + fprintf(stderr, "No valid configuration found. Exiting.\n"); + } + delete config; return nullptr; } @@ -307,6 +318,13 @@ void xmrig::ConfigLoader::showVersion() printf("\nlibuv/%s\n", uv_version_string()); # ifndef XMRIG_NO_HTTPD - printf("libmicrohttpd/%s\n", MHD_get_version()); + printf("microhttpd/%s\n", MHD_get_version()); +# endif + +# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT) + { + constexpr const char *v = OPENSSL_VERSION_TEXT + 8; + printf("OpenSSL/%.*s\n", static_cast(strchr(v, ' ') - v), v); + } # endif } diff --git a/src/common/config/ConfigWatcher.cpp b/src/common/config/ConfigWatcher.cpp index bde35f23..14107b62 100644 --- a/src/common/config/ConfigWatcher.cpp +++ b/src/common/config/ConfigWatcher.cpp @@ -27,9 +27,9 @@ #include "common/config/ConfigLoader.h" #include "common/config/ConfigWatcher.h" +#include "common/interfaces/IWatcherListener.h" #include "common/log/Log.h" #include "core/ConfigCreator.h" -#include "interfaces/IWatcherListener.h" xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) : diff --git a/src/Cpu_stub.cpp b/src/common/cpu/BasicCpuInfo.cpp similarity index 69% rename from src/Cpu_stub.cpp rename to src/common/cpu/BasicCpuInfo.cpp index 87d9de75..cb1e6d1d 100644 --- a/src/Cpu_stub.cpp +++ b/src/common/cpu/BasicCpuInfo.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,9 @@ * along with this program. If not, see . */ +#include +#include + #ifdef _MSC_VER # include @@ -32,14 +35,8 @@ # define bit_AES (1 << 25) #endif -#ifndef bit_BMI2 -# define bit_BMI2 (1 << 8) -#endif -#include - - -#include "Cpu.h" +#include "common/cpu/BasicCpuInfo.h" #define VENDOR_ID (0) @@ -74,7 +71,7 @@ static inline void cpuid(int level, int output[4]) { static inline void cpu_brand_string(char* s) { - int cpu_info[4] = { 0 }; + int32_t cpu_info[4] = { 0 }; cpuid(VENDOR_ID, cpu_info); if (cpu_info[EAX_Reg] >= 4) { @@ -89,50 +86,46 @@ static inline void cpu_brand_string(char* s) { static inline bool has_aes_ni() { - int cpu_info[4] = { 0 }; + int32_t cpu_info[4] = { 0 }; cpuid(PROCESSOR_INFO, cpu_info); return (cpu_info[ECX_Reg] & bit_AES) != 0; } -static inline bool has_bmi2() { - int cpu_info[4] = { 0 }; - cpuid(EXTENDED_FEATURES, cpu_info); - - return (cpu_info[EBX_Reg] & bit_BMI2) != 0; -} - - -char Cpu::m_brand[64] = { 0 }; -int Cpu::m_flags = 0; -int Cpu::m_l2_cache = 0; -int Cpu::m_l3_cache = 0; -int Cpu::m_sockets = 1; -int Cpu::m_totalCores = 0; -int Cpu::m_totalThreads = 0; - - -int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage) -{ - int count = m_totalThreads / 2; - return count < 1 ? 1 : count; -} - - -void Cpu::initCommon() +xmrig::BasicCpuInfo::BasicCpuInfo() : + m_assembly(ASM_NONE), + m_aes(has_aes_ni()), + m_brand(), + m_threads(std::thread::hardware_concurrency()) { cpu_brand_string(m_brand); -# if defined(__x86_64__) || defined(_M_AMD64) - m_flags |= X86_64; +# ifndef XMRIG_NO_ASM + if (hasAES()) { + char vendor[13] = { 0 }; + int32_t data[4] = { 0 }; + + cpuid(0, data); + + memcpy(vendor + 0, &data[1], 4); + memcpy(vendor + 4, &data[3], 4); + memcpy(vendor + 8, &data[2], 4); + + if (memcmp(vendor, "GenuineIntel", 12) == 0) { + m_assembly = ASM_INTEL; + } + else if (memcmp(vendor, "AuthenticAMD", 12) == 0) { + m_assembly = ASM_RYZEN; + } + } # endif - - if (has_aes_ni()) { - m_flags |= AES; - } - - if (has_bmi2()) { - m_flags |= BMI2; - } +} + + +size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const +{ + const size_t count = threads() / 2; + + return count < 1 ? 1 : count; } diff --git a/src/common/cpu/BasicCpuInfo.h b/src/common/cpu/BasicCpuInfo.h new file mode 100644 index 00000000..911674ea --- /dev/null +++ b/src/common/cpu/BasicCpuInfo.h @@ -0,0 +1,70 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_BASICCPUINFO_H +#define XMRIG_BASICCPUINFO_H + + +#include "common/interfaces/ICpuInfo.h" + + +namespace xmrig { + + +class BasicCpuInfo : public ICpuInfo +{ +public: + BasicCpuInfo(); + +protected: + size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override; + + inline Assembly assembly() const override { return m_assembly; } + inline bool hasAES() const override { return m_aes; } + inline bool isSupported() const override { return true; } + inline const char *brand() const override { return m_brand; } + inline int32_t cores() const override { return -1; } + inline int32_t L2() const override { return -1; } + inline int32_t L3() const override { return -1; } + inline int32_t nodes() const override { return -1; } + inline int32_t sockets() const override { return 1; } + inline int32_t threads() const override { return m_threads; } + +# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__) + inline bool isX64() const override { return true; } +# else + inline bool isX64() const override { return false; } +# endif + +private: + Assembly m_assembly; + bool m_aes; + char m_brand[64]; + int32_t m_threads; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_BASICCPUINFO_H */ diff --git a/src/Cpu_arm.cpp b/src/common/cpu/BasicCpuInfo_arm.cpp similarity index 74% rename from src/Cpu_arm.cpp rename to src/common/cpu/BasicCpuInfo_arm.cpp index 59ff8421..c1c127db 100644 --- a/src/Cpu_arm.cpp +++ b/src/common/cpu/BasicCpuInfo_arm.cpp @@ -21,34 +21,27 @@ * along with this program. If not, see . */ - #include +#include -#include "Cpu.h" +#include "common/cpu/BasicCpuInfo.h" -char Cpu::m_brand[64] = { 0 }; -int Cpu::m_flags = 0; -int Cpu::m_l2_cache = 0; -int Cpu::m_l3_cache = 0; -int Cpu::m_sockets = 1; -int Cpu::m_totalCores = 0; -size_t Cpu::m_totalThreads = 0; - - -size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage) -{ - return m_totalThreads; -} - - -void Cpu::initCommon() +xmrig::BasicCpuInfo::BasicCpuInfo() : + m_aes(false), + m_brand(), + m_threads(std::thread::hardware_concurrency()) { memcpy(m_brand, "Unknown", 7); -# if defined(XMRIG_ARMv8) - m_flags |= X86_64; - m_flags |= AES; +# if __ARM_FEATURE_CRYPTO + m_aes = true; # endif } + + +size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const +{ + return threads(); +} diff --git a/src/Cpu_unix.cpp b/src/common/cpu/Cpu.cpp similarity index 71% rename from src/Cpu_unix.cpp rename to src/common/cpu/Cpu.cpp index b895c897..b1bb28ac 100644 --- a/src/Cpu_unix.cpp +++ b/src/common/cpu/Cpu.cpp @@ -22,33 +22,36 @@ */ -#ifdef __FreeBSD__ -# include -# include -# include -# include -#endif +#include -#include -#include -#include -#include +#include "common/cpu/BasicCpuInfo.h" +#include "common/cpu/Cpu.h" -#include "Cpu.h" +static xmrig::ICpuInfo *cpuInfo = nullptr; -#ifdef __FreeBSD__ -typedef cpuset_t cpu_set_t; -#endif - - -void Cpu::init() +xmrig::ICpuInfo *xmrig::Cpu::info() { -# ifdef XMRIG_NO_LIBCPUID - m_totalThreads = sysconf(_SC_NPROCESSORS_CONF); -# endif + assert(cpuInfo != nullptr); - initCommon(); + return cpuInfo; +} + + +void xmrig::Cpu::init() +{ + assert(cpuInfo == nullptr); + + cpuInfo = new BasicCpuInfo(); +} + + +void xmrig::Cpu::release() +{ + assert(cpuInfo != nullptr); + + delete cpuInfo; + cpuInfo = nullptr; } diff --git a/src/Cpu_mac.cpp b/src/common/cpu/Cpu.h similarity index 75% rename from src/Cpu_mac.cpp rename to src/common/cpu/Cpu.h index 085148bc..1d5a9fb1 100644 --- a/src/Cpu_mac.cpp +++ b/src/common/cpu/Cpu.h @@ -4,7 +4,7 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -21,20 +21,26 @@ * along with this program. If not, see . */ - -#include -#include -#include +#ifndef XMRIG_CPU_H +#define XMRIG_CPU_H -#include "Cpu.h" +#include "common/interfaces/ICpuInfo.h" -void Cpu::init() +namespace xmrig { + + +class Cpu { -# ifdef XMRIG_NO_LIBCPUID - m_totalThreads = sysconf(_SC_NPROCESSORS_CONF); -# endif +public: + static ICpuInfo *info(); + static void init(); + static void release(); +}; - initCommon(); -} + +} /* namespace xmrig */ + + +#endif /* XMRIG_CPU_H */ diff --git a/src/common/crypto/Algorithm.cpp b/src/common/crypto/Algorithm.cpp index fce4d7b8..a3cf48b2 100644 --- a/src/common/crypto/Algorithm.cpp +++ b/src/common/crypto/Algorithm.cpp @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -57,29 +58,43 @@ static AlgoData const algorithms[] = { { "cryptonight/0", "cn/0", xmrig::CRYPTONIGHT, xmrig::VARIANT_0 }, { "cryptonight/1", "cn/1", xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, { "cryptonight/xtl", "cn/xtl", xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, + { "cryptonight/msr", "cn/msr", xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR }, + { "cryptonight/xao", "cn/xao", xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO }, + { "cryptonight/rto", "cn/rto", xmrig::CRYPTONIGHT, xmrig::VARIANT_RTO }, + { "cryptonight/2", "cn/2", xmrig::CRYPTONIGHT, xmrig::VARIANT_2 }, # ifndef XMRIG_NO_AEON { "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO }, + { "cryptonight-light", "cn-light", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO }, { "cryptonight-lite/0", "cn-lite/0", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, { "cryptonight-lite/1", "cn-lite/1", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, - { "cryptonight-lite/ipbc", "cn-lite/ipbc", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IPBC }, # endif # ifndef XMRIG_NO_SUMO - { "cryptonight-heavy", "cn-heavy", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 }, + { "cryptonight-heavy", "cn-heavy", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_AUTO }, + { "cryptonight-heavy/0", "cn-heavy/0", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 }, + { "cryptonight-heavy/xhv", "cn-heavy/xhv", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_XHV }, + { "cryptonight-heavy/tube", "cn-heavy/tube", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_TUBE }, # endif }; #ifdef XMRIG_PROXY_PROJECT static AlgoData const xmrStakAlgorithms[] = { - { "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, - { "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, - { "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, - { "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, - { "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, - { "cryptonight_lite_v7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, - { "cryptonight_lite_v7_xor", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IPBC }, + { "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, + { "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, + { "cryptonight-monerov8", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_2 }, + { "cryptonight_v8", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_2 }, + { "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, + { "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, + { "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, + { "cryptonight_lite_v7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, + { "cryptonight_heavy", nullptr, xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 }, + { "cryptonight_haven", nullptr, xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_XHV }, + { "cryptonight_masari", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR }, + { "cryptonight_masari", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR }, + { "cryptonight-bittube2", nullptr, xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_TUBE }, // bittube-miner + { "cryptonight_alloy", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO }, // xmr-stak-alloy }; #endif @@ -87,8 +102,13 @@ static AlgoData const xmrStakAlgorithms[] = { static const char *variants[] = { "0", "1", - "ipbc", - "xtl" + "tube", + "xtl", + "msr", + "xhv", + "xao", + "rto", + "2", }; @@ -144,11 +164,6 @@ void xmrig::Algorithm::parseAlgorithm(const char *algo) void xmrig::Algorithm::parseVariant(const char *variant) { - if (m_algo == CRYPTONIGHT_HEAVY) { - m_variant = VARIANT_0; - return; - } - m_variant = VARIANT_AUTO; for (size_t i = 0; i < ARRAY_SIZE(variants); i++) { @@ -162,11 +177,21 @@ void xmrig::Algorithm::parseVariant(const char *variant) void xmrig::Algorithm::parseVariant(int variant) { - if (variant >= VARIANT_AUTO && variant <= VARIANT_XTL) { - m_variant = static_cast(variant); - } - else { - assert(false); + assert(variant >= -1 && variant <= 2); + + switch (variant) { + case -1: + case 0: + case 1: + m_variant = static_cast(variant); + break; + + case 2: + m_variant = VARIANT_2; + break; + + default: + break; } } @@ -174,10 +199,6 @@ void xmrig::Algorithm::parseVariant(int variant) void xmrig::Algorithm::setAlgo(Algo algo) { m_algo = algo; - - if (m_algo == CRYPTONIGHT_HEAVY) { - m_variant = VARIANT_0; - } } diff --git a/src/common/crypto/Algorithm.h b/src/common/crypto/Algorithm.h index bcf029d8..731fa793 100644 --- a/src/common/crypto/Algorithm.h +++ b/src/common/crypto/Algorithm.h @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -22,8 +23,8 @@ * along with this program. If not, see . */ -#ifndef __ALGORITHM_H__ -#define __ALGORITHM_H__ +#ifndef XMRIG_ALGORITHM_H +#define XMRIG_ALGORITHM_H #include diff --git a/src/common/crypto/keccak.h b/src/common/crypto/keccak.h index 0413ec2d..6121044a 100644 --- a/src/common/crypto/keccak.h +++ b/src/common/crypto/keccak.h @@ -23,8 +23,8 @@ */ -#ifndef KECCAK_H_ -#define KECCAK_H_ +#ifndef XMRIG_KECCAK_H +#define XMRIG_KECCAK_H #include #include @@ -41,9 +41,15 @@ inline void keccak(const uint8_t *in, size_t inlen, uint8_t *md) keccak(in, static_cast(inlen), md, 200); } + +inline void keccak(const char *in, size_t inlen, uint8_t *md) +{ + keccak(reinterpret_cast(in), static_cast(inlen), md, 200); +} + // update the state void keccakf(uint64_t st[25], int norounds); } /* namespace xmrig */ -#endif /* KECCAK_H_ */ +#endif /* XMRIG_KECCAK_H */ diff --git a/src/interfaces/IClientListener.h b/src/common/interfaces/IClientListener.h similarity index 100% rename from src/interfaces/IClientListener.h rename to src/common/interfaces/IClientListener.h diff --git a/src/interfaces/IConfig.h b/src/common/interfaces/IConfig.h similarity index 76% rename from src/interfaces/IConfig.h rename to src/common/interfaces/IConfig.h index 2422b891..69f2ffab 100644 --- a/src/interfaces/IConfig.h +++ b/src/common/interfaces/IConfig.h @@ -20,10 +20,11 @@ * along with this program. If not, see . */ -#ifndef __ICONFIG_H__ -#define __ICONFIG_H__ +#ifndef XMRIG_ICONFIG_H +#define XMRIG_ICONFIG_H +#include "common/crypto/Algorithm.h" #include "rapidjson/fwd.h" @@ -41,6 +42,7 @@ public: ApiPort = 4000, ApiRestrictedKey = 4004, ApiWorkerIdKey = 4002, + ApiIdKey = 4005, BackgroundKey = 'B', ColorKey = 1002, ConfigKey = 'c', @@ -61,6 +63,9 @@ public: VerboseKey = 1100, VersionKey = 'V', WatchKey = 1105, + TlsKey = 1013, + FingerprintKey = 1014, + AutoSaveKey = 1016, // xmrig common CPUPriorityKey = 1021, @@ -76,6 +81,20 @@ public: SafeKey = 1005, ThreadsKey = 't', HardwareAESKey = 1011, + AssemblyKey = 1015, + + // xmrig amd + OclPlatformKey = 1400, + OclAffinityKey = 1401, + OclDevicesKey = 1402, + OclLaunchKey = 1403, + OclCacheKey = 1404, + OclPrintKey = 1405, + OclLoaderKey = 1406, + OclSridedIndexKey = 1407, + OclMemChunkKey = 1408, + OclUnrollKey = 1409, + OclCompModeKey = 1410, // xmrig-proxy AccessLogFileKey = 'A', @@ -87,6 +106,16 @@ public: PoolCoinKey = 'C', ReuseTimeoutKey = 1106, WorkersKey = 1103, + WorkersAdvKey = 1107, + + // xmrig nvidia + CudaMaxThreadsKey = 1200, + CudaBFactorKey = 1201, + CudaBSleepKey = 1202, + CudaDevicesKey = 1203, + CudaLaunchKey = 1204, + CudaAffinityKey = 1205, + CudaMaxUsageKey = 1206, }; virtual ~IConfig() {} @@ -97,6 +126,7 @@ public: virtual bool parseString(int key, const char *arg) = 0; virtual bool parseUint64(int key, uint64_t arg) = 0; virtual bool save() = 0; + virtual const Algorithm &algorithm() const = 0; virtual const char *fileName() const = 0; virtual void getJSON(rapidjson::Document &doc) const = 0; virtual void parseJSON(const rapidjson::Document &doc) = 0; @@ -107,4 +137,4 @@ public: } /* namespace xmrig */ -#endif // __ICONFIG_H__ +#endif // XMRIG_ICONFIG_H diff --git a/src/interfaces/IConfigCreator.h b/src/common/interfaces/IConfigCreator.h similarity index 100% rename from src/interfaces/IConfigCreator.h rename to src/common/interfaces/IConfigCreator.h diff --git a/src/interfaces/IConsoleListener.h b/src/common/interfaces/IConsoleListener.h similarity index 100% rename from src/interfaces/IConsoleListener.h rename to src/common/interfaces/IConsoleListener.h diff --git a/src/interfaces/IControllerListener.h b/src/common/interfaces/IControllerListener.h similarity index 92% rename from src/interfaces/IControllerListener.h rename to src/common/interfaces/IControllerListener.h index d6077138..35249bcd 100644 --- a/src/interfaces/IControllerListener.h +++ b/src/common/interfaces/IControllerListener.h @@ -21,8 +21,8 @@ * along with this program. If not, see . */ -#ifndef __ICONTROLLERLISTENER_H__ -#define __ICONTROLLERLISTENER_H__ +#ifndef XMRIG_ICONTROLLERLISTENER_H +#define XMRIG_ICONTROLLERLISTENER_H namespace xmrig { @@ -43,4 +43,4 @@ public: } /* namespace xmrig */ -#endif // __ICONTROLLERLISTENER_H__ +#endif // XMRIG_ICONTROLLERLISTENER_H diff --git a/src/common/interfaces/ICpuInfo.h b/src/common/interfaces/ICpuInfo.h new file mode 100644 index 00000000..267616d0 --- /dev/null +++ b/src/common/interfaces/ICpuInfo.h @@ -0,0 +1,60 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2018 XMRig + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CPUINFO_H +#define XMRIG_CPUINFO_H + + +#include +#include + + +#include "common/xmrig.h" + + +namespace xmrig { + + +class ICpuInfo +{ +public: + virtual ~ICpuInfo() {} + + virtual bool hasAES() const = 0; + virtual bool isSupported() const = 0; + virtual bool isX64() const = 0; + virtual const char *brand() const = 0; + virtual int32_t cores() const = 0; + virtual int32_t L2() const = 0; + virtual int32_t L3() const = 0; + virtual int32_t nodes() const = 0; + virtual int32_t sockets() const = 0; + virtual int32_t threads() const = 0; + virtual size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const = 0; + virtual xmrig::Assembly assembly() const = 0; +}; + + +} /* namespace xmrig */ + + +#endif // XMRIG_CPUINFO_H diff --git a/src/interfaces/ILogBackend.h b/src/common/interfaces/ILogBackend.h similarity index 69% rename from src/interfaces/ILogBackend.h rename to src/common/interfaces/ILogBackend.h index 458b504c..85a04e93 100644 --- a/src/interfaces/ILogBackend.h +++ b/src/common/interfaces/ILogBackend.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,15 +26,30 @@ #include +#include class ILogBackend { public: + enum Level { + ERR, + WARNING, + NOTICE, + INFO, + DEBUG + }; + +# ifdef APP_DEBUG + constexpr static const size_t kBufferSize = 1024; +# else + constexpr static const size_t kBufferSize = 512; +# endif + virtual ~ILogBackend() {} - virtual void message(int level, const char* fmt, va_list args) = 0; - virtual void text(const char* fmt, va_list args) = 0; + virtual void message(Level level, const char* fmt, va_list args) = 0; + virtual void text(const char* fmt, va_list args) = 0; }; diff --git a/src/interfaces/IStrategy.h b/src/common/interfaces/IStrategy.h similarity index 100% rename from src/interfaces/IStrategy.h rename to src/common/interfaces/IStrategy.h diff --git a/src/interfaces/IStrategyListener.h b/src/common/interfaces/IStrategyListener.h similarity index 100% rename from src/interfaces/IStrategyListener.h rename to src/common/interfaces/IStrategyListener.h diff --git a/src/interfaces/IWatcherListener.h b/src/common/interfaces/IWatcherListener.h similarity index 100% rename from src/interfaces/IWatcherListener.h rename to src/common/interfaces/IWatcherListener.h diff --git a/src/Cpu.h b/src/common/log/BasicLog.cpp similarity index 50% rename from src/Cpu.h rename to src/common/log/BasicLog.cpp index a125bae8..cb4defcd 100644 --- a/src/Cpu.h +++ b/src/common/log/BasicLog.cpp @@ -21,46 +21,69 @@ * along with this program. If not, see . */ -#ifndef __CPU_H__ -#define __CPU_H__ + +#include +#include +#include +#include +#include + +#ifdef WIN32 +# include +# include +#endif -#include +#include "common/log/BasicLog.h" +#include "common/log/Log.h" -class Cpu +BasicLog::BasicLog() { -public: - enum Flags { - X86_64 = 1, - AES = 2, - BMI2 = 4 - }; - - static size_t optimalThreadsCount(size_t size, int maxCpuUsage); - static void init(); - - static inline bool hasAES() { return (m_flags & AES) != 0; } - static inline bool isX64() { return (m_flags & X86_64) != 0; } - static inline const char *brand() { return m_brand; } - static inline int cores() { return m_totalCores; } - static inline int l2() { return m_l2_cache; } - static inline int l3() { return m_l3_cache; } - static inline int sockets() { return m_sockets; } - static inline int threads() { return m_totalThreads; } - -private: - static void initCommon(); - - static bool m_l2_exclusive; - static char m_brand[64]; - static int m_flags; - static int m_l2_cache; - static int m_l3_cache; - static int m_sockets; - static int m_totalCores; - static size_t m_totalThreads; -}; +} -#endif /* __CPU_H__ */ +void BasicLog::message(Level level, const char* fmt, va_list args) +{ + time_t now = time(nullptr); + tm stime; + +# ifdef _WIN32 + localtime_s(&stime, &now); +# else + localtime_r(&now, &stime); +# endif + + snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s", + stime.tm_year + 1900, + stime.tm_mon + 1, + stime.tm_mday, + stime.tm_hour, + stime.tm_min, + stime.tm_sec, + Log::colorByLevel(level, false), + fmt, + Log::endl(false) + ); + + print(args); +} + + +void BasicLog::text(const char* fmt, va_list args) +{ + snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(false)); + + print(args); +} + + +void BasicLog::print(va_list args) +{ + if (vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args) <= 0) { + return; + } + + fputs(m_buf, stdout); + fflush(stdout); +} diff --git a/src/common/log/BasicLog.h b/src/common/log/BasicLog.h new file mode 100644 index 00000000..523538e9 --- /dev/null +++ b/src/common/log/BasicLog.h @@ -0,0 +1,55 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __BASICLOG_H__ +#define __BASICLOG_H__ + + +#include + + +#include "common/interfaces/ILogBackend.h" + + +namespace xmrig { + class Controller; +} + + +class BasicLog : public ILogBackend +{ +public: + BasicLog(); + + void message(Level level, const char *fmt, va_list args) override; + void text(const char *fmt, va_list args) override; + +private: + bool isWritable() const; + void print(va_list args); + + char m_buf[kBufferSize]; + char m_fmt[256]; +}; + +#endif /* __BASICLOG_H__ */ diff --git a/src/common/log/ConsoleLog.cpp b/src/common/log/ConsoleLog.cpp index b7d187d1..6cf61980 100644 --- a/src/common/log/ConsoleLog.cpp +++ b/src/common/log/ConsoleLog.cpp @@ -66,7 +66,7 @@ ConsoleLog::ConsoleLog(xmrig::Controller *controller) : } -void ConsoleLog::message(int level, const char* fmt, va_list args) +void ConsoleLog::message(Level level, const char* fmt, va_list args) { time_t now = time(nullptr); tm stime; @@ -77,43 +77,18 @@ void ConsoleLog::message(int level, const char* fmt, va_list args) localtime_r(&now, &stime); # endif - const char* color = nullptr; - const bool colors = m_controller->config()->isColors(); + const bool isColors = m_controller->config()->isColors(); - if (colors) { - switch (level) { - case Log::ERR: - color = Log::kCL_RED; - break; - - case Log::WARNING: - color = Log::kCL_YELLOW; - break; - - case Log::NOTICE: - color = Log::kCL_WHITE; - break; - - case Log::DEBUG: - color = Log::kCL_GRAY; - break; - - default: - color = ""; - break; - } - } - - snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n", + snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s", stime.tm_year + 1900, stime.tm_mon + 1, stime.tm_mday, stime.tm_hour, stime.tm_min, stime.tm_sec, - colors ? color : "", + Log::colorByLevel(level, isColors), fmt, - colors ? Log::kCL_N : "" + Log::endl(isColors) ); print(args); @@ -122,7 +97,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args) void ConsoleLog::text(const char* fmt, va_list args) { - snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_controller->config()->isColors() ? Log::kCL_N : ""); + snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(m_controller->config()->isColors())); print(args); } diff --git a/src/common/log/ConsoleLog.h b/src/common/log/ConsoleLog.h index 6649be84..bac09a53 100644 --- a/src/common/log/ConsoleLog.h +++ b/src/common/log/ConsoleLog.h @@ -28,7 +28,7 @@ #include -#include "interfaces/ILogBackend.h" +#include "common/interfaces/ILogBackend.h" namespace xmrig { @@ -41,14 +41,14 @@ class ConsoleLog : public ILogBackend public: ConsoleLog(xmrig::Controller *controller); - void message(int level, const char *fmt, va_list args) override; + void message(Level level, const char *fmt, va_list args) override; void text(const char *fmt, va_list args) override; private: bool isWritable() const; void print(va_list args); - char m_buf[512]; + char m_buf[kBufferSize]; char m_fmt[256]; uv_buf_t m_uvBuf; uv_stream_t *m_stream; diff --git a/src/common/log/FileLog.cpp b/src/common/log/FileLog.cpp index c8eaf5f7..9134c7c7 100644 --- a/src/common/log/FileLog.cpp +++ b/src/common/log/FileLog.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,9 +30,13 @@ #include "common/log/FileLog.h" +#include "common/log/Log.h" +#include "core/Config.h" +#include "core/Controller.h" -FileLog::FileLog(const char *fileName) +FileLog::FileLog(xmrig::Controller *controller, const char *fileName) : + m_controller(controller) { uv_fs_t req; m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr); @@ -40,7 +44,7 @@ FileLog::FileLog(const char *fileName) } -void FileLog::message(int level, const char* fmt, va_list args) +void FileLog::message(Level level, const char* fmt, va_list args) { if (m_file < 0) { return; @@ -55,29 +59,33 @@ void FileLog::message(int level, const char* fmt, va_list args) localtime_r(&now, &stime); # endif - char *buf = new char[512]; - int size = snprintf(buf, 23, "[%d-%02d-%02d %02d:%02d:%02d] ", - stime.tm_year + 1900, - stime.tm_mon + 1, - stime.tm_mday, - stime.tm_hour, - stime.tm_min, - stime.tm_sec); + const bool isColors = m_controller->config()->isColors(); - size = vsnprintf(buf + size, 512 - size - 1, fmt, args) + size; - buf[size] = '\n'; + snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s", + stime.tm_year + 1900, + stime.tm_mon + 1, + stime.tm_mday, + stime.tm_hour, + stime.tm_min, + stime.tm_sec, + Log::colorByLevel(level, isColors), + fmt, + Log::endl(isColors) + ); - write(buf, size + 1); + char *buf = new char[kBufferSize]; + const int size = vsnprintf(buf, kBufferSize - 1, m_fmt, args); + + write(buf, size); } void FileLog::text(const char* fmt, va_list args) { - message(0, fmt, args); + message(INFO, fmt, args); } - void FileLog::onWrite(uv_fs_t *req) { delete [] static_cast(req->data); @@ -93,5 +101,5 @@ void FileLog::write(char *data, size_t size) uv_fs_t *req = new uv_fs_t; req->data = buf.base; - uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, 0, FileLog::onWrite); + uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, -1, FileLog::onWrite); } diff --git a/src/common/log/FileLog.h b/src/common/log/FileLog.h index 2b3ca5d4..8a58d4e4 100644 --- a/src/common/log/FileLog.h +++ b/src/common/log/FileLog.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,15 +28,20 @@ #include -#include "interfaces/ILogBackend.h" +#include "common/interfaces/ILogBackend.h" + + +namespace xmrig { + class Controller; +} class FileLog : public ILogBackend { public: - FileLog(const char *fileName); + FileLog(xmrig::Controller *controller, const char *fileName); - void message(int level, const char* fmt, va_list args) override; + void message(Level level, const char* fmt, va_list args) override; void text(const char* fmt, va_list args) override; private: @@ -44,7 +49,9 @@ private: void write(char *data, size_t size); + char m_fmt[256]; int m_file; + xmrig::Controller *m_controller; }; #endif /* __FILELOG_H__ */ diff --git a/src/common/log/Log.cpp b/src/common/log/Log.cpp index 03237f03..2af90209 100644 --- a/src/common/log/Log.cpp +++ b/src/common/log/Log.cpp @@ -29,14 +29,28 @@ #include +#include "common/interfaces/ILogBackend.h" +#include "common/log/BasicLog.h" #include "common/log/Log.h" -#include "interfaces/ILogBackend.h" Log *Log::m_self = nullptr; -void Log::message(Log::Level level, const char* fmt, ...) +static const char *colors[5] = { + "\x1B[0;31m", /* ERR */ + "\x1B[0;33m", /* WARNING */ + "\x1B[1;37m", /* NOTICE */ + "", /* INFO */ +# ifdef WIN32 + "\x1B[1;30m" /* DEBUG */ +# else + "\x1B[90m" /* DEBUG */ +# endif +}; + + +void Log::message(ILogBackend::Level level, const char* fmt, ...) { uv_mutex_lock(&m_mutex); @@ -76,6 +90,34 @@ void Log::text(const char* fmt, ...) } +const char *Log::colorByLevel(ILogBackend::Level level, bool isColors) +{ + if (!isColors) { + return ""; + } + + return colors[level]; +} + + +const char *Log::endl(bool isColors) +{ +# ifdef _WIN32 + return isColors ? "\x1B[0m\r\n" : "\r\n"; +# else + return isColors ? "\x1B[0m\n" : "\n"; +# endif +} + + +void Log::defaultInit() +{ + m_self = new Log(); + + add(new BasicLog()); +} + + Log::~Log() { for (auto backend : m_backends) { diff --git a/src/common/log/Log.h b/src/common/log/Log.h index 463c2248..2774ae0c 100644 --- a/src/common/log/Log.h +++ b/src/common/log/Log.h @@ -30,39 +30,24 @@ #include -class ILogBackend; +#include "common/interfaces/ILogBackend.h" class Log { public: - enum Level { - ERR, - WARNING, - NOTICE, - INFO, - DEBUG - }; - - constexpr static const char* kCL_N = "\x1B[0m"; - constexpr static const char* kCL_RED = "\x1B[31m"; - constexpr static const char* kCL_YELLOW = "\x1B[33m"; - constexpr static const char* kCL_WHITE = "\x1B[01;37m"; - -# ifdef WIN32 - constexpr static const char* kCL_GRAY = "\x1B[01;30m"; -# else - constexpr static const char* kCL_GRAY = "\x1B[90m"; -# endif - - static inline Log* i() { assert(m_self != nullptr); return m_self; } + static inline Log* i() { if (!m_self) { defaultInit(); } return m_self; } static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); } static inline void init() { if (!m_self) { new Log(); } } static inline void release() { assert(m_self != nullptr); delete m_self; } - void message(Level level, const char* fmt, ...); + void message(ILogBackend::Level level, const char* fmt, ...); void text(const char* fmt, ...); + static const char *colorByLevel(ILogBackend::Level level, bool isColors = true); + static const char *endl(bool isColors = true); + static void defaultInit(); + private: inline Log() { assert(m_self == nullptr); @@ -80,32 +65,34 @@ private: }; -#define RED_BOLD(x) "\e[1;31m" x "\e[0m" -#define RED(x) "\e[0;31m" x "\e[0m" -#define GREEN_BOLD(x) "\e[1;32m" x "\e[0m" -#define GREEN(x) "\e[0;32m" x "\e[0m" -#define MAGENTA_BOLD(x) "\e[1;35m" x "\e[0m" -#define MAGENTA(x) "\e[0;35m" x "\e[0m" -#define CYAN_BOLD(x) "\e[1;36m" x "\e[0m" -#define CYAN(x) "\e[0;36m" x "\e[0m" -#define WHITE_BOLD(x) "\e[1;37m" x "\e[0m" -#define WHITE(x) "\e[0;37m" x "\e[0m" +#define RED_BOLD(x) "\x1B[1;31m" x "\x1B[0m" +#define RED(x) "\x1B[0;31m" x "\x1B[0m" +#define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m" +#define GREEN(x) "\x1B[0;32m" x "\x1B[0m" +#define YELLOW(x) "\x1B[0;33m" x "\x1B[0m" +#define YELLOW_BOLD(x) "\x1B[1;33m" x "\x1B[0m" +#define MAGENTA_BOLD(x) "\x1B[1;35m" x "\x1B[0m" +#define MAGENTA(x) "\x1B[0;35m" x "\x1B[0m" +#define CYAN_BOLD(x) "\x1B[1;36m" x "\x1B[0m" +#define CYAN(x) "\x1B[0;36m" x "\x1B[0m" +#define WHITE_BOLD(x) "\x1B[1;37m" x "\x1B[0m" +#define WHITE(x) "\x1B[0;37m" x "\x1B[0m" -#define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__) -#define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__) -#define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__) -#define LOG_INFO(x, ...) Log::i()->message(Log::INFO, x, ##__VA_ARGS__) +#define LOG_ERR(x, ...) Log::i()->message(ILogBackend::ERR, x, ##__VA_ARGS__) +#define LOG_WARN(x, ...) Log::i()->message(ILogBackend::WARNING, x, ##__VA_ARGS__) +#define LOG_NOTICE(x, ...) Log::i()->message(ILogBackend::NOTICE, x, ##__VA_ARGS__) +#define LOG_INFO(x, ...) Log::i()->message(ILogBackend::INFO, x, ##__VA_ARGS__) #ifdef APP_DEBUG -# define LOG_DEBUG(x, ...) Log::i()->message(Log::DEBUG, x, ##__VA_ARGS__) +# define LOG_DEBUG(x, ...) Log::i()->message(ILogBackend::DEBUG, x, ##__VA_ARGS__) #else # define LOG_DEBUG(x, ...) #endif #if defined(APP_DEBUG) || defined(APP_DEVEL) -# define LOG_DEBUG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__) -# define LOG_DEBUG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__) +# define LOG_DEBUG_ERR(x, ...) Log::i()->message(ILogBackend::ERR, x, ##__VA_ARGS__) +# define LOG_DEBUG_WARN(x, ...) Log::i()->message(ILogBackend::WARNING, x, ##__VA_ARGS__) #else # define LOG_DEBUG_ERR(x, ...) # define LOG_DEBUG_WARN(x, ...) diff --git a/src/common/log/SysLog.cpp b/src/common/log/SysLog.cpp index 70879c33..bcb96394 100644 --- a/src/common/log/SysLog.cpp +++ b/src/common/log/SysLog.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,13 +35,13 @@ SysLog::SysLog() } -void SysLog::message(int level, const char *fmt, va_list args) +void SysLog::message(Level level, const char *fmt, va_list args) { - vsyslog(level, fmt, args); + vsyslog(static_cast(level), fmt, args); } void SysLog::text(const char *fmt, va_list args) { - message(LOG_INFO, fmt, args); + vsyslog(LOG_INFO, fmt, args); } diff --git a/src/common/log/SysLog.h b/src/common/log/SysLog.h index 38de1a6a..5cfeefcd 100644 --- a/src/common/log/SysLog.h +++ b/src/common/log/SysLog.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,7 +25,7 @@ #define __SYSLOG_H__ -#include "interfaces/ILogBackend.h" +#include "common/interfaces/ILogBackend.h" class SysLog : public ILogBackend @@ -33,7 +33,7 @@ class SysLog : public ILogBackend public: SysLog(); - void message(int level, const char *fmt, va_list args) override; + void message(Level level, const char *fmt, va_list args) override; void text(const char *fmt, va_list args) override; }; diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index 921fa618..1d1d86c7 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -29,9 +29,16 @@ #include +#ifndef XMRIG_NO_TLS +# include +# include +# include "common/net/Tls.h" +#endif + + +#include "common/interfaces/IClientListener.h" #include "common/log/Log.h" #include "common/net/Client.h" -#include "interfaces/IClientListener.h" #include "net/JobResult.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" @@ -48,6 +55,17 @@ int64_t Client::m_sequence = 1; xmrig::Storage Client::m_storage; +#ifdef APP_DEBUG +static const char *states[] = { + "unconnected", + "host-lookup", + "connecting", + "connected", + "closing" +}; +#endif + + Client::Client(int id, const char *agent, IClientListener *listener) : m_ipv6(false), m_nicehash(false), @@ -61,6 +79,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) : m_failures(0), m_recvBufPos(0), m_state(UnconnectedState), + m_tls(nullptr), m_expire(0), m_jobs(0), m_keepAlive(0), @@ -92,6 +111,12 @@ Client::~Client() void Client::connect() { +# ifndef XMRIG_NO_TLS + if (m_pool.isTLS()) { + m_tls = new Tls(this); + } +# endif + resolve(m_pool.host()); } @@ -122,6 +147,7 @@ void Client::deleteLater() } + void Client::setPool(const Pool &pool) { if (!pool.isValid()) { @@ -160,6 +186,30 @@ bool Client::disconnect() } +const char *Client::tlsFingerprint() const +{ +# ifndef XMRIG_NO_TLS + if (isTLS() && m_pool.fingerprint() == nullptr) { + return m_tls->fingerprint(); + } +# endif + + return nullptr; +} + + +const char *Client::tlsVersion() const +{ +# ifndef XMRIG_NO_TLS + if (isTLS()) { + return m_tls->version(); + } +# endif + + return nullptr; +} + + int64_t Client::submit(const JobResult &result) { using namespace rapidjson; @@ -209,7 +259,11 @@ int64_t Client::submit(const JobResult &result) bool Client::close() { - if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) { + if (m_state == ClosingState) { + return m_socket != nullptr; + } + + if (m_state == UnconnectedState || m_socket == nullptr) { return false; } @@ -245,6 +299,16 @@ bool Client::isCriticalError(const char *message) } +bool Client::isTLS() const +{ +# ifndef XMRIG_NO_TLS + return m_pool.isTLS() && m_tls; +# else + return false; +# endif +} + + bool Client::parseJob(const rapidjson::Value ¶ms, int *code) { if (!params.IsObject()) { @@ -270,17 +334,17 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) } if (params.HasMember("algo")) { - job.algorithm().parseAlgorithm(params["algo"].GetString()); + job.setAlgorithm(params["algo"].GetString()); } if (params.HasMember("variant")) { const rapidjson::Value &variant = params["variant"]; if (variant.IsInt()) { - job.algorithm().parseVariant(variant.GetInt()); + job.setVariant(variant.GetInt()); } else if (variant.IsString()){ - job.algorithm().parseVariant(variant.GetString()); + job.setVariant(variant.GetString()); } } @@ -330,8 +394,47 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code) } +bool Client::send(BIO *bio) +{ +# ifndef XMRIG_NO_TLS + uv_buf_t buf; + buf.len = BIO_get_mem_data(bio, &buf.base); + + if (buf.len == 0) { + return true; + } + + LOG_DEBUG("[%s] TLS send (%d bytes)", m_pool.url(), static_cast(buf.len)); + + bool result = false; + if (state() == ConnectedState && uv_is_writable(m_stream)) { + result = uv_try_write(m_stream, &buf, 1) > 0; + + if (!result) { + close(); + } + } + else { + LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state); + } + + (void) BIO_reset(bio); + + return result; +# else + return false; +# endif +} + + bool Client::verifyAlgorithm(const xmrig::Algorithm &algorithm) const { +# ifdef XMRIG_PROXY_PROJECT + if (m_pool.algorithm().variant() == xmrig::VARIANT_AUTO || m_id == -1) { + return true; + } +# endif + if (m_pool.isCompatible(algorithm)) { return true; } @@ -383,7 +486,9 @@ int64_t Client::send(const rapidjson::Document &doc) doc.Accept(writer); const size_t size = buffer.GetSize(); - if (size > (sizeof(m_buf) - 2)) { + if (size > (sizeof(m_sendBuf) - 2)) { + LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", m_pool.url(), size, (sizeof(m_sendBuf) - 2)); + close(); return -1; } @@ -398,16 +503,27 @@ int64_t Client::send(const rapidjson::Document &doc) int64_t Client::send(size_t size) { LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf); - if (state() != ConnectedState || !uv_is_writable(m_stream)) { - LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state); - return -1; + +# ifndef XMRIG_NO_TLS + if (isTLS()) { + if (!m_tls->send(m_sendBuf, size)) { + return -1; + } } + else +# endif + { + if (state() != ConnectedState || !uv_is_writable(m_stream)) { + LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state); + return -1; + } - uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size); + uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size); - if (uv_try_write(m_stream, &buf, 1) < 0) { - close(); - return -1; + if (uv_try_write(m_stream, &buf, 1) < 0) { + close(); + return -1; + } } m_expire = uv_now(uv_default_loop()) + kResponseTimeout; @@ -438,7 +554,6 @@ void Client::connect(sockaddr *addr) setState(ConnectingState); reinterpret_cast(addr)->sin_port = htons(m_pool.port()); - delete m_socket; uv_connect_t *req = new uv_connect_t; req->data = m_storage.ptr(m_key); @@ -457,6 +572,22 @@ void Client::connect(sockaddr *addr) } +void Client::handshake() +{ +# ifndef XMRIG_NO_TLS + if (isTLS()) { + m_expire = uv_now(uv_default_loop()) + kResponseTimeout; + + m_tls->handshake(); + } + else +# endif + { + login(); + } +} + + void Client::login() { using namespace rapidjson; @@ -478,13 +609,19 @@ void Client::login() params.AddMember("rigid", StringRef(m_pool.rigId()), allocator); } - Value algo(kArrayType); +# ifdef XMRIG_PROXY_PROJECT + if (m_pool.algorithm().variant() != xmrig::VARIANT_AUTO) +# endif + { + Value algo(kArrayType); - for (const auto &a : m_pool.algorithms()) { - algo.PushBack(StringRef(a.shortName()), allocator); + for (const auto &a : m_pool.algorithms()) { + algo.PushBack(StringRef(a.shortName()), allocator); + } + + params.AddMember("algo", algo, allocator); } - params.AddMember("algo", algo, allocator); doc.AddMember("params", params, allocator); send(doc); @@ -499,6 +636,13 @@ void Client::onClose() m_socket = nullptr; setState(UnconnectedState); +# ifndef XMRIG_NO_TLS + if (m_tls) { + delete m_tls; + m_tls = nullptr; + } +# endif + reconnect(); } @@ -653,6 +797,35 @@ void Client::ping() } +void Client::read() +{ + char* end; + char* start = m_recvBuf.base; + size_t remaining = m_recvBufPos; + + while ((end = static_cast(memchr(start, '\n', remaining))) != nullptr) { + end++; + size_t len = end - start; + parse(start, len); + + remaining -= len; + start = end; + } + + if (remaining == 0) { + m_recvBufPos = 0; + return; + } + + if (start == m_recvBuf.base) { + return; + } + + memcpy(m_recvBuf.base, start, remaining); + m_recvBufPos = remaining; +} + + void Client::reconnect() { if (!m_listener) { @@ -661,13 +834,14 @@ void Client::reconnect() return; } - setState(ConnectingState); m_keepAlive = 0; if (m_failures == -1) { return m_listener->onClose(this, -1); } + setState(ConnectingState); + m_failures++; m_listener->onClose(this, (int) m_failures); @@ -677,7 +851,7 @@ void Client::reconnect() void Client::setState(SocketState state) { - LOG_DEBUG("[%s] state: %d", m_pool.url(), state); + LOG_DEBUG("[%s] state: \"%s\"", m_pool.url(), states[state]); if (m_state == state) { return; @@ -745,7 +919,7 @@ void Client::onConnect(uv_connect_t *req, int status) uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead); delete req; - client->login(); + client->handshake(); } @@ -757,7 +931,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) } if (nread < 0) { - if (nread != UV_EOF && !client->isQuiet()) { + if (!client->isQuiet()) { LOG_ERR("[%s] read error: \"%s\"", client->m_pool.url(), uv_strerror((int) nread)); } @@ -777,30 +951,18 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) client->m_recvBufPos += nread; - char* end; - char* start = client->m_recvBuf.base; - size_t remaining = client->m_recvBufPos; +# ifndef XMRIG_NO_TLS + if (client->isTLS()) { + LOG_DEBUG("[%s] TLS received (%d bytes)", client->m_pool.url(), static_cast(nread)); - while ((end = static_cast(memchr(start, '\n', remaining))) != nullptr) { - end++; - size_t len = end - start; - client->parse(start, len); - - remaining -= len; - start = end; - } - - if (remaining == 0) { + client->m_tls->read(client->m_recvBuf.base, client->m_recvBufPos); client->m_recvBufPos = 0; - return; } - - if (start == client->m_recvBuf.base) { - return; + else +# endif + { + client->read(); } - - memcpy(client->m_recvBuf.base, start, remaining); - client->m_recvBufPos = remaining; } diff --git a/src/common/net/Client.h b/src/common/net/Client.h index 27273092..d6418338 100644 --- a/src/common/net/Client.h +++ b/src/common/net/Client.h @@ -21,8 +21,8 @@ * along with this program. If not, see . */ -#ifndef __CLIENT_H__ -#define __CLIENT_H__ +#ifndef XMRIG_CLIENT_H +#define XMRIG_CLIENT_H #include @@ -30,6 +30,7 @@ #include +#include "common/crypto/Algorithm.h" #include "common/net/Id.h" #include "common/net/Job.h" #include "common/net/Pool.h" @@ -42,6 +43,9 @@ class IClientListener; class JobResult; +typedef struct bio_st BIO; + + class Client { public: @@ -53,12 +57,20 @@ public: ClosingState }; - constexpr static int kResponseTimeout = 20 * 1000; + constexpr static int kResponseTimeout = 20 * 1000; + +# ifndef XMRIG_NO_TLS + constexpr static int kInputBufferSize = 1024 * 16; +# else + constexpr static int kInputBufferSize = 1024 * 2; +# endif Client(int id, const char *agent, IClientListener *listener); ~Client(); bool disconnect(); + const char *tlsFingerprint() const; + const char *tlsVersion() const; int64_t submit(const JobResult &result); void connect(); void connect(const Pool &pool); @@ -66,18 +78,22 @@ public: void setPool(const Pool &pool); void tick(uint64_t now); - inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } - inline const char *host() const { return m_pool.host(); } - inline const char *ip() const { return m_ip; } - inline const Job &job() const { return m_job; } - inline int id() const { return m_id; } - inline SocketState state() const { return m_state; } - inline uint16_t port() const { return m_pool.port(); } - inline void setQuiet(bool quiet) { m_quiet = quiet; } - inline void setRetries(int retries) { m_retries = retries; } - inline void setRetryPause(int ms) { m_retryPause = ms; } + inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } + inline const char *host() const { return m_pool.host(); } + inline const char *ip() const { return m_ip; } + inline const Job &job() const { return m_job; } + inline int id() const { return m_id; } + inline SocketState state() const { return m_state; } + inline uint16_t port() const { return m_pool.port(); } + inline void setAlgo(const xmrig::Algorithm &algo) { m_pool.setAlgo(algo); } + inline void setQuiet(bool quiet) { m_quiet = quiet; } + inline void setRetries(int retries) { m_retries = retries; } + inline void setRetryPause(int ms) { m_retryPause = ms; } private: + class Tls; + + enum Extensions { NicehashExt = 1, AlgoExt = 2 @@ -85,14 +101,17 @@ private: bool close(); bool isCriticalError(const char *message); + bool isTLS() const; bool parseJob(const rapidjson::Value ¶ms, int *code); bool parseLogin(const rapidjson::Value &result, int *code); + bool send(BIO *bio); bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const; int resolve(const char *host); int64_t send(const rapidjson::Document &doc); int64_t send(size_t size); void connect(const std::vector &ipv4, const std::vector &ipv6); void connect(sockaddr *addr); + void handshake(); void login(); void onClose(); void parse(char *line, size_t len); @@ -100,6 +119,7 @@ private: void parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error); void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error); void ping(); + void read(); void reconnect(); void setState(SocketState state); void startTimeout(); @@ -118,9 +138,9 @@ private: bool m_ipv6; bool m_nicehash; bool m_quiet; - char m_buf[2048]; + char m_buf[kInputBufferSize]; char m_ip[46]; - char m_sendBuf[768]; + char m_sendBuf[2048]; const char *m_agent; IClientListener *m_listener; int m_extensions; @@ -133,6 +153,7 @@ private: size_t m_recvBufPos; SocketState m_state; std::map m_results; + Tls *m_tls; uint64_t m_expire; uint64_t m_jobs; uint64_t m_keepAlive; @@ -148,4 +169,4 @@ private: }; -#endif /* __CLIENT_H__ */ +#endif /* XMRIG_CLIENT_H */ diff --git a/src/common/net/Job.cpp b/src/common/net/Job.cpp index 34aab326..2bfb39f0 100644 --- a/src/common/net/Job.cpp +++ b/src/common/net/Job.cpp @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -58,6 +59,7 @@ static inline char hf_bin2hex(unsigned char c) Job::Job() : + m_autoVariant(false), m_nicehash(false), m_poolId(-2), m_threadId(-1), @@ -69,7 +71,8 @@ Job::Job() : } -Job::Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId) : +Job::Job(int poolId, bool nicehash, const xmrig::Algorithm &algorithm, const xmrig::Id &clientId) : + m_autoVariant(algorithm.variant() == xmrig::VARIANT_AUTO), m_nicehash(nicehash), m_poolId(poolId), m_threadId(-1), @@ -112,6 +115,10 @@ bool Job::setBlob(const char *blob) m_nicehash = true; } + if (m_autoVariant) { + m_algorithm.setVariant(variant()); + } + # ifdef XMRIG_PROXY_PROJECT memset(m_rawBlob, 0, sizeof(m_rawBlob)); memcpy(m_rawBlob, blob, m_size * 2); @@ -163,6 +170,16 @@ bool Job::setTarget(const char *target) } +void Job::setAlgorithm(const char *algo) +{ + m_algorithm.parseAlgorithm(algo); + + if (m_algorithm.variant() == xmrig::VARIANT_AUTO) { + m_algorithm.setVariant(variant()); + } +} + + bool Job::fromHex(const char* in, unsigned int len, unsigned char* out) { bool error = false; @@ -207,3 +224,25 @@ bool Job::operator!=(const Job &other) const { return m_id != other.m_id || memcmp(m_blob, other.m_blob, sizeof(m_blob)) != 0; } + + +xmrig::Variant Job::variant() const +{ + using namespace xmrig; + + switch (m_algorithm.algo()) { + case CRYPTONIGHT: + return (m_blob[0] >= 8) ? VARIANT_2 : VARIANT_1; + + case CRYPTONIGHT_LITE: + return VARIANT_1; + + case CRYPTONIGHT_HEAVY: + return VARIANT_0; + + default: + break; + } + + return m_algorithm.variant(); +} diff --git a/src/common/net/Job.h b/src/common/net/Job.h index 08d5ae82..b561b9c1 100644 --- a/src/common/net/Job.h +++ b/src/common/net/Job.h @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -22,8 +23,8 @@ * along with this program. If not, see . */ -#ifndef __JOB_H__ -#define __JOB_H__ +#ifndef XMRIG_JOB_H +#define XMRIG_JOB_H #include @@ -38,11 +39,12 @@ class Job { public: Job(); - Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId); + Job(int poolId, bool nicehash, const xmrig::Algorithm &algorithm, const xmrig::Id &clientId); ~Job(); bool setBlob(const char *blob); bool setTarget(const char *target); + void setAlgorithm(const char *algo); inline bool isNicehash() const { return m_nicehash; } inline bool isValid() const { return m_size > 0 && m_diff > 0; } @@ -62,12 +64,8 @@ public: inline void setClientId(const xmrig::Id &id) { m_clientId = id; } inline void setPoolId(int poolId) { m_poolId = poolId; } inline void setThreadId(int threadId) { m_threadId = threadId; } - inline xmrig::Algorithm &algorithm() { return m_algorithm; } - - inline xmrig::Variant variant() const - { - return (m_algorithm.variant() == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_1 : xmrig::VARIANT_0) : m_algorithm.variant()); - } + inline void setVariant(const char *variant) { m_algorithm.parseVariant(variant); } + inline void setVariant(int variant) { m_algorithm.parseVariant(variant); } # ifdef XMRIG_PROXY_PROJECT inline char *rawBlob() { return m_rawBlob; } @@ -87,6 +85,9 @@ public: bool operator!=(const Job &other) const; private: + xmrig::Variant variant() const; + + bool m_autoVariant; bool m_nicehash; int m_poolId; int m_threadId; @@ -104,4 +105,4 @@ private: # endif }; -#endif /* __JOB_H__ */ +#endif /* XMRIG_JOB_H */ diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index 8c0de46a..141e5115 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -5,6 +5,7 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -45,6 +46,7 @@ Pool::Pool() : m_nicehash(false), + m_tls(false), m_keepAlive(0), m_port(kDefaultPort) { @@ -64,6 +66,7 @@ Pool::Pool() : */ Pool::Pool(const char *url) : m_nicehash(false), + m_tls(false), m_keepAlive(0), m_port(kDefaultPort) { @@ -71,8 +74,9 @@ Pool::Pool(const char *url) : } -Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash) : +Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls) : m_nicehash(nicehash), + m_tls(tls), m_keepAlive(keepAlive), m_port(port), m_host(host), @@ -91,27 +95,39 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo bool Pool::isCompatible(const xmrig::Algorithm &algorithm) const { + if (m_algorithms.empty()) { + return true; + } + for (const auto &a : m_algorithms) { if (algorithm == a) { return true; } } +# ifdef XMRIG_PROXY_PROJECT + if (m_algorithm.algo() == xmrig::CRYPTONIGHT && algorithm.algo() == xmrig::CRYPTONIGHT && m_algorithm.variant() == xmrig::VARIANT_XTL) { + return true; + } +# endif + return false; } bool Pool::isEqual(const Pool &other) const { - return (m_nicehash == other.m_nicehash - && m_keepAlive == other.m_keepAlive - && m_port == other.m_port - && m_algorithm == other.m_algorithm - && m_host == other.m_host - && m_password == other.m_password - && m_rigId == other.m_rigId - && m_url == other.m_url - && m_user == other.m_user); + return (m_nicehash == other.m_nicehash + && m_tls == other.m_tls + && m_keepAlive == other.m_keepAlive + && m_port == other.m_port + && m_algorithm == other.m_algorithm + && m_fingerprint == other.m_fingerprint + && m_host == other.m_host + && m_password == other.m_password + && m_rigId == other.m_rigId + && m_url == other.m_url + && m_user == other.m_user); } @@ -123,7 +139,13 @@ bool Pool::parse(const char *url) const char *base = url; if (p) { - if (strncasecmp(url, "stratum+tcp://", 14)) { + if (strncasecmp(url, "stratum+tcp://", 14) == 0) { + m_tls = false; + } + else if (strncasecmp(url, "stratum+ssl://", 14) == 0) { + m_tls = true; + } + else { return false; } @@ -201,6 +223,7 @@ rapidjson::Value Pool::toJSON(rapidjson::Document &doc) const case xmrig::VARIANT_AUTO: case xmrig::VARIANT_0: case xmrig::VARIANT_1: + case xmrig::VARIANT_2: obj.AddMember("variant", m_algorithm.variant(), allocator); break; @@ -209,45 +232,33 @@ rapidjson::Value Pool::toJSON(rapidjson::Document &doc) const break; } + obj.AddMember("tls", isTLS(), allocator); + obj.AddMember("tls-fingerprint", fingerprint() ? Value(StringRef(fingerprint())).Move() : Value(kNullType).Move(), allocator); + return obj; } -void Pool::adjust(xmrig::Algo algorithm) +void Pool::adjust(const xmrig::Algorithm &algorithm) { if (!isValid()) { return; } if (!m_algorithm.isValid()) { - m_algorithm.setAlgo(algorithm); + m_algorithm.setAlgo(algorithm.algo()); + adjustVariant(algorithm.variant()); } - if (strstr(m_host.data(), ".nicehash.com")) { - m_keepAlive = false; - m_nicehash = true; + rebuild(); +} - if (strstr(m_host.data(), "cryptonightv7.")) { - m_algorithm.setVariant(xmrig::VARIANT_1); - } - } - if (strstr(m_host.data(), ".minergate.com")) { - m_keepAlive = false; - m_algorithm.setVariant(xmrig::VARIANT_1); - } +void Pool::setAlgo(const xmrig::Algorithm &algorithm) +{ + m_algorithm = algorithm; - m_algorithms.push_back(m_algorithm); - -# ifndef XMRIG_PROXY_PROJECT - if (m_algorithm.algo() != xmrig::CRYPTONIGHT_HEAVY) { - addVariant(xmrig::VARIANT_1); - addVariant(xmrig::VARIANT_0); - addVariant(xmrig::VARIANT_XTL); - addVariant(xmrig::VARIANT_IPBC); - addVariant(xmrig::VARIANT_AUTO); - } -# endif + rebuild(); } @@ -299,3 +310,98 @@ void Pool::addVariant(xmrig::Variant variant) m_algorithms.push_back(algorithm); } + + +void Pool::adjustVariant(const xmrig::Variant variantHint) +{ +# ifndef XMRIG_PROXY_PROJECT + using namespace xmrig; + + if (m_host.contains(".nicehash.com")) { + m_keepAlive = false; + m_nicehash = true; + bool valid = true; + + if (m_host.contains("cryptonight.") && m_port == 3355) { + valid = m_algorithm.algo() == CRYPTONIGHT; + m_algorithm.setVariant(VARIANT_0); + } + else if (m_host.contains("cryptonightv7.") && m_port == 3363) { + valid = m_algorithm.algo() == CRYPTONIGHT; + m_algorithm.setVariant(VARIANT_1); + } + else if (m_host.contains("cryptonightheavy.") && m_port == 3364) { + valid = m_algorithm.algo() == CRYPTONIGHT_HEAVY; + m_algorithm.setVariant(VARIANT_0); + } + + if (!valid) { + m_algorithm.setAlgo(INVALID_ALGO); + } + + return; + } + + if (m_host.contains(".minergate.com")) { + m_keepAlive = false; + bool valid = true; + m_algorithm.setVariant(VARIANT_1); + + if (m_host.contains("xmr.pool.")) { + valid = m_algorithm.algo() == CRYPTONIGHT; + m_algorithm.setVariant(m_port == 45700 ? VARIANT_1 : VARIANT_0); + } + else if (m_host.contains("aeon.pool.") && m_port == 45690) { + valid = m_algorithm.algo() == CRYPTONIGHT_LITE; + m_algorithm.setVariant(VARIANT_1); + } + + if (!valid) { + m_algorithm.setAlgo(INVALID_ALGO); + } + + return; + } + + if (variantHint != VARIANT_AUTO) { + m_algorithm.setVariant(variantHint); + return; + } + + if (m_algorithm.variant() != VARIANT_AUTO) { + return; + } + + if (m_algorithm.algo() == CRYPTONIGHT_HEAVY) { + m_algorithm.setVariant(VARIANT_0); + } + else if (m_algorithm.algo() == CRYPTONIGHT_LITE) { + m_algorithm.setVariant(VARIANT_1); + } +# endif +} + + +void Pool::rebuild() +{ + m_algorithms.clear(); + + if (!m_algorithm.isValid()) { + return; + } + + m_algorithms.push_back(m_algorithm); + +# ifndef XMRIG_PROXY_PROJECT + addVariant(xmrig::VARIANT_2); + addVariant(xmrig::VARIANT_1); + addVariant(xmrig::VARIANT_0); + addVariant(xmrig::VARIANT_XTL); + addVariant(xmrig::VARIANT_TUBE); + addVariant(xmrig::VARIANT_MSR); + addVariant(xmrig::VARIANT_XHV); + addVariant(xmrig::VARIANT_XAO); + addVariant(xmrig::VARIANT_RTO); + addVariant(xmrig::VARIANT_AUTO); +# endif +} diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index ad015bf2..123cc131 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -5,6 +5,7 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -21,8 +22,8 @@ * along with this program. If not, see . */ -#ifndef __POOL_H__ -#define __POOL_H__ +#ifndef XMRIG_POOL_H +#define XMRIG_POOL_H #include @@ -44,30 +45,35 @@ public: Pool(); Pool(const char *url); Pool(const char *host, - uint16_t port, - const char *user = nullptr, - const char *password = nullptr, - int keepAlive = 0, - bool nicehash = false + uint16_t port, + const char *user = nullptr, + const char *password = nullptr, + int keepAlive = 0, + bool nicehash = false, + bool tls = false ); - inline bool isNicehash() const { return m_nicehash; } - inline bool isValid() const { return !m_host.isNull() && m_port > 0; } - inline const char *host() const { return m_host.data(); } - inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } - inline const char *rigId() const { return m_rigId.data(); } - inline const char *url() const { return m_url.data(); } - inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } - inline const xmrig::Algorithm &algorithm() const { return m_algorithm; } - inline const xmrig::Algorithms &algorithms() const { return m_algorithms; } - inline int keepAlive() const { return m_keepAlive; } - inline uint16_t port() const { return m_port; } - inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } - inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } - inline void setPassword(const char *password) { m_password = password; } - inline void setRigId(const char *rigId) { m_rigId = rigId; } - inline void setUser(const char *user) { m_user = user; } - inline xmrig::Algorithm &algorithm() { return m_algorithm; } + inline bool isNicehash() const { return m_nicehash; } + inline bool isTLS() const { return m_tls; } + inline bool isValid() const { return !m_host.isNull() && m_port > 0; } + inline const char *fingerprint() const { return m_fingerprint.data(); } + inline const char *host() const { return m_host.data(); } + inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } + inline const char *rigId() const { return m_rigId.data(); } + inline const char *url() const { return m_url.data(); } + inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } + inline const xmrig::Algorithm &algorithm() const { return m_algorithm; } + inline const xmrig::Algorithms &algorithms() const { return m_algorithms; } + inline int keepAlive() const { return m_keepAlive; } + inline uint16_t port() const { return m_port; } + inline void setFingerprint(const char *fingerprint) { m_fingerprint = fingerprint; } + inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } + inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } + inline void setPassword(const char *password) { m_password = password; } + inline void setRigId(const char *rigId) { m_rigId = rigId; } + inline void setTLS(bool tls) { m_tls = tls; } + inline void setUser(const char *user) { m_user = user; } + inline xmrig::Algorithm &algorithm() { return m_algorithm; } inline bool operator!=(const Pool &other) const { return !isEqual(other); } inline bool operator==(const Pool &other) const { return isEqual(other); } @@ -77,7 +83,8 @@ public: bool parse(const char *url); bool setUserpass(const char *userpass); rapidjson::Value toJSON(rapidjson::Document &doc) const; - void adjust(xmrig::Algo algorithm); + void adjust(const xmrig::Algorithm &algorithm); + void setAlgo(const xmrig::Algorithm &algorithm); # ifdef APP_DEBUG void print() const; @@ -86,12 +93,16 @@ public: private: bool parseIPv6(const char *addr); void addVariant(xmrig::Variant variant); + void adjustVariant(const xmrig::Variant variantHint); + void rebuild(); bool m_nicehash; + bool m_tls; int m_keepAlive; uint16_t m_port; xmrig::Algorithm m_algorithm; xmrig::Algorithms m_algorithms; + xmrig::c_str m_fingerprint; xmrig::c_str m_host; xmrig::c_str m_password; xmrig::c_str m_rigId; @@ -102,4 +113,4 @@ private: typedef std::vector Pools; -#endif /* __POOL_H__ */ +#endif /* XMRIG_POOL_H */ diff --git a/src/common/net/Tls.cpp b/src/common/net/Tls.cpp new file mode 100644 index 00000000..182d86ff --- /dev/null +++ b/src/common/net/Tls.cpp @@ -0,0 +1,190 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018 SChernykh + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "common/net/Client.h" +#include "common/net/Tls.h" +#include "common/log/Log.h" + + +#ifdef _MSC_VER +# define strncasecmp(x,y,z) _strnicmp(x,y,z) +#endif + + +Client::Tls::Tls(Client *client) : + m_ready(false), + m_buf(), + m_fingerprint(), + m_client(client), + m_ssl(nullptr) +{ + m_ctx = SSL_CTX_new(SSLv23_method()); + assert(m_ctx != nullptr); + + if (!m_ctx) { + return; + } + + m_writeBio = BIO_new(BIO_s_mem()); + m_readBio = BIO_new(BIO_s_mem()); + SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); +} + + +Client::Tls::~Tls() +{ + if (m_ctx) { + SSL_CTX_free(m_ctx); + } + + if (m_ssl) { + SSL_free(m_ssl); + } +} + + +bool Client::Tls::handshake() +{ + m_ssl = SSL_new(m_ctx); + assert(m_ssl != nullptr); + + if (!m_ssl) { + return false; + } + + SSL_set_connect_state(m_ssl); + SSL_set_bio(m_ssl, m_readBio, m_writeBio); + SSL_do_handshake(m_ssl); + + return send(); +} + + +bool Client::Tls::send(const char *data, size_t size) +{ + SSL_write(m_ssl, data, size); + + return send(); +} + + +const char *Client::Tls::fingerprint() const +{ + return m_ready ? m_fingerprint : nullptr; +} + + +const char *Client::Tls::version() const +{ + return m_ready ? SSL_get_version(m_ssl) : nullptr; +} + + +void Client::Tls::read(const char *data, size_t size) +{ + BIO_write(m_readBio, data, size); + + if (!SSL_is_init_finished(m_ssl)) { + const int rc = SSL_connect(m_ssl); + + if (rc < 0 && SSL_get_error(m_ssl, rc) == SSL_ERROR_WANT_READ) { + send(); + } else if (rc == 1) { + X509 *cert = SSL_get_peer_certificate(m_ssl); + if (!verify(cert)) { + X509_free(cert); + m_client->close(); + + return; + } + + X509_free(cert); + m_ready = true; + m_client->login(); + } + + return; + } + + int bytes_read = 0; + while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) { + m_client->parse(m_buf, bytes_read); + } +} + + +bool Client::Tls::send() +{ + return m_client->send(m_writeBio); +} + + +bool Client::Tls::verify(X509 *cert) +{ + if (cert == nullptr) { + LOG_ERR("[%s] Failed to get server certificate", m_client->m_pool.url()); + + return false; + } + + if (!verifyFingerprint(cert)) { + LOG_ERR("[%s] Failed to verify server certificate fingerprint", m_client->m_pool.url()); + + const char *fingerprint = m_client->m_pool.fingerprint(); + if (strlen(m_fingerprint) == 64 && fingerprint != nullptr) { + LOG_ERR("\"%s\" was given", m_fingerprint); + LOG_ERR("\"%s\" was configured", fingerprint); + } + + return false; + } + + return true; +} + + +bool Client::Tls::verifyFingerprint(X509 *cert) +{ + const EVP_MD *digest = EVP_get_digestbyname("sha256"); + if (digest == nullptr) { + return false; + } + + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int dlen; + + if (X509_digest(cert, digest, md, &dlen) != 1) { + return false; + } + + Job::toHex(md, 32, m_fingerprint); + const char *fingerprint = m_client->m_pool.fingerprint(); + + return fingerprint == nullptr || strncasecmp(m_fingerprint, fingerprint, 64) == 0; +} diff --git a/src/common/net/Tls.h b/src/common/net/Tls.h new file mode 100644 index 00000000..6e38f32f --- /dev/null +++ b/src/common/net/Tls.h @@ -0,0 +1,62 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_TLS_H +#define XMRIG_TLS_H + + +#include + + +#include "common/net/Client.h" + + +class Client::Tls +{ +public: + Tls(Client *client); + ~Tls(); + + bool handshake(); + bool send(const char *data, size_t size); + const char *fingerprint() const; + const char *version() const; + void read(const char *data, size_t size); + +private: + bool send(); + bool verify(X509 *cert); + bool verifyFingerprint(X509 *cert); + + BIO *m_readBio; + BIO *m_writeBio; + bool m_ready; + char m_buf[1024 * 2]; + char m_fingerprint[32 * 2 + 8]; + Client *m_client; + SSL *m_ssl; + SSL_CTX *m_ctx; +}; + + +#endif /* XMRIG_TLS_H */ diff --git a/src/common/net/strategies/FailoverStrategy.cpp b/src/common/net/strategies/FailoverStrategy.cpp index 295b4335..fab78590 100644 --- a/src/common/net/strategies/FailoverStrategy.cpp +++ b/src/common/net/strategies/FailoverStrategy.cpp @@ -22,10 +22,10 @@ */ +#include "common/interfaces/IStrategyListener.h" #include "common/net/Client.h" #include "common/net/strategies/FailoverStrategy.h" #include "common/Platform.h" -#include "interfaces/IStrategyListener.h" FailoverStrategy::FailoverStrategy(const std::vector &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) : diff --git a/src/common/net/strategies/FailoverStrategy.h b/src/common/net/strategies/FailoverStrategy.h index f86b366a..07095b3b 100644 --- a/src/common/net/strategies/FailoverStrategy.h +++ b/src/common/net/strategies/FailoverStrategy.h @@ -28,9 +28,9 @@ #include +#include "common/interfaces/IClientListener.h" +#include "common/interfaces/IStrategy.h" #include "common/net/Pool.h" -#include "interfaces/IClientListener.h" -#include "interfaces/IStrategy.h" class Client; diff --git a/src/common/net/strategies/SinglePoolStrategy.cpp b/src/common/net/strategies/SinglePoolStrategy.cpp index 21ce7b34..2cfc0976 100644 --- a/src/common/net/strategies/SinglePoolStrategy.cpp +++ b/src/common/net/strategies/SinglePoolStrategy.cpp @@ -22,10 +22,10 @@ */ +#include "common/interfaces/IStrategyListener.h" #include "common/net/Client.h" #include "common/net/strategies/SinglePoolStrategy.h" #include "common/Platform.h" -#include "interfaces/IStrategyListener.h" SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet) : diff --git a/src/common/net/strategies/SinglePoolStrategy.h b/src/common/net/strategies/SinglePoolStrategy.h index 41d90e34..1a48d678 100644 --- a/src/common/net/strategies/SinglePoolStrategy.h +++ b/src/common/net/strategies/SinglePoolStrategy.h @@ -25,8 +25,8 @@ #define __SINGLEPOOLSTRATEGY_H__ -#include "interfaces/IClientListener.h" -#include "interfaces/IStrategy.h" +#include "common/interfaces/IClientListener.h" +#include "common/interfaces/IStrategy.h" class Client; diff --git a/src/common/utils/c_str.h b/src/common/utils/c_str.h index 3cc4d326..7ce63754 100644 --- a/src/common/utils/c_str.h +++ b/src/common/utils/c_str.h @@ -72,6 +72,12 @@ public: } + inline bool contains(const char *str) const + { + return strstr(m_data, str) != nullptr; + } + + inline bool isNull() const { return m_data == nullptr; } inline const char *data() const { return m_data; } inline size_t size() const { return m_data == nullptr ? 0 : strlen(m_data); } diff --git a/src/common/utils/timestamp.h b/src/common/utils/timestamp.h new file mode 100644 index 00000000..6b6a8ab2 --- /dev/null +++ b/src/common/utils/timestamp.h @@ -0,0 +1,47 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_TIMESTAMP_H +#define XMRIG_TIMESTAMP_H + + +#include + + +namespace xmrig { + + +static inline int64_t currentMSecsSinceEpoch() +{ + using namespace std::chrono; + if (high_resolution_clock::is_steady) { + return time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); + } + + return time_point_cast(steady_clock::now()).time_since_epoch().count(); +} + + +} /* namespace xmrig */ + +#endif /* XMRIG_TIMESTAMP_H */ diff --git a/src/common/xmrig.h b/src/common/xmrig.h index a6fda9fc..52650f0d 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -21,8 +21,8 @@ * along with this program. If not, see . */ -#ifndef __XMRIG_H__ -#define __XMRIG_H__ +#ifndef XMRIG_XMRIG_H +#define XMRIG_XMRIG_H namespace xmrig @@ -33,7 +33,7 @@ enum Algo { INVALID_ALGO = -1, CRYPTONIGHT, /* CryptoNight (Monero) */ CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ - CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (SUMO) */ + CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (RYO) */ }; @@ -61,8 +61,20 @@ enum Variant { VARIANT_AUTO = -1, // Autodetect VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7 - VARIANT_IPBC = 2, // CryptoNight Lite variant 1 with XOR (IPBC only) - VARIANT_XTL = 3 // CryptoNight variant 1 (Stellite only) + VARIANT_TUBE = 2, // Modified CryptoNight-Heavy (TUBE only) + VARIANT_XTL = 3, // Modified CryptoNight variant 1 (Stellite only) + VARIANT_MSR = 4, // Modified CryptoNight variant 1 (Masari only) + VARIANT_XHV = 5, // Modified CryptoNight-Heavy (Haven Protocol only) + VARIANT_XAO = 6, // Modified CryptoNight variant 0 (Alloy only) + VARIANT_RTO = 7, // Modified CryptoNight variant 1 (Arto only) + VARIANT_2 = 8, // CryptoNight variant 2 + VARIANT_MAX +}; + + +enum AlgoVerify { + VERIFY_HW_AES = 1, + VERIFY_SOFT_AES = 2 }; @@ -73,7 +85,25 @@ enum AesMode { }; +enum OclVendor { + OCL_VENDOR_UNKNOWN = -2, + OCL_VENDOR_MANUAL = -1, + OCL_VENDOR_AMD = 0, + OCL_VENDOR_NVIDIA = 1, + OCL_VENDOR_INTEL = 2 +}; + + +enum Assembly { + ASM_NONE, + ASM_AUTO, + ASM_INTEL, + ASM_RYZEN, + ASM_MAX +}; + + } /* namespace xmrig */ -#endif /* __XMRIG_H__ */ +#endif /* XMRIG_XMRIG_H */ diff --git a/src/config.json b/src/config.json index 3013ba62..ae85b1f7 100644 --- a/src/config.json +++ b/src/config.json @@ -1,34 +1,43 @@ { - "algo": "cryptonight", // cryptonight (default) or cryptonight-lite - "av": 0, // algorithm variation, 0 auto select - "background": false, // true to run the miner in the background - "colors": true, // false to disable colored output - "cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1 - "cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest) - "donate-level": 5, // donate level, mininum 1% - "log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log" - "max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option. - "print-time": 60, // print hashrate report every N seconds - "retries": 5, // number of times to retry before switch to backup server - "retry-pause": 5, // time to pause between retries - "safe": false, // true to safe adjust threads and av settings for current CPU - "syslog": false, // use system log for output messages - "threads": null, // number of miner threads - "pools": [ - { - "url": "failover.xmrig.com:443", // URL of mining server - "user": "YOUR_WALLET", // username for mining server - "pass": "x", // password for mining server - "keepalive": true, // send keepalived for prevent timeout (need pool support) - "nicehash": false, // enable nicehash/xmrig-proxy support - "variant": -1 // algorithm PoW variant - } - ], + "algo": "cryptonight", "api": { - "port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API - "access-token": null, // access token for API - "worker-id": null, // custom worker-id for API + "port": 0, + "access-token": null, + "id": null, + "worker-id": null, "ipv6": false, "restricted": true - } + }, + "asm": true, + "autosave": true, + "av": 0, + "background": false, + "colors": true, + "cpu-affinity": null, + "cpu-priority": null, + "donate-level": 5, + "huge-pages": true, + "hw-aes": null, + "log-file": null, + "max-cpu-usage": 75, + "pools": [ + { + "url": "donate.v2.xmrig.com:3333", + "user": "YOUR_WALLET_ADDRESS", + "pass": "x", + "rig-id": null, + "nicehash": false, + "keepalive": false, + "variant": -1, + "tls": false, + "tls-fingerprint": null + } + ], + "print-time": 60, + "retries": 5, + "retry-pause": 5, + "safe": false, + "threads": null, + "user-agent": null, + "watch": false } \ No newline at end of file diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 0c4ce779..c8891c77 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -27,9 +27,10 @@ #include "common/config/ConfigLoader.h" +#include "common/cpu/Cpu.h" #include "core/Config.h" #include "core/ConfigCreator.h" -#include "Cpu.h" +#include "crypto/Asm.h" #include "crypto/CryptoNight_constants.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" @@ -43,20 +44,16 @@ static char affinity_tmp[20] = { 0 }; xmrig::Config::Config() : xmrig::CommonConfig(), m_aesMode(AES_AUTO), m_algoVariant(AV_AUTO), - m_dryRun(false), + m_assembly(ASM_AUTO), m_hugePages(true), m_safe(false), + m_shouldSave(false), m_maxCpuUsage(75), m_priority(-1) { } -xmrig::Config::~Config() -{ -} - - bool xmrig::Config::reload(const char *json) { return xmrig::ConfigLoader::reload(this, json); @@ -76,11 +73,17 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const Value api(kObjectType); api.AddMember("port", apiPort(), allocator); api.AddMember("access-token", apiToken() ? Value(StringRef(apiToken())).Move() : Value(kNullType).Move(), allocator); + api.AddMember("id", apiId() ? Value(StringRef(apiId())).Move() : Value(kNullType).Move(), allocator); api.AddMember("worker-id", apiWorkerId() ? Value(StringRef(apiWorkerId())).Move() : Value(kNullType).Move(), allocator); api.AddMember("ipv6", isApiIPv6(), allocator); api.AddMember("restricted", isApiRestricted(), allocator); doc.AddMember("api", api, allocator); +# ifndef XMRIG_NO_ASM + doc.AddMember("asm", Asm::toJSON(m_assembly), allocator); +# endif + + doc.AddMember("autosave", isAutoSave(), allocator); doc.AddMember("av", algoVariant(), allocator); doc.AddMember("background", isBackground(), allocator); doc.AddMember("colors", isColors(), allocator); @@ -112,17 +115,17 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("retry-pause", retryPause(), allocator); doc.AddMember("safe", m_safe, allocator); - if (threadsMode() == Advanced) { + if (threadsMode() != Simple) { Value threads(kArrayType); for (const IThread *thread : m_threads.list) { - threads.PushBack(thread->toConfig(doc), doc.GetAllocator()); + threads.PushBack(thread->toConfig(doc), allocator); } doc.AddMember("threads", threads, allocator); } else { - doc.AddMember("threads", threadsMode() == Automatic ? Value(kNullType) : Value(threadsCount()), allocator); + doc.AddMember("threads", threadsCount(), allocator); } doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); @@ -153,7 +156,7 @@ bool xmrig::Config::finalize() if (!m_threads.cpu.empty()) { m_threads.mode = Advanced; - const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; + const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; for (size_t i = 0; i < m_threads.cpu.size(); ++i) { m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES)); @@ -162,25 +165,26 @@ bool xmrig::Config::finalize() return true; } - m_algoVariant = getAlgoVariant(); + const AlgoVariant av = getAlgoVariant(); m_threads.mode = m_threads.count ? Simple : Automatic; - const size_t size = CpuThread::multiway(m_algoVariant) * cn_select_memory(m_algorithm.algo()) / 1024; + const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024; if (!m_threads.count) { - m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); + m_threads.count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); } else if (m_safe) { - const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); + const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); if (m_threads.count > count) { m_threads.count = count; } } for (size_t i = 0; i < m_threads.count; ++i) { - m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), m_algoVariant, m_threads.mask, m_priority)); + m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority, m_assembly)); } + m_shouldSave = m_threads.mode == Automatic; return true; } @@ -192,22 +196,24 @@ bool xmrig::Config::parseBoolean(int key, bool enable) } switch (key) { - case IConfig::SafeKey: /* --safe */ + case SafeKey: /* --safe */ m_safe = enable; break; - case IConfig::HugePagesKey: /* --no-huge-pages */ + case HugePagesKey: /* --no-huge-pages */ m_hugePages = enable; break; - case IConfig::DryRunKey: /* --dry-run */ - m_dryRun = enable; - break; - - case IConfig::HardwareAESKey: /* hw-aes config only */ + case HardwareAESKey: /* hw-aes config only */ m_aesMode = enable ? AES_HW : AES_SOFT; break; +# ifndef XMRIG_NO_ASM + case AssemblyKey: + m_assembly = Asm::parse(enable); + break; +# endif + default: break; } @@ -223,32 +229,37 @@ bool xmrig::Config::parseString(int key, const char *arg) } switch (key) { - case xmrig::IConfig::AVKey: /* --av */ - case xmrig::IConfig::MaxCPUUsageKey: /* --max-cpu-usage */ - case xmrig::IConfig::CPUPriorityKey: /* --cpu-priority */ + case AVKey: /* --av */ + case MaxCPUUsageKey: /* --max-cpu-usage */ + case CPUPriorityKey: /* --cpu-priority */ return parseUint64(key, strtol(arg, nullptr, 10)); - case xmrig::IConfig::SafeKey: /* --safe */ - case xmrig::IConfig::DryRunKey: /* --dry-run */ + case SafeKey: /* --safe */ return parseBoolean(key, true); - case xmrig::IConfig::HugePagesKey: /* --no-huge-pages */ + case HugePagesKey: /* --no-huge-pages */ return parseBoolean(key, false); - case xmrig::IConfig::ThreadsKey: /* --threads */ + case ThreadsKey: /* --threads */ if (strncmp(arg, "all", 3) == 0) { - m_threads.count = Cpu::threads(); + m_threads.count = Cpu::info()->threads(); return true; } return parseUint64(key, strtol(arg, nullptr, 10)); - case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */ + case CPUAffinityKey: /* --cpu-affinity */ { const char *p = strstr(arg, "0x"); return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); } +# ifndef XMRIG_NO_ASM + case AssemblyKey: /* --asm */ + m_assembly = Asm::parse(arg); + break; +# endif + default: break; } @@ -264,7 +275,7 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg) } switch (key) { - case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */ + case CPUAffinityKey: /* --cpu-affinity */ if (arg) { m_threads.mask = arg; } @@ -303,25 +314,25 @@ void xmrig::Config::parseJSON(const rapidjson::Document &doc) bool xmrig::Config::parseInt(int key, int arg) { switch (key) { - case xmrig::IConfig::ThreadsKey: /* --threads */ + case ThreadsKey: /* --threads */ if (arg >= 0 && arg < 1024) { m_threads.count = arg; } break; - case xmrig::IConfig::AVKey: /* --av */ + case AVKey: /* --av */ if (arg >= AV_AUTO && arg < AV_MAX) { m_algoVariant = static_cast(arg); } break; - case xmrig::IConfig::MaxCPUUsageKey: /* --max-cpu-usage */ + case MaxCPUUsageKey: /* --max-cpu-usage */ if (m_maxCpuUsage > 0 && arg <= 100) { m_maxCpuUsage = arg; } break; - case xmrig::IConfig::CPUPriorityKey: /* --cpu-priority */ + case CPUPriorityKey: /* --cpu-priority */ if (arg >= 0 && arg <= 5) { m_priority = arg; } @@ -344,10 +355,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const # endif if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { - return Cpu::hasAES() ? AV_SINGLE : AV_SINGLE_SOFT; + return Cpu::info()->hasAES() ? AV_SINGLE : AV_SINGLE_SOFT; } - if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) { + if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { return static_cast(m_algoVariant + 2); } @@ -359,10 +370,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const { if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { - return Cpu::hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT; + return Cpu::info()->hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT; } - if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) { + if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { return static_cast(m_algoVariant + 2); } diff --git a/src/core/Config.h b/src/core/Config.h index 0c6a2173..eb33ee14 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -21,8 +21,8 @@ * along with this program. If not, see . */ -#ifndef __CONFIG_H__ -#define __CONFIG_H__ +#ifndef XMRIG_CONFIG_H +#define XMRIG_CONFIG_H #include @@ -69,7 +69,6 @@ public: Config(); - ~Config(); bool reload(const char *json); @@ -77,8 +76,9 @@ public: inline AesMode aesMode() const { return m_aesMode; } inline AlgoVariant algoVariant() const { return m_algoVariant; } - inline bool isDryRun() const { return m_dryRun; } + inline Assembly assembly() const { return m_assembly; } inline bool isHugePages() const { return m_hugePages; } + inline bool isShouldSave() const { return m_shouldSave && isAutoSave(); } inline const std::vector &threads() const { return m_threads.list; } inline int priority() const { return m_priority; } inline int threadsCount() const { return m_threads.list.size(); } @@ -117,9 +117,10 @@ private: AesMode m_aesMode; AlgoVariant m_algoVariant; - bool m_dryRun; + Assembly m_assembly; bool m_hugePages; bool m_safe; + bool m_shouldSave; int m_maxCpuUsage; int m_priority; Threads m_threads; @@ -128,4 +129,4 @@ private: } /* namespace xmrig */ -#endif /* __CONFIG_H__ */ +#endif /* XMRIG_CONFIG_H */ diff --git a/src/core/ConfigCreator.h b/src/core/ConfigCreator.h index fcc6c596..054eb78c 100644 --- a/src/core/ConfigCreator.h +++ b/src/core/ConfigCreator.h @@ -24,8 +24,8 @@ #define __CONFIGCREATOR_H__ +#include "common/interfaces/IConfigCreator.h" #include "core/Config.h" -#include "interfaces/IConfigCreator.h" namespace xmrig { diff --git a/src/core/ConfigLoader_platform.h b/src/core/ConfigLoader_platform.h index 9704d5e3..54546211 100644 --- a/src/core/ConfigLoader_platform.h +++ b/src/core/ConfigLoader_platform.h @@ -22,8 +22,8 @@ * along with this program. If not, see . */ -#ifndef __CONFIGLOADER_PLATFORM_H__ -#define __CONFIGLOADER_PLATFORM_H__ +#ifndef XMRIG_CONFIGLOADER_PLATFORM_H +#define XMRIG_CONFIGLOADER_PLATFORM_H #ifdef _MSC_VER @@ -33,8 +33,8 @@ #endif +#include "common/interfaces/IConfig.h" #include "version.h" -#include "interfaces/IConfig.h" namespace xmrig { @@ -61,7 +61,10 @@ Options:\n\ --rig-id=ID rig identifier for pool-side statistics (needs pool support)\n\ -t, --threads=N number of miner threads\n\ -v, --av=N algorithm variation, 0 auto select\n\ - -k, --keepalive send keepalived for prevent timeout (need pool support)\n\ + -k, --keepalive send keepalived packet for prevent timeout (needs pool support)\n\ + --nicehash enable nicehash.com support\n\ + --tls enable SSL/TLS support (needs pool support)\n\ + --tls-fingerprint=F pool TLS certificate fingerprint, if set enable strict certificate pinning\n\ -r, --retries=N number of times to retry before switch to backup server (default: 5)\n\ -R, --retry-pause=N time to pause between retries (default: 5)\n\ --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\ @@ -81,13 +84,15 @@ Options:\n\ "\ --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\ --safe safe adjust threads and av settings for current CPU\n\ - --nicehash enable nicehash/xmrig-proxy support\n\ + --asm=ASM ASM code for cn/2, possible values: auto, none, intel, ryzen.\n\ --print-time=N print hashrate report every N seconds\n\ --api-port=N port for the miner API\n\ --api-access-token=T access token for API\n\ --api-worker-id=ID custom worker-id for API\n\ + --api-id=ID custom instance ID for API\n\ --api-ipv6 enable IPv6 support for API\n\ --api-no-restricted enable full remote access (only if API token set)\n\ + --dry-run test configuration and exit\n\ -h, --help display this help and exit\n\ -V, --version output version information and exit\n\ "; @@ -101,6 +106,7 @@ static struct option const options[] = { { "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey }, { "api-port", 1, nullptr, xmrig::IConfig::ApiPort }, { "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, + { "api-id", 1, nullptr, xmrig::IConfig::ApiIdKey }, { "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, { "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, { "av", 1, nullptr, xmrig::IConfig::AVKey }, @@ -130,8 +136,11 @@ static struct option const options[] = { { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, + { "tls", 0, nullptr, xmrig::IConfig::TlsKey }, + { "tls-fingerprint", 1, nullptr, xmrig::IConfig::FingerprintKey }, { "version", 0, nullptr, xmrig::IConfig::VersionKey }, - { 0, 0, 0, 0 } + { "asm", 1, nullptr, xmrig::IConfig::AssemblyKey }, + { nullptr, 0, nullptr, 0 } }; @@ -155,20 +164,24 @@ static struct option const config_options[] = { { "threads", 1, nullptr, xmrig::IConfig::ThreadsKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey }, - { 0, 0, 0, 0 } + { "asm", 1, nullptr, xmrig::IConfig::AssemblyKey }, + { "autosave", 0, nullptr, xmrig::IConfig::AutoSaveKey }, + { nullptr, 0, nullptr, 0 } }; static struct option const pool_options[] = { - { "url", 1, nullptr, xmrig::IConfig::UrlKey }, - { "pass", 1, nullptr, xmrig::IConfig::PasswordKey }, - { "user", 1, nullptr, xmrig::IConfig::UserKey }, - { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, - { "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey }, - { "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey }, - { "variant", 1, nullptr, xmrig::IConfig::VariantKey }, - { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, - { 0, 0, 0, 0 } + { "url", 1, nullptr, xmrig::IConfig::UrlKey }, + { "pass", 1, nullptr, xmrig::IConfig::PasswordKey }, + { "user", 1, nullptr, xmrig::IConfig::UserKey }, + { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, + { "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey }, + { "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey }, + { "variant", 1, nullptr, xmrig::IConfig::VariantKey }, + { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, + { "tls", 0, nullptr, xmrig::IConfig::TlsKey }, + { "tls-fingerprint", 1, nullptr, xmrig::IConfig::FingerprintKey }, + { nullptr, 0, nullptr, 0 } }; @@ -178,10 +191,11 @@ static struct option const api_options[] = { { "worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, { "ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, { "restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, - { 0, 0, 0, 0 } + { "id", 1, nullptr, xmrig::IConfig::ApiIdKey }, + { nullptr, 0, nullptr, 0 } }; } /* namespace xmrig */ -#endif /* __CONFIGLOADER_PLATFORM_H__ */ +#endif /* XMRIG_CONFIGLOADER_PLATFORM_H */ diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index b1e03f32..792ac939 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -26,14 +26,14 @@ #include "common/config/ConfigLoader.h" +#include "common/cpu/Cpu.h" +#include "common/interfaces/IControllerListener.h" #include "common/log/ConsoleLog.h" #include "common/log/FileLog.h" #include "common/log/Log.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" -#include "Cpu.h" -#include "interfaces/IControllerListener.h" #include "net/Network.h" @@ -110,7 +110,7 @@ int xmrig::Controller::init(int argc, char **argv) } if (config()->logFile()) { - Log::add(new FileLog(config()->logFile())); + Log::add(new FileLog(this, config()->logFile())); } # ifdef HAVE_SYSLOG_H diff --git a/src/core/Controller.h b/src/core/Controller.h index 25f91843..2c66af53 100644 --- a/src/core/Controller.h +++ b/src/core/Controller.h @@ -25,7 +25,7 @@ #define __CONTROLLER_H__ -#include "interfaces/IWatcherListener.h" +#include "common/interfaces/IWatcherListener.h" class Network; diff --git a/src/Cpu.cpp b/src/core/cpu/AdvancedCpuInfo.cpp similarity index 57% rename from src/Cpu.cpp rename to src/core/cpu/AdvancedCpuInfo.cpp index eebe585d..c1a9f8cd 100644 --- a/src/Cpu.cpp +++ b/src/core/cpu/AdvancedCpuInfo.cpp @@ -21,65 +21,25 @@ * along with this program. If not, see . */ - #include #include #include +#include -#include "Cpu.h" +#include "core/cpu/AdvancedCpuInfo.h" -bool Cpu::m_l2_exclusive = false; -char Cpu::m_brand[64] = { 0 }; -int Cpu::m_flags = 0; -int Cpu::m_l2_cache = 0; -int Cpu::m_l3_cache = 0; -int Cpu::m_sockets = 1; -int Cpu::m_totalCores = 0; -size_t Cpu::m_totalThreads = 0; - - -size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage) -{ - if (m_totalThreads == 1) { - return 1; - } - - size_t cache = 0; - if (m_l3_cache) { - cache = m_l2_exclusive ? (m_l2_cache + m_l3_cache) : m_l3_cache; - } - else { - cache = m_l2_cache; - } - - size_t count = 0; - - if (cache) { - count = cache / size; - - if (cache % size >= size / 2) { - count++; - } - } - else { - count = m_totalThreads / 2; - } - - if (count > m_totalThreads) { - count = m_totalThreads; - } - - if (((float) count / m_totalThreads * 100) > maxCpuUsage) { - count = (int) ceil((float) m_totalThreads * (maxCpuUsage / 100.0)); - } - - return count < 1 ? 1 : count; -} - - -void Cpu::initCommon() +xmrig::AdvancedCpuInfo::AdvancedCpuInfo() : + m_assembly(ASM_NONE), + m_aes(false), + m_L2_exclusive(false), + m_brand(), + m_cores(0), + m_L2(0), + m_L3(0), + m_sockets(1), + m_threads(std::thread::hardware_concurrency()) { struct cpu_raw_data_t raw = { 0 }; struct cpu_id_t data = { 0 }; @@ -87,42 +47,78 @@ void Cpu::initCommon() cpuid_get_raw_data(&raw); cpu_identify(&raw, &data); - strncpy(m_brand, data.brand_str, sizeof(m_brand) - 1); - - m_totalThreads = data.total_logical_cpus; - m_sockets = m_totalThreads / data.num_logical_cpus; + strncpy(m_brand, data.brand_str, sizeof(m_brand)); + m_sockets = threads() / data.num_logical_cpus; if (m_sockets == 0) { m_sockets = 1; } - m_totalCores = data.num_cores * m_sockets; - m_l3_cache = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0; + m_cores = data.num_cores * m_sockets; + m_L3 = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0; // Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97 if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) { - m_l2_cache = data.l2_cache * (m_totalCores / 2) * m_sockets; - m_l2_exclusive = true; + m_L2 = data.l2_cache * (cores() / 2) * m_sockets; + m_L2_exclusive = true; } // Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue // These processors have L2 cache shared by 2 cores. else if (data.vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17)) { - int l2_count_per_socket = m_totalCores > 1 ? m_totalCores / 2 : 1; - m_l2_cache = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0; + int l2_count_per_socket = cores() > 1 ? cores() / 2 : 1; + m_L2 = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0; } else{ - m_l2_cache = data.l2_cache > 0 ? data.l2_cache * m_totalCores * m_sockets : 0; + m_L2 = data.l2_cache > 0 ? data.l2_cache * cores() * m_sockets : 0; } -# if defined(__x86_64__) || defined(_M_AMD64) - m_flags |= X86_64; -# endif - if (data.flags[CPU_FEATURE_AES]) { - m_flags |= AES; - } + m_aes = true; - if (data.flags[CPU_FEATURE_BMI2]) { - m_flags |= BMI2; + if (data.vendor == VENDOR_AMD) { + m_assembly = ASM_RYZEN; + } + else if (data.vendor == VENDOR_INTEL) { + m_assembly = ASM_INTEL; + } } } + + +size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const +{ + if (threads() == 1) { + return 1; + } + + size_t cache = 0; + if (m_L3) { + cache = m_L2_exclusive ? (m_L2 + m_L3) : m_L3; + } + else { + cache = m_L2; + } + + size_t count = 0; + + if (cache) { + count = cache / memSize; + + if (cache % memSize >= memSize / 2) { + count++; + } + } + else { + count = threads() / 2; + } + + if (count > (size_t) threads()) { + count = threads(); + } + + if (((float) count / threads() * 100) > maxCpuUsage) { + count = (int) ceil((float) threads() * (maxCpuUsage / 100.0)); + } + + return count < 1 ? 1 : count; +} diff --git a/src/core/cpu/AdvancedCpuInfo.h b/src/core/cpu/AdvancedCpuInfo.h new file mode 100644 index 00000000..5e8967ad --- /dev/null +++ b/src/core/cpu/AdvancedCpuInfo.h @@ -0,0 +1,75 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_ADVANCEDCPUINFO_H +#define XMRIG_ADVANCEDCPUINFO_H + + +#include "common/interfaces/ICpuInfo.h" + + +namespace xmrig { + + +class AdvancedCpuInfo : public ICpuInfo +{ +public: + AdvancedCpuInfo(); + +protected: + size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override; + + inline Assembly assembly() const override { return m_assembly; } + inline bool hasAES() const override { return m_aes; } + inline bool isSupported() const override { return true; } + inline const char *brand() const override { return m_brand; } + inline int32_t cores() const override { return m_cores; } + inline int32_t L2() const override { return m_L2; } + inline int32_t L3() const override { return m_L3; } + inline int32_t nodes() const override { return -1; } + inline int32_t sockets() const override { return m_sockets; } + inline int32_t threads() const override { return m_threads; } + +# if defined(__x86_64__) || defined(_M_AMD64) + inline bool isX64() const override { return true; } +# else + inline bool isX64() const override { return false; } +# endif + +private: + Assembly m_assembly; + bool m_aes; + bool m_L2_exclusive; + char m_brand[64]; + int32_t m_cores; + int32_t m_L2; + int32_t m_L3; + int32_t m_sockets; + int32_t m_threads; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_ADVANCEDCPUINFO_H */ diff --git a/src/Cpu_win.cpp b/src/core/cpu/Cpu.cpp similarity index 69% rename from src/Cpu_win.cpp rename to src/core/cpu/Cpu.cpp index 7258f726..773255d2 100644 --- a/src/Cpu_win.cpp +++ b/src/core/cpu/Cpu.cpp @@ -22,20 +22,40 @@ */ -#include +#include -#include "Cpu.h" +#include "common/cpu/Cpu.h" -void Cpu::init() +#ifndef XMRIG_NO_LIBCPUID +# include "core/cpu/AdvancedCpuInfo.h" +#endif + + +static xmrig::ICpuInfo *cpuInfo = nullptr; + + +xmrig::ICpuInfo *xmrig::Cpu::info() { -# ifdef XMRIG_NO_LIBCPUID - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); + assert(cpuInfo != nullptr); - m_totalThreads = sysinfo.dwNumberOfProcessors; -# endif - - initCommon(); + return cpuInfo; +} + + +void xmrig::Cpu::init() +{ + assert(cpuInfo == nullptr); + + cpuInfo = new AdvancedCpuInfo(); +} + + +void xmrig::Cpu::release() +{ + assert(cpuInfo != nullptr); + + delete cpuInfo; + cpuInfo = nullptr; } diff --git a/src/crypto/Asm.cpp b/src/crypto/Asm.cpp new file mode 100644 index 00000000..48c1beb8 --- /dev/null +++ b/src/crypto/Asm.cpp @@ -0,0 +1,100 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include + + +#ifdef _MSC_VER +# define strncasecmp _strnicmp +# define strcasecmp _stricmp +#endif + + +#include "crypto/Asm.h" +#include "rapidjson/document.h" + + +static const char *asmNames[] = { + "none", + "auto", + "intel", + "ryzen" +}; + + +xmrig::Assembly xmrig::Asm::parse(const char *assembly, Assembly defaultValue) +{ + constexpr size_t const size = sizeof(asmNames) / sizeof((asmNames)[0]); + assert(assembly != nullptr); + assert(ASM_MAX == size); + + if (assembly == nullptr) { + return defaultValue; + } + + for (size_t i = 0; i < size; i++) { + if (strcasecmp(assembly, asmNames[i]) == 0) { + return static_cast(i); + } + } + + return defaultValue; +} + + +xmrig::Assembly xmrig::Asm::parse(const rapidjson::Value &value, Assembly defaultValue) +{ + if (value.IsBool()) { + return parse(value.GetBool()); + } + + if (value.IsString()) { + return parse(value.GetString(), defaultValue); + } + + return defaultValue; +} + + +const char *xmrig::Asm::toString(Assembly assembly) +{ + return asmNames[assembly]; +} + + +rapidjson::Value xmrig::Asm::toJSON(Assembly assembly) +{ + using namespace rapidjson; + + if (assembly == ASM_NONE) { + return Value(false); + } + + if (assembly == ASM_AUTO) { + return Value(true); + } + + return Value(StringRef(toString(assembly))); +} diff --git a/src/crypto/Asm.h b/src/crypto/Asm.h new file mode 100644 index 00000000..3b755fd6 --- /dev/null +++ b/src/crypto/Asm.h @@ -0,0 +1,50 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_ASM_H +#define XMRIG_ASM_H + + +#include "common/xmrig.h" +#include "rapidjson/fwd.h" + + +namespace xmrig { + + +class Asm +{ +public: + static Assembly parse(const char *assembly, Assembly defaultValue = ASM_AUTO); + static Assembly parse(const rapidjson::Value &value, Assembly defaultValue = ASM_AUTO); + static const char *toString(Assembly assembly); + static rapidjson::Value toJSON(Assembly assembly); + + inline static Assembly parse(bool enable) { return enable ? ASM_AUTO : ASM_NONE; } +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_ASM_H */ diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index e8e86dc4..680f1740 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -22,8 +22,8 @@ * along with this program. If not, see . */ -#ifndef __CRYPTONIGHT_H__ -#define __CRYPTONIGHT_H__ +#ifndef XMRIG_CRYPTONIGHT_H +#define XMRIG_CRYPTONIGHT_H #include @@ -31,9 +31,9 @@ struct cryptonight_ctx { - alignas(16) uint8_t state[200]; - alignas(16) uint8_t* memory; + alignas(16) uint8_t state[224]; + alignas(16) uint8_t *memory; }; -#endif /* __CRYPTONIGHT_H__ */ +#endif /* XMRIG_CRYPTONIGHT_H */ diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index 746de79c..4fcebc3e 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -7,6 +7,7 @@ * Copyright 2016 Imran Yusuff * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -23,10 +24,11 @@ * along with this program. If not, see . */ -#ifndef __CRYPTONIGHT_ARM_H__ -#define __CRYPTONIGHT_ARM_H__ +#ifndef XMRIG_CRYPTONIGHT_ARM_H +#define XMRIG_CRYPTONIGHT_ARM_H +#include "common/crypto/keccak.h" #include "common/utils/mm_malloc.h" #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_constants.h" @@ -36,7 +38,6 @@ extern "C" { -#include "crypto/c_keccak.h" #include "crypto/c_groestl.h" #include "crypto/c_blake256.h" #include "crypto/c_jh.h" @@ -73,7 +74,7 @@ static inline __attribute__((always_inline)) __m128i _mm_set_epi64x(const uint64 } -#ifdef XMRIG_ARMv8 +#if __ARM_FEATURE_CRYPTO static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) { alignas(16) const __m128i zero = { 0 }; @@ -82,6 +83,8 @@ static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, #else static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) { + alignas(16) const __m128i zero = { 0 }; + return zero; } #endif @@ -93,10 +96,7 @@ static inline __attribute__((always_inline)) uint64_t _mm_cvtsi128_si64(__m128i } -#define EXTRACT64(X) _mm_cvtsi128_si64(X) - - -#if defined(XMRIG_ARMv8) +#if defined (__arm64__) || defined (__aarch64__) static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi) { unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b; @@ -380,125 +380,190 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } -static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) +static inline __m128i aes_round_tweak_div(const __m128i &in, const __m128i &key) { - mem_out[0] = EXTRACT64(tmp); + alignas(16) uint32_t k[4]; + alignas(16) uint32_t x[4]; - uint64_t vh = vgetq_lane_u64(tmp, 1); + _mm_store_si128((__m128i*) k, key); + _mm_store_si128((__m128i*) x, _mm_xor_si128(in, _mm_set_epi64x(0xffffffffffffffff, 0xffffffffffffffff))); - uint8_t x = vh >> 24; - static const uint16_t table = 0x7531; - const uint8_t index = (((x >> 3) & 6) | (x & 1)) << 1; - vh ^= ((table >> index) & 0x3) << 28; + #define BYTE(p, i) ((unsigned char*)&x[p])[i] + k[0] ^= saes_table[0][BYTE(0, 0)] ^ saes_table[1][BYTE(1, 1)] ^ saes_table[2][BYTE(2, 2)] ^ saes_table[3][BYTE(3, 3)]; + x[0] ^= k[0]; + k[1] ^= saes_table[0][BYTE(1, 0)] ^ saes_table[1][BYTE(2, 1)] ^ saes_table[2][BYTE(3, 2)] ^ saes_table[3][BYTE(0, 3)]; + x[1] ^= k[1]; + k[2] ^= saes_table[0][BYTE(2, 0)] ^ saes_table[1][BYTE(3, 1)] ^ saes_table[2][BYTE(0, 2)] ^ saes_table[3][BYTE(1, 3)]; + x[2] ^= k[2]; + k[3] ^= saes_table[0][BYTE(3, 0)] ^ saes_table[1][BYTE(0, 1)] ^ saes_table[2][BYTE(1, 2)] ^ saes_table[3][BYTE(2, 3)]; + #undef BYTE - mem_out[1] = vh; + return _mm_load_si128((__m128i*)k); } -template +template +static inline void cryptonight_monero_tweak(const uint8_t* l, uint64_t idx, __m128i ax0, __m128i bx0, __m128i bx1, __m128i cx) +{ + uint64_t* mem_out = (uint64_t*)&l[idx]; + + if (VARIANT == xmrig::VARIANT_2) { + VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1); + _mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx)); + } else { + __m128i tmp = _mm_xor_si128(bx0, cx); + mem_out[0] = _mm_cvtsi128_si64(tmp); + + uint64_t vh = vgetq_lane_u64(tmp, 1); + + uint8_t x = vh >> 24; + static const uint16_t table = 0x7531; + const uint8_t index = (((x >> (VARIANT == xmrig::VARIANT_XTL ? 4 : 3)) & 6) | (x & 1)) << 1; + vh ^= ((table >> index) & 0x3) << 28; + + mem_out[1] = vh; + } +} + + +template inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr bool IS_V1 = xmrig::cn_base_variant() == xmrig::VARIANT_1; - if (VARIANT > 0 && size < 43) { + if (IS_V1 && size < 43) { memset(output, 0, 32); return; } - keccak(input, (int) size, ctx[0]->state, 200); - - VARIANT1_INIT(0); + xmrig::keccak(input, size, ctx[0]->state); cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); const uint8_t* l0 = ctx[0]->memory; uint64_t* h0 = reinterpret_cast(ctx[0]->state); + VARIANT1_INIT(0); + VARIANT2_INIT(0); + uint64_t al0 = h0[0] ^ h0[4]; uint64_t ah0 = h0[1] ^ h0[5]; __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i bx1 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); - uint64_t idx0 = h0[0] ^ h0[4]; + uint64_t idx0 = al0; for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx; + if (VARIANT == xmrig::VARIANT_TUBE || !SOFT_AES) { + cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); + } - if (SOFT_AES) { - cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0)); + const __m128i ax0 = _mm_set_epi64x(ah0, al0); + if (VARIANT == xmrig::VARIANT_TUBE) { + cx = aes_round_tweak_div(cx, ax0); + } + else if (SOFT_AES) { + cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0); } else { - cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); - cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); + cx = _mm_aesenc_si128(cx, ax0); } - if (VARIANT > 0) { - cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); + if (IS_V1 || VARIANT == xmrig::VARIANT_2) { + cryptonight_monero_tweak(l0, idx0 & MASK, ax0, bx0, bx1, cx); } else { _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); } - idx0 = EXTRACT64(cx); - bx0 = cx; + idx0 = _mm_cvtsi128_si64(cx); uint64_t hi, lo, cl, ch; cl = ((uint64_t*) &l0[idx0 & MASK])[0]; ch = ((uint64_t*) &l0[idx0 & MASK])[1]; - lo = __umul128(idx0, cl, &hi); + if (VARIANT == xmrig::VARIANT_2) { + VARIANT2_INTEGER_MATH(0, cl, cx); + lo = __umul128(idx0, cl, &hi); + VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo); + } + else { + lo = __umul128(idx0, cl, &hi); + } al0 += hi; ah0 += lo; - VARIANT1_2(ah0, 0); ((uint64_t*)&l0[idx0 & MASK])[0] = al0; - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; - VARIANT1_2(ah0, 0); - ah0 ^= ch; + if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; + } else if (IS_V1) { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; + } else { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; + } + al0 ^= cl; + ah0 ^= ch; idx0 = al0; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { - int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; - int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; - int64_t q = n / (d | 0x5); + const int64x2_t x = vld1q_s64(reinterpret_cast(&l0[idx0 & MASK])); + const int64_t n = vgetq_lane_s64(x, 0); + const int32_t d = vgetq_lane_s32(x, 2); + const int64_t q = n / (d | 0x5); ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; - idx0 = d ^ q; + + if (VARIANT == xmrig::VARIANT_XHV) { + idx0 = (~d) ^ q; + } + else { + idx0 = d ^ q; + } } + if (VARIANT == xmrig::VARIANT_2) { + bx1 = bx0; + } + bx0 = cx; } cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); - keccakf(h0, 24); + xmrig::keccakf(h0, 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); } -template +template inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr bool IS_V1 = xmrig::cn_base_variant() == xmrig::VARIANT_1; - if (VARIANT > 0 && size < 43) { + if (IS_V1 && size < 43) { memset(output, 0, 64); return; } - keccak(input, (int) size, ctx[0]->state, 200); - keccak(input + size, (int) size, ctx[1]->state, 200); - - VARIANT1_INIT(0); - VARIANT1_INIT(1); + xmrig::keccak(input, size, ctx[0]->state); + xmrig::keccak(input + size, size, ctx[1]->state); const uint8_t* l0 = ctx[0]->memory; const uint8_t* l1 = ctx[1]->memory; uint64_t* h0 = reinterpret_cast(ctx[0]->state); uint64_t* h1 = reinterpret_cast(ctx[1]->state); + VARIANT1_INIT(0); + VARIANT1_INIT(1); + VARIANT2_INIT(0); + VARIANT2_INIT(1); + cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); @@ -507,116 +572,165 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si uint64_t ah0 = h0[1] ^ h0[5]; uint64_t ah1 = h1[1] ^ h1[5]; - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i bx00 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i bx01 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); + __m128i bx10 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i bx11 = _mm_set_epi64x(h1[9] ^ h1[11], h1[8] ^ h1[10]); - uint64_t idx0 = h0[0] ^ h0[4]; - uint64_t idx1 = h1[0] ^ h1[4]; + uint64_t idx0 = al0; + uint64_t idx1 = al1; for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx0, cx1; - - if (SOFT_AES) { - cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0)); - cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1)); - } - else { + if (VARIANT == xmrig::VARIANT_TUBE || !SOFT_AES) { cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); - cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); - cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); } - if (VARIANT > 0) { - cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); - cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + const __m128i ax0 = _mm_set_epi64x(ah0, al0); + const __m128i ax1 = _mm_set_epi64x(ah1, al1); + if (VARIANT == xmrig::VARIANT_TUBE) { + cx0 = aes_round_tweak_div(cx0, ax0); + cx1 = aes_round_tweak_div(cx1, ax1); + } + else if (SOFT_AES) { + cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0); + cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], ax1); + } + else { + cx0 = _mm_aesenc_si128(cx0, ax0); + cx1 = _mm_aesenc_si128(cx1, ax1); + } + + if (IS_V1 || (VARIANT == xmrig::VARIANT_2)) { + cryptonight_monero_tweak(l0, idx0 & MASK, ax0, bx00, bx01, cx0); + cryptonight_monero_tweak(l1, idx1 & MASK, ax1, bx10, bx11, cx1); } else { - _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); - _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); - }; + _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx00, cx0)); + _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx10, cx1)); + } - idx0 = EXTRACT64(cx0); - idx1 = EXTRACT64(cx1); - - bx0 = cx0; - bx1 = cx1; + idx0 = _mm_cvtsi128_si64(cx0); + idx1 = _mm_cvtsi128_si64(cx1); uint64_t hi, lo, cl, ch; cl = ((uint64_t*) &l0[idx0 & MASK])[0]; ch = ((uint64_t*) &l0[idx0 & MASK])[1]; - lo = __umul128(idx0, cl, &hi); + if (VARIANT == xmrig::VARIANT_2) { + VARIANT2_INTEGER_MATH(0, cl, cx0); + lo = __umul128(idx0, cl, &hi); + VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo); + } else { + lo = __umul128(idx0, cl, &hi); + } al0 += hi; ah0 += lo; - VARIANT1_2(ah0, 0); - ((uint64_t*) &l0[idx0 & MASK])[0] = al0; - ((uint64_t*) &l0[idx0 & MASK])[1] = ah0; - VARIANT1_2(ah0, 0); + ((uint64_t*)&l0[idx0 & MASK])[0] = al0; + + if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; + } else if (IS_V1) { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; + } else { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; + } - ah0 ^= ch; al0 ^= cl; + ah0 ^= ch; idx0 = al0; - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { - int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; - int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; - int64_t q = n / (d | 0x5); + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + const int64x2_t x = vld1q_s64(reinterpret_cast(&l0[idx0 & MASK])); + const int64_t n = vgetq_lane_s64(x, 0); + const int32_t d = vgetq_lane_s32(x, 2); + const int64_t q = n / (d | 0x5); ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; - idx0 = d ^ q; + + if (VARIANT == xmrig::VARIANT_XHV) { + idx0 = (~d) ^ q; + } + else { + idx0 = d ^ q; + } } cl = ((uint64_t*) &l1[idx1 & MASK])[0]; ch = ((uint64_t*) &l1[idx1 & MASK])[1]; - lo = __umul128(idx1, cl, &hi); + if (VARIANT == xmrig::VARIANT_2) { + VARIANT2_INTEGER_MATH(1, cl, cx1); + lo = __umul128(idx1, cl, &hi); + VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo); + } else { + lo = __umul128(idx1, cl, &hi); + } al1 += hi; ah1 += lo; - VARIANT1_2(ah1, 1); - ((uint64_t*) &l1[idx1 & MASK])[0] = al1; - ((uint64_t*) &l1[idx1 & MASK])[1] = ah1; - VARIANT1_2(ah1, 1); + ((uint64_t*)&l1[idx1 & MASK])[0] = al1; + + if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1; + } else if (IS_V1) { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1; + } else { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1; + } - ah1 ^= ch; al1 ^= cl; + ah1 ^= ch; idx1 = al1; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { - int64_t n = ((int64_t*)&l1[idx1 & MASK])[0]; - int32_t d = ((int32_t*)&l1[idx1 & MASK])[2]; - int64_t q = n / (d | 0x5); + const int64x2_t x = vld1q_s64(reinterpret_cast(&l1[idx1 & MASK])); + const int64_t n = vgetq_lane_s64(x, 0); + const int32_t d = vgetq_lane_s32(x, 2); + const int64_t q = n / (d | 0x5); ((int64_t*)&l1[idx1 & MASK])[0] = n ^ q; - idx1 = d ^ q; + + if (VARIANT == xmrig::VARIANT_XHV) { + idx1 = (~d) ^ q; + } + else { + idx1 = d ^ q; + } } + if (VARIANT == xmrig::VARIANT_2) { + bx01 = bx00; + bx11 = bx10; + } + bx00 = cx0; + bx10 = cx1; } cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); - keccakf(h0, 24); - keccakf(h1, 24); + xmrig::keccakf(h0, 24); + xmrig::keccakf(h1, 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); } -template +template inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { } -template +template inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { } -template +template inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { } diff --git a/src/crypto/CryptoNight_constants.h b/src/crypto/CryptoNight_constants.h index 7e6627fd..f13891a7 100644 --- a/src/crypto/CryptoNight_constants.h +++ b/src/crypto/CryptoNight_constants.h @@ -38,6 +38,8 @@ namespace xmrig constexpr const size_t CRYPTONIGHT_MEMORY = 2 * 1024 * 1024; constexpr const uint32_t CRYPTONIGHT_MASK = 0x1FFFF0; constexpr const uint32_t CRYPTONIGHT_ITER = 0x80000; +constexpr const uint32_t CRYPTONIGHT_MSR_ITER = 0x40000; +constexpr const uint32_t CRYPTONIGHT_XAO_ITER = 0x100000; constexpr const size_t CRYPTONIGHT_LITE_MEMORY = 1 * 1024 * 1024; constexpr const uint32_t CRYPTONIGHT_LITE_MASK = 0xFFFF0; @@ -102,14 +104,34 @@ inline uint32_t cn_select_mask(Algo algorithm) } -template inline constexpr uint32_t cn_select_iter() { return 0; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } +template inline constexpr uint32_t cn_select_iter() { return 0; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_MSR_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_XAO_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } -inline uint32_t cn_select_iter(Algo algorithm) +inline uint32_t cn_select_iter(Algo algorithm, Variant variant) { + switch (variant) { + case VARIANT_MSR: + return CRYPTONIGHT_MSR_ITER; + + case VARIANT_RTO: + return CRYPTONIGHT_XAO_ITER; + + default: + break; + } + switch(algorithm) { case CRYPTONIGHT: @@ -129,6 +151,18 @@ inline uint32_t cn_select_iter(Algo algorithm) } +template inline constexpr Variant cn_base_variant() { return VARIANT_0; } +template<> inline constexpr Variant cn_base_variant() { return VARIANT_0; } +template<> inline constexpr Variant cn_base_variant() { return VARIANT_1; } +template<> inline constexpr Variant cn_base_variant() { return VARIANT_1; } +template<> inline constexpr Variant cn_base_variant() { return VARIANT_1; } +template<> inline constexpr Variant cn_base_variant() { return VARIANT_1; } +template<> inline constexpr Variant cn_base_variant() { return VARIANT_0; } +template<> inline constexpr Variant cn_base_variant() { return VARIANT_0; } +template<> inline constexpr Variant cn_base_variant() { return VARIANT_1; } +template<> inline constexpr Variant cn_base_variant() { return VARIANT_2; } + + } /* namespace xmrig */ diff --git a/src/crypto/CryptoNight_monero.h b/src/crypto/CryptoNight_monero.h index ea1622ab..52229026 100644 --- a/src/crypto/CryptoNight_monero.h +++ b/src/crypto/CryptoNight_monero.h @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -22,30 +23,31 @@ * along with this program. If not, see . */ -#ifndef __CRYPTONIGHT_MONERO_H__ -#define __CRYPTONIGHT_MONERO_H__ +#ifndef XMRIG_CRYPTONIGHT_MONERO_H +#define XMRIG_CRYPTONIGHT_MONERO_H +#include +#include // VARIANT ALTERATIONS #ifndef XMRIG_ARM # define VARIANT1_INIT(part) \ uint64_t tweak1_2_##part = 0; \ - if (VARIANT > 0) { \ + if (IS_V1) { \ tweak1_2_##part = (*reinterpret_cast(input + 35 + part * size) ^ \ *(reinterpret_cast(ctx[part]->state) + 24)); \ } #else # define VARIANT1_INIT(part) \ uint64_t tweak1_2_##part = 0; \ - if (VARIANT > 0) { \ - volatile const uint64_t a = *reinterpret_cast(input + 35 + part * size); \ - volatile const uint64_t b = *(reinterpret_cast(ctx[part]->state) + 24); \ - tweak1_2_##part = a ^ b; \ + if (IS_V1) { \ + memcpy(&tweak1_2_##part, input + 35 + part * size, sizeof tweak1_2_##part); \ + tweak1_2_##part ^= *(reinterpret_cast(ctx[part]->state) + 24); \ } #endif #define VARIANT1_1(p) \ - if (VARIANT > 0) { \ + if (IS_V1) { \ const uint8_t tmp = reinterpret_cast(p)[11]; \ static const uint32_t table = 0x75310; \ const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ @@ -53,9 +55,96 @@ } #define VARIANT1_2(p, part) \ - if (VARIANT > 0) { \ + if (IS_V1) { \ (p) ^= tweak1_2_##part; \ } -#endif /* __CRYPTONIGHT_MONERO_H__ */ +#ifndef XMRIG_ARM +# define VARIANT2_INIT(part) \ + __m128i division_result_xmm_##part = _mm_cvtsi64_si128(h##part[12]); \ + __m128i sqrt_result_xmm_##part = _mm_cvtsi64_si128(h##part[13]); + +#ifdef _MSC_VER +# define VARIANT2_SET_ROUNDING_MODE() if (VARIANT == xmrig::VARIANT_2) { _control87(RC_DOWN, MCW_RC); } +#else +# define VARIANT2_SET_ROUNDING_MODE() if (VARIANT == xmrig::VARIANT_2) { fesetround(FE_DOWNWARD); } +#endif + +# define VARIANT2_INTEGER_MATH(part, cl, cx) \ + do { \ + const uint64_t sqrt_result = static_cast(_mm_cvtsi128_si64(sqrt_result_xmm_##part)); \ + const uint64_t cx_0 = _mm_cvtsi128_si64(cx); \ + cl ^= static_cast(_mm_cvtsi128_si64(division_result_xmm_##part)) ^ (sqrt_result << 32); \ + const uint32_t d = static_cast(cx_0 + (sqrt_result << 1)) | 0x80000001UL; \ + const uint64_t cx_1 = _mm_cvtsi128_si64(_mm_srli_si128(cx, 8)); \ + const uint64_t division_result = static_cast(cx_1 / d) + ((cx_1 % d) << 32); \ + division_result_xmm_##part = _mm_cvtsi64_si128(static_cast(division_result)); \ + sqrt_result_xmm_##part = int_sqrt_v2(cx_0 + division_result); \ + } while (0) + +# define VARIANT2_SHUFFLE(base_ptr, offset, _a, _b, _b1) \ + do { \ + const __m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))); \ + const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \ + const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \ + _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \ + _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \ + _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \ + } while (0) + +# define VARIANT2_SHUFFLE2(base_ptr, offset, _a, _b, _b1, hi, lo) \ + do { \ + const __m128i chunk1 = _mm_xor_si128(_mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))), _mm_set_epi64x(lo, hi)); \ + const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \ + hi ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[0]; \ + lo ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[1]; \ + const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \ + _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \ + _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \ + _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \ + } while (0) + +#else +# define VARIANT2_INIT(part) \ + uint64_t division_result_##part = h##part[12]; \ + uint64_t sqrt_result_##part = h##part[13]; + +# define VARIANT2_INTEGER_MATH(part, cl, cx) \ + do { \ + const uint64_t cx_0 = _mm_cvtsi128_si64(cx); \ + cl ^= division_result_##part ^ (sqrt_result_##part << 32); \ + const uint32_t d = static_cast(cx_0 + (sqrt_result_##part << 1)) | 0x80000001UL; \ + const uint64_t cx_1 = _mm_cvtsi128_si64(_mm_srli_si128(cx, 8)); \ + division_result_##part = static_cast(cx_1 / d) + ((cx_1 % d) << 32); \ + const uint64_t sqrt_input = cx_0 + division_result_##part; \ + sqrt_result_##part = sqrt(sqrt_input + 18446744073709551616.0) * 2.0 - 8589934592.0; \ + const uint64_t s = sqrt_result_##part >> 1; \ + const uint64_t b = sqrt_result_##part & 1; \ + const uint64_t r2 = (uint64_t)(s) * (s + b) + (sqrt_result_##part << 32); \ + sqrt_result_##part += ((r2 + b > sqrt_input) ? -1 : 0) + ((r2 + (1ULL << 32) < sqrt_input - s) ? 1 : 0); \ + } while (0) + +# define VARIANT2_SHUFFLE(base_ptr, offset, _a, _b, _b1) \ + do { \ + const uint64x2_t chunk1 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10))); \ + const uint64x2_t chunk2 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20))); \ + const uint64x2_t chunk3 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30))); \ + vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \ + vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \ + vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \ + } while (0) + +# define VARIANT2_SHUFFLE2(base_ptr, offset, _a, _b, _b1, hi, lo) \ + do { \ + const uint64x2_t chunk1 = veorq_u64(vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10))), vcombine_u64(vcreate_u64(hi), vcreate_u64(lo))); \ + const uint64x2_t chunk2 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20))); \ + hi ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[0]; \ + lo ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[1]; \ + const uint64x2_t chunk3 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30))); \ + vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \ + vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \ + vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \ + } while (0) +#endif +#endif /* XMRIG_CRYPTONIGHT_MONERO_H */ diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h index bf6013e8..95e12197 100644 --- a/src/crypto/CryptoNight_test.h +++ b/src/crypto/CryptoNight_test.h @@ -69,7 +69,7 @@ const static uint8_t test_output_v0[160] = { }; -// Monero v7 +// Cryptonight variant 1 (Monero v7) const static uint8_t test_output_v1[160] = { 0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9, 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9, @@ -84,6 +84,21 @@ const static uint8_t test_output_v1[160] = { }; +// Cryptonight variant 2 (Monero v8) +const static uint8_t test_output_v2[160] = { + 0x97, 0x37, 0x82, 0x82, 0xCF, 0x10, 0xE7, 0xAD, 0x03, 0x3F, 0x7B, 0x80, 0x74, 0xC4, 0x0E, 0x14, + 0xD0, 0x6E, 0x7F, 0x60, 0x9D, 0xDD, 0xDA, 0x78, 0x76, 0x80, 0xB5, 0x8C, 0x05, 0xF4, 0x3D, 0x21, + 0x87, 0x1F, 0xCD, 0x68, 0x23, 0xF6, 0xA8, 0x79, 0xBB, 0x3F, 0x33, 0x95, 0x1C, 0x8E, 0x8E, 0x89, + 0x1D, 0x40, 0x43, 0x88, 0x0B, 0x02, 0xDF, 0xA1, 0xBB, 0x3B, 0xE4, 0x98, 0xB5, 0x0E, 0x75, 0x78, + 0xE6, 0x0D, 0x24, 0x0F, 0x65, 0x85, 0x60, 0x3A, 0x4A, 0xE5, 0x5F, 0x54, 0x9B, 0xC8, 0x79, 0x93, + 0xEB, 0x3D, 0x98, 0x2C, 0xFE, 0x9B, 0xFB, 0x15, 0xB6, 0x88, 0x21, 0x94, 0xB0, 0x05, 0x86, 0x5C, + 0x59, 0x8B, 0x93, 0x7A, 0xDA, 0xD2, 0xA2, 0x14, 0xED, 0xB7, 0xC4, 0x5D, 0xA1, 0xEF, 0x26, 0xF3, + 0xC7, 0x73, 0x29, 0x4D, 0xF1, 0xC8, 0x2C, 0xE0, 0xD0, 0xE9, 0xED, 0x0C, 0x70, 0x75, 0x05, 0x3E, + 0x5B, 0xF6, 0xA0, 0x6E, 0xEA, 0xDE, 0x87, 0x0B, 0x06, 0x29, 0x03, 0xBF, 0xB4, 0x85, 0x9D, 0x04, + 0x75, 0x1A, 0xCD, 0x1E, 0xD6, 0xAA, 0x1B, 0x05, 0x24, 0x6A, 0x2C, 0x80, 0x69, 0x68, 0xDC, 0x97 +}; + + // Stellite (XTL) const static uint8_t test_output_xtl[160] = { 0x8F, 0xE5, 0xF0, 0x5F, 0x02, 0x2A, 0x61, 0x7D, 0xE5, 0x3F, 0x79, 0x36, 0x4B, 0x25, 0xCB, 0xC3, @@ -99,6 +114,51 @@ const static uint8_t test_output_xtl[160] = { }; +// Masari (MSR) +const static uint8_t test_output_msr[160] = { + 0x3C, 0x7A, 0x61, 0x08, 0x4C, 0x5E, 0xB8, 0x65, 0xB4, 0x98, 0xAB, 0x2F, 0x5A, 0x1A, 0xC5, 0x2C, + 0x49, 0xC1, 0x77, 0xC2, 0xD0, 0x13, 0x34, 0x42, 0xD6, 0x5E, 0xD5, 0x14, 0x33, 0x5C, 0x82, 0xC5, + 0x69, 0xDF, 0x38, 0x51, 0x1B, 0xB3, 0xEB, 0x7D, 0xE7, 0x6B, 0x08, 0x8E, 0xB6, 0x7E, 0xB7, 0x1C, + 0x5F, 0x3C, 0x81, 0xC9, 0xF7, 0xCE, 0xAE, 0x28, 0xC0, 0xFE, 0xEB, 0xBA, 0x0B, 0x40, 0x38, 0x1D, + 0x44, 0xD0, 0xD5, 0xD3, 0x98, 0x1F, 0xA3, 0x0E, 0xE9, 0x89, 0x1A, 0xD7, 0x88, 0xCC, 0x25, 0x76, + 0x9C, 0xFF, 0x4D, 0x7F, 0x9C, 0xCF, 0x48, 0x07, 0x91, 0xF9, 0x82, 0xF5, 0x4C, 0xE9, 0xBD, 0x82, + 0x36, 0x36, 0x64, 0x14, 0xED, 0xB8, 0x54, 0xEE, 0x22, 0xA1, 0x66, 0xA3, 0x87, 0x10, 0x76, 0x1F, + 0x5A, 0xCD, 0x4C, 0x31, 0x4C, 0xBA, 0x41, 0xD2, 0xDB, 0x6C, 0x31, 0x2E, 0x7A, 0x64, 0x15, 0xFF, + 0xA6, 0xD9, 0xB9, 0x7D, 0x1C, 0x3C, 0x98, 0xDD, 0x16, 0xE6, 0xD3, 0xAA, 0xEF, 0xB6, 0xB3, 0x53, + 0x74, 0xD1, 0xAC, 0x5C, 0x04, 0x26, 0x7D, 0x71, 0xDE, 0xAB, 0x66, 0x28, 0x91, 0x3A, 0x6F, 0x4F +}; + + +// Alloy (XAO) +const static uint8_t test_output_xao[160] = { + 0x9A, 0x29, 0xD0, 0xC4, 0xAF, 0xDC, 0x63, 0x9B, 0x65, 0x53, 0xB1, 0xC8, 0x37, 0x35, 0x11, 0x4C, + 0x5D, 0x77, 0x16, 0x21, 0x42, 0x97, 0x5C, 0xB8, 0x50, 0xC0, 0xA5, 0x1F, 0x64, 0x07, 0xBD, 0x33, + 0xF1, 0xC9, 0x98, 0x40, 0x42, 0xDE, 0x39, 0xD1, 0xBA, 0x2D, 0xAD, 0xEC, 0xFE, 0xEA, 0xD8, 0x46, + 0x56, 0x1C, 0x32, 0x90, 0x42, 0x63, 0x10, 0x80, 0xD7, 0x01, 0xE4, 0xE6, 0x20, 0xB3, 0x60, 0x45, + 0x05, 0xE5, 0xC2, 0x18, 0xCD, 0x07, 0xA4, 0x40, 0x42, 0x91, 0xE2, 0xA4, 0x52, 0x54, 0x79, 0xBA, + 0xCD, 0x7E, 0x61, 0x2D, 0x7F, 0x7E, 0x69, 0x5E, 0xD7, 0xC0, 0x06, 0x65, 0xD7, 0xA1, 0xB8, 0xB8, + 0x1E, 0x31, 0x1C, 0xD3, 0xB7, 0xBC, 0x78, 0x3C, 0x01, 0xAF, 0x77, 0xAA, 0xF3, 0x0F, 0x4C, 0xF2, + 0xD1, 0x8B, 0x58, 0xC7, 0xEB, 0x99, 0x91, 0x53, 0x43, 0x71, 0x47, 0x99, 0x9E, 0x04, 0xA4, 0xEA, + 0xB8, 0xA3, 0xB0, 0x9E, 0x09, 0xF5, 0x57, 0x5C, 0xCF, 0x8A, 0xC6, 0xCA, 0x88, 0x51, 0x9A, 0x01, + 0x31, 0xCC, 0x0C, 0xA6, 0x53, 0xB5, 0x5F, 0xFD, 0x7D, 0x29, 0x3A, 0x35, 0xE9, 0x0E, 0x25, 0x6C +}; + + +// Arto (RTO) +const static uint8_t test_output_rto[160] = { + 0x82, 0x66, 0x1E, 0x1C, 0x6E, 0x64, 0x36, 0x66, 0x84, 0x06, 0x32, 0x7A, 0x9B, 0xB1, 0x13, 0x19, + 0xA5, 0x56, 0x16, 0x15, 0xDF, 0xEC, 0x1C, 0x9E, 0xE3, 0x88, 0x4A, 0x6C, 0x1C, 0xEB, 0x76, 0xA5, + 0xB3, 0xFB, 0xF4, 0x3F, 0x2B, 0x6A, 0x3A, 0x39, 0xA3, 0x6E, 0x08, 0x33, 0x67, 0x90, 0x31, 0xB9, + 0x3F, 0x27, 0xE4, 0x79, 0x32, 0x61, 0x6B, 0x5C, 0x8A, 0xF8, 0xAF, 0xC0, 0x60, 0xFD, 0x83, 0xB7, + 0x11, 0x11, 0x89, 0xB4, 0xDC, 0xAE, 0x40, 0xC8, 0x64, 0xAA, 0x4D, 0x19, 0x23, 0x7B, 0xD3, 0x27, + 0xB2, 0x0F, 0xA7, 0x50, 0x7D, 0xCA, 0xF5, 0x03, 0x06, 0xB2, 0x26, 0x62, 0xF3, 0x68, 0x2D, 0x30, + 0x6F, 0x93, 0x1E, 0xFF, 0xCD, 0x85, 0x40, 0x28, 0x5F, 0xC3, 0x8C, 0x76, 0x51, 0x9E, 0xD5, 0x06, + 0x32, 0xD6, 0x35, 0x83, 0xF6, 0x3B, 0x54, 0x4F, 0xA1, 0x9C, 0x13, 0xD8, 0xC4, 0x0E, 0x01, 0x2F, + 0x29, 0xDB, 0x8C, 0x1C, 0xB7, 0x06, 0x86, 0x79, 0x6D, 0xFF, 0x9F, 0x89, 0x3B, 0x3A, 0xA5, 0x79, + 0xE7, 0x81, 0x4E, 0x2A, 0xBD, 0x62, 0xC1, 0x1B, 0x7C, 0xB9, 0x33, 0x7B, 0xEE, 0x95, 0x80, 0xB3 +}; + + #ifndef XMRIG_NO_AEON const static uint8_t test_output_v0_lite[160] = { 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, @@ -127,26 +187,11 @@ const static uint8_t test_output_v1_lite[160] = { 0x8C, 0x2B, 0xA4, 0x1F, 0x60, 0x76, 0x39, 0xD7, 0xF6, 0x46, 0x77, 0x18, 0x20, 0xAD, 0xD4, 0xC9, 0x87, 0xF7, 0x37, 0xDA, 0xFD, 0xBA, 0xBA, 0xD2, 0xF2, 0x68, 0xDC, 0x26, 0x8D, 0x1B, 0x08, 0xC6 }; - - -// IPBC -const static uint8_t test_output_ipbc_lite[160] = { - 0xE4, 0x93, 0x8C, 0xAA, 0x59, 0x8D, 0x02, 0x8A, 0xB8, 0x6F, 0x25, 0xD2, 0xB1, 0x23, 0xD0, 0xD5, - 0x33, 0xE3, 0x9F, 0x37, 0xAC, 0xE5, 0xF8, 0xEB, 0x7A, 0xE8, 0x40, 0xEB, 0x5D, 0xB1, 0x35, 0x5F, - 0xB2, 0x47, 0x86, 0xF0, 0x7F, 0x6F, 0x4B, 0x55, 0x3E, 0xA1, 0xBB, 0xE8, 0xA1, 0x75, 0x00, 0x2D, - 0x07, 0x9A, 0x21, 0x0E, 0xBD, 0x06, 0x6A, 0xB0, 0xFD, 0x96, 0x9E, 0xE6, 0xE4, 0x69, 0x67, 0xBB, - 0x88, 0x45, 0x0B, 0x91, 0x0B, 0x7B, 0xCB, 0x21, 0x3C, 0x3C, 0x09, 0x30, 0x07, 0x71, 0x07, 0xD5, - 0xB8, 0x2D, 0x83, 0x09, 0xAF, 0x7E, 0xB2, 0xA8, 0xAC, 0x25, 0xDC, 0x10, 0xF8, 0x63, 0x6A, 0xBC, - 0x73, 0x01, 0x4E, 0xA8, 0x1C, 0xDA, 0x9A, 0x86, 0x17, 0xEC, 0xA8, 0xFB, 0xAA, 0x23, 0x23, 0x17, - 0xE1, 0x32, 0x68, 0x9C, 0x4C, 0xF4, 0x08, 0xED, 0xB0, 0x15, 0xC3, 0xA9, 0x0F, 0xF0, 0xA2, 0x7E, - 0xD9, 0xE4, 0x23, 0xA7, 0x9E, 0x91, 0xD8, 0x73, 0x94, 0xD6, 0x6C, 0x70, 0x9B, 0x8B, 0x72, 0x92, - 0xA3, 0xA4, 0x0A, 0xE2, 0x3C, 0x0A, 0x34, 0x88, 0xA1, 0x6D, 0xFE, 0x02, 0x44, 0x60, 0x7B, 0x3D -}; #endif #ifndef XMRIG_NO_SUMO -const static uint8_t test_output_heavy[160] = { +const static uint8_t test_output_v0_heavy[160] = { 0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64, 0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2, 0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A, @@ -158,6 +203,34 @@ const static uint8_t test_output_heavy[160] = { 0x53, 0x62, 0x0A, 0x54, 0x7D, 0x43, 0xEA, 0x18, 0x94, 0xED, 0xD8, 0x92, 0x06, 0x6A, 0xA1, 0x51, 0xAD, 0xB1, 0xFD, 0x89, 0xFB, 0x5C, 0xB4, 0x25, 0x6A, 0xDD, 0xB0, 0x09, 0xC5, 0x72, 0x87, 0xEB }; + +const static uint8_t test_output_xhv_heavy[160] = { + 0x5A, 0xC3, 0xF7, 0x85, 0xC4, 0x90, 0xC5, 0x85, 0x50, 0xEC, 0x95, 0xD2, 0x72, 0x65, 0x63, 0x57, + 0x7E, 0x7C, 0x1C, 0x21, 0x2D, 0x0C, 0xDE, 0x59, 0x12, 0x73, 0x20, 0x1E, 0x44, 0xFD, 0xD5, 0xB6, + 0x1F, 0x4E, 0xB2, 0x0A, 0x36, 0x51, 0x4B, 0xF5, 0x4D, 0xC9, 0xE0, 0x90, 0x2C, 0x16, 0x47, 0x3F, + 0xDE, 0x18, 0x29, 0x8E, 0xBB, 0x34, 0x2B, 0xEF, 0x7A, 0x04, 0x22, 0xD1, 0xB1, 0xF2, 0x48, 0xDA, + 0xE3, 0x7F, 0x4B, 0x4C, 0xB4, 0xDF, 0xE8, 0xD3, 0x70, 0xE2, 0xE7, 0x44, 0x25, 0x87, 0x12, 0xF9, + 0x8F, 0x28, 0x0B, 0xCE, 0x2C, 0xEE, 0xDD, 0x88, 0x94, 0x35, 0x48, 0x51, 0xAE, 0xC8, 0x9C, 0x0B, + 0xED, 0x2F, 0xE6, 0x0F, 0x39, 0x05, 0xB4, 0x4A, 0x8F, 0x38, 0x44, 0x2D, 0x4B, 0xE9, 0x7B, 0x81, + 0xC6, 0xB0, 0xE0, 0x0A, 0x39, 0x8C, 0x38, 0xFE, 0x63, 0x31, 0x47, 0x65, 0x0D, 0x2B, 0xF4, 0x96, + 0x13, 0x91, 0x89, 0xB4, 0x5B, 0xA9, 0x2A, 0x7A, 0x09, 0x65, 0x14, 0x20, 0x76, 0x24, 0x6C, 0x80, + 0x1D, 0x3F, 0x9F, 0xCD, 0x68, 0x39, 0xA9, 0x42, 0x27, 0xC1, 0x0C, 0x53, 0x98, 0x35, 0x60, 0x7A +}; + + +// TUBE +const static uint8_t test_output_tube_heavy[160] = { + 0xFE, 0x53, 0x35, 0x20, 0x76, 0xEA, 0xE6, 0x89, 0xFA, 0x3B, 0x4F, 0xDA, 0x61, 0x46, 0x34, 0xCF, + 0xC3, 0x12, 0xEE, 0x0C, 0x38, 0x7D, 0xF2, 0xB8, 0xB7, 0x4D, 0xA2, 0xA1, 0x59, 0x74, 0x12, 0x35, + 0xCD, 0x3F, 0x29, 0xDF, 0x07, 0x4A, 0x14, 0xAD, 0x0B, 0x98, 0x99, 0x37, 0xCA, 0x14, 0x68, 0xA3, + 0x8D, 0xAE, 0x86, 0xC1, 0xA3, 0x54, 0x05, 0xBE, 0xEA, 0x6D, 0x29, 0x24, 0x0C, 0x82, 0x97, 0x74, + 0xA0, 0x64, 0x77, 0xCD, 0x8D, 0x8A, 0xC3, 0x10, 0xB4, 0x89, 0x0E, 0xBB, 0x7D, 0xE6, 0x32, 0x8F, + 0xF4, 0x2D, 0xB6, 0x9E, 0x8A, 0xF9, 0xF8, 0xEE, 0x2C, 0xD0, 0x74, 0xED, 0xA9, 0xAA, 0xA1, 0xFB, + 0xE2, 0xC9, 0x89, 0x66, 0xD6, 0x66, 0x52, 0xA2, 0x16, 0xDA, 0x36, 0xA0, 0x10, 0x62, 0xD2, 0xB1, + 0x76, 0xD1, 0x31, 0xE9, 0x1C, 0x08, 0xB6, 0xCA, 0xAF, 0x89, 0xB9, 0x3D, 0x2C, 0xFA, 0x9A, 0x30, + 0x74, 0x6A, 0x96, 0xA1, 0x95, 0x6C, 0xBB, 0x46, 0x4D, 0xE0, 0xEB, 0x28, 0xBE, 0x2A, 0x8C, 0x34, + 0x57, 0x79, 0xBE, 0x52, 0xFB, 0xBC, 0x68, 0x43, 0x45, 0xF4, 0xDF, 0xA5, 0xA8, 0xFD, 0x55, 0xA6 +}; #endif diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 66bcf8b5..8dcdd414 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -22,8 +23,8 @@ * along with this program. If not, see . */ -#ifndef __CRYPTONIGHT_X86_H__ -#define __CRYPTONIGHT_X86_H__ +#ifndef XMRIG_CRYPTONIGHT_X86_H +#define XMRIG_CRYPTONIGHT_X86_H #ifdef __GNUC__ @@ -73,10 +74,7 @@ static inline void do_skein_hash(const uint8_t *input, size_t len, uint8_t *outp void (* const extra_hashes[4])(const uint8_t *, size_t, uint8_t *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash}; - #if defined(__x86_64__) || defined(_M_AMD64) -# define EXTRACT64(X) _mm_cvtsi128_si64(X) - # ifdef __GNUC__ static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi) { @@ -88,13 +86,14 @@ static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi) #define __umul128 _umul128 # endif #elif defined(__i386__) || defined(_M_IX86) -# define HI32(X) \ - _mm_srli_si128((X), 4) +static inline int64_t _mm_cvtsi128_si64(__m128i a) +{ + return ((uint64_t)(uint32_t)_mm_cvtsi128_si32(a) | ((uint64_t)(uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(a, 4)) << 32)); +} - -# define EXTRACT64(X) \ - ((uint64_t)(uint32_t)_mm_cvtsi128_si32(X) | \ - ((uint64_t)(uint32_t)_mm_cvtsi128_si32(HI32(X)) << 32)) +static inline __m128i _mm_cvtsi64_si128(int64_t a) { + return _mm_set_epi64x(0, a); +} static inline uint64_t __umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) { // multiplier = ab = a * 2^32 + b @@ -386,89 +385,149 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } -template -static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) +static inline __m128i aes_round_tweak_div(const __m128i &in, const __m128i &key) { - mem_out[0] = EXTRACT64(tmp); + alignas(16) uint32_t k[4]; + alignas(16) uint32_t x[4]; - tmp = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(tmp), _mm_castsi128_ps(tmp))); - uint64_t vh = EXTRACT64(tmp); + _mm_store_si128((__m128i*) k, key); + _mm_store_si128((__m128i*) x, _mm_xor_si128(in, _mm_set_epi64x(0xffffffffffffffff, 0xffffffffffffffff))); - uint8_t x = vh >> 24; - static const uint16_t table = 0x7531; - const uint8_t index = (((x >> SHIFT) & 6) | (x & 1)) << 1; - vh ^= ((table >> index) & 0x3) << 28; + #define BYTE(p, i) ((unsigned char*)&x[p])[i] + k[0] ^= saes_table[0][BYTE(0, 0)] ^ saes_table[1][BYTE(1, 1)] ^ saes_table[2][BYTE(2, 2)] ^ saes_table[3][BYTE(3, 3)]; + x[0] ^= k[0]; + k[1] ^= saes_table[0][BYTE(1, 0)] ^ saes_table[1][BYTE(2, 1)] ^ saes_table[2][BYTE(3, 2)] ^ saes_table[3][BYTE(0, 3)]; + x[1] ^= k[1]; + k[2] ^= saes_table[0][BYTE(2, 0)] ^ saes_table[1][BYTE(3, 1)] ^ saes_table[2][BYTE(0, 2)] ^ saes_table[3][BYTE(1, 3)]; + x[2] ^= k[2]; + k[3] ^= saes_table[0][BYTE(3, 0)] ^ saes_table[1][BYTE(0, 1)] ^ saes_table[2][BYTE(1, 2)] ^ saes_table[3][BYTE(2, 3)]; + #undef BYTE - mem_out[1] = vh; + return _mm_load_si128((__m128i*)k); } -template +static inline __m128i int_sqrt_v2(const uint64_t n0) +{ + __m128d x = _mm_castsi128_pd(_mm_add_epi64(_mm_cvtsi64_si128(n0 >> 12), _mm_set_epi64x(0, 1023ULL << 52))); + x = _mm_sqrt_sd(_mm_setzero_pd(), x); + uint64_t r = static_cast(_mm_cvtsi128_si64(_mm_castpd_si128(x))); + + const uint64_t s = r >> 20; + r >>= 19; + + uint64_t x2 = (s - (1022ULL << 32)) * (r - s - (1022ULL << 32) + 1); +# if (defined(_MSC_VER) || __GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 1)) && (defined(__x86_64__) || defined(_M_AMD64)) + _addcarry_u64(_subborrow_u64(0, x2, n0, (unsigned long long int*)&x2), r, 0, (unsigned long long int*)&r); +# else + if (x2 < n0) ++r; +# endif + + return _mm_cvtsi64_si128(r); +} + + +template +static inline void cryptonight_monero_tweak(uint64_t* mem_out, const uint8_t* l, uint64_t idx, __m128i ax0, __m128i bx0, __m128i bx1, __m128i cx) +{ + if (VARIANT == xmrig::VARIANT_2) { + VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1); + _mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx)); + } else { + __m128i tmp = _mm_xor_si128(bx0, cx); + mem_out[0] = _mm_cvtsi128_si64(tmp); + + tmp = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(tmp), _mm_castsi128_ps(tmp))); + uint64_t vh = _mm_cvtsi128_si64(tmp); + + uint8_t x = static_cast(vh >> 24); + static const uint16_t table = 0x7531; + const uint8_t index = (((x >> (VARIANT == xmrig::VARIANT_XTL ? 4 : 3)) & 6) | (x & 1)) << 1; + vh ^= ((table >> index) & 0x3) << 28; + + mem_out[1] = vh; + } +} + + +template inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr bool IS_V1 = xmrig::cn_base_variant() == xmrig::VARIANT_1; - if (VARIANT > 0 && size < 43) { + if (IS_V1 && size < 43) { memset(output, 0, 32); return; } xmrig::keccak(input, size, ctx[0]->state); - VARIANT1_INIT(0) - cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); const uint8_t* l0 = ctx[0]->memory; uint64_t* h0 = reinterpret_cast(ctx[0]->state); + VARIANT1_INIT(0); + VARIANT2_INIT(0); + VARIANT2_SET_ROUNDING_MODE(); + uint64_t al0 = h0[0] ^ h0[4]; uint64_t ah0 = h0[1] ^ h0[5]; __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i bx1 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); uint64_t idx0 = al0; for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx; + if (VARIANT == xmrig::VARIANT_TUBE || !SOFT_AES) { + cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); + } - if (SOFT_AES) { - cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0)); + const __m128i ax0 = _mm_set_epi64x(ah0, al0); + if (VARIANT == xmrig::VARIANT_TUBE) { + cx = aes_round_tweak_div(cx, ax0); + } + else if (SOFT_AES) { + cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0); } else { - cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); - cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); + cx = _mm_aesenc_si128(cx, ax0); } - if (VARIANT > 0) { - cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); + if (IS_V1 || VARIANT == xmrig::VARIANT_2) { + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], l0, idx0 & MASK, ax0, bx0, bx1, cx); } else { _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); } - idx0 = EXTRACT64(cx); - bx0 = cx; + idx0 = _mm_cvtsi128_si64(cx); uint64_t hi, lo, cl, ch; cl = ((uint64_t*) &l0[idx0 & MASK])[0]; ch = ((uint64_t*) &l0[idx0 & MASK])[1]; - lo = __umul128(idx0, cl, &hi); + if (VARIANT == xmrig::VARIANT_2) { + VARIANT2_INTEGER_MATH(0, cl, cx); + lo = __umul128(idx0, cl, &hi); + VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo); + } + else { + lo = __umul128(idx0, cl, &hi); + } al0 += hi; ah0 += lo; ((uint64_t*)&l0[idx0 & MASK])[0] = al0; - if (VARIANT > 0) { - if (VARIANT == xmrig::VARIANT_IPBC) { - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; - } - else { - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; - } - } - else { + if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; + } else if (IS_V1) { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; + } else { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; } @@ -477,13 +536,22 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si idx0 = al0; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { - int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; - int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; + int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; + int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; int64_t q = n / (d | 0x5); ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; + + if (VARIANT == xmrig::VARIANT_XHV) { + d = ~d; + } + idx0 = d ^ q; } + if (VARIANT == xmrig::VARIANT_2) { + bx1 = bx0; + } + bx0 = cx; } cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); @@ -493,14 +561,67 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si } -template +#ifndef XMRIG_NO_ASM +extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx *ctx); +extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx *ctx); +extern "C" void cnv2_double_mainloop_sandybridge_asm(cryptonight_ctx* ctx0, cryptonight_ctx* ctx1); + + +template +inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) +{ + constexpr size_t MEM = xmrig::cn_select_memory(); + + xmrig::keccak(input, size, ctx[0]->state); + cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory)); + + if (ASM == xmrig::ASM_INTEL) { + cnv2_mainloop_ivybridge_asm(ctx[0]); + } + else { + cnv2_mainloop_ryzen_asm(ctx[0]); + } + + cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state)); + xmrig::keccakf(reinterpret_cast(ctx[0]->state), 24); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); +} + + +template +inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) +{ + constexpr size_t MEM = xmrig::cn_select_memory(); + + xmrig::keccak(input, size, ctx[0]->state); + xmrig::keccak(input + size, size, ctx[1]->state); + + cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory)); + cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[1]->state), reinterpret_cast<__m128i*>(ctx[1]->memory)); + + cnv2_double_mainloop_sandybridge_asm(ctx[0], ctx[1]); + + cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state)); + cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[1]->memory), reinterpret_cast<__m128i*>(ctx[1]->state)); + + xmrig::keccakf(reinterpret_cast(ctx[0]->state), 24); + xmrig::keccakf(reinterpret_cast(ctx[1]->state), 24); + + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); + extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); +} +#endif + + +template inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr bool IS_V1 = xmrig::cn_base_variant() == xmrig::VARIANT_1; - if (VARIANT > 0 && size < 43) { + if (IS_V1 && size < 43) { memset(output, 0, 64); return; } @@ -508,14 +629,17 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si xmrig::keccak(input, size, ctx[0]->state); xmrig::keccak(input + size, size, ctx[1]->state); - VARIANT1_INIT(0); - VARIANT1_INIT(1); - const uint8_t* l0 = ctx[0]->memory; const uint8_t* l1 = ctx[1]->memory; uint64_t* h0 = reinterpret_cast(ctx[0]->state); uint64_t* h1 = reinterpret_cast(ctx[1]->state); + VARIANT1_INIT(0); + VARIANT1_INIT(1); + VARIANT2_INIT(0); + VARIANT2_INIT(1); + VARIANT2_SET_ROUNDING_MODE(); + cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); @@ -524,60 +648,69 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si uint64_t ah0 = h0[1] ^ h0[5]; uint64_t ah1 = h1[1] ^ h1[5]; - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i bx00 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i bx01 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); + __m128i bx10 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i bx11 = _mm_set_epi64x(h1[9] ^ h1[11], h1[8] ^ h1[10]); uint64_t idx0 = al0; uint64_t idx1 = al1; for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx0, cx1; - - if (SOFT_AES) { - cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0)); - cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1)); - } - else { + if (VARIANT == xmrig::VARIANT_TUBE || !SOFT_AES) { cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); - cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); - cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); } - if (VARIANT > 0) { - cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); - cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + const __m128i ax0 = _mm_set_epi64x(ah0, al0); + const __m128i ax1 = _mm_set_epi64x(ah1, al1); + if (VARIANT == xmrig::VARIANT_TUBE) { + cx0 = aes_round_tweak_div(cx0, ax0); + cx1 = aes_round_tweak_div(cx1, ax1); + } + else if (SOFT_AES) { + cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0); + cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], ax1); + } + else { + cx0 = _mm_aesenc_si128(cx0, ax0); + cx1 = _mm_aesenc_si128(cx1, ax1); + } + + if (IS_V1 || (VARIANT == xmrig::VARIANT_2)) { + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], l0, idx0 & MASK, ax0, bx00, bx01, cx0); + cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], l1, idx1 & MASK, ax1, bx10, bx11, cx1); } else { - _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); - _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx00, cx0)); + _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx10, cx1)); } - idx0 = EXTRACT64(cx0); - idx1 = EXTRACT64(cx1); - - bx0 = cx0; - bx1 = cx1; + idx0 = _mm_cvtsi128_si64(cx0); + idx1 = _mm_cvtsi128_si64(cx1); uint64_t hi, lo, cl, ch; cl = ((uint64_t*) &l0[idx0 & MASK])[0]; ch = ((uint64_t*) &l0[idx0 & MASK])[1]; - lo = __umul128(idx0, cl, &hi); + if (VARIANT == xmrig::VARIANT_2) { + VARIANT2_INTEGER_MATH(0, cl, cx0); + lo = __umul128(idx0, cl, &hi); + VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo); + } else { + lo = __umul128(idx0, cl, &hi); + } al0 += hi; ah0 += lo; ((uint64_t*)&l0[idx0 & MASK])[0] = al0; - if (VARIANT > 0) { - if (VARIANT == xmrig::VARIANT_IPBC) { - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; - } - else { - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; - } - } - else { - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; + if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + ((uint64_t*) &l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; + } else if (IS_V1) { + ((uint64_t*) &l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; + } else { + ((uint64_t*) &l0[idx0 & MASK])[1] = ah0; } al0 ^= cl; @@ -585,32 +718,39 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si idx0 = al0; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { - int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; - int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; + int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; + int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; int64_t q = n / (d | 0x5); ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; + + if (VARIANT == xmrig::VARIANT_XHV) { + d = ~d; + } + idx0 = d ^ q; } cl = ((uint64_t*) &l1[idx1 & MASK])[0]; ch = ((uint64_t*) &l1[idx1 & MASK])[1]; - lo = __umul128(idx1, cl, &hi); + if (VARIANT == xmrig::VARIANT_2) { + VARIANT2_INTEGER_MATH(1, cl, cx1); + lo = __umul128(idx1, cl, &hi); + VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo); + } else { + lo = __umul128(idx1, cl, &hi); + } al1 += hi; ah1 += lo; ((uint64_t*)&l1[idx1 & MASK])[0] = al1; - if (VARIANT > 0) { - if (VARIANT == xmrig::VARIANT_IPBC) { - ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1; - } - else { - ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1; - } - } - else { + if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1; + } else if (IS_V1) { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1; + } else { ((uint64_t*)&l1[idx1 & MASK])[1] = ah1; } @@ -619,13 +759,25 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si idx1 = al1; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { - int64_t n = ((int64_t*)&l1[idx1 & MASK])[0]; - int32_t d = ((int32_t*)&l1[idx1 & MASK])[2]; + int64_t n = ((int64_t*)&l1[idx1 & MASK])[0]; + int32_t d = ((int32_t*)&l1[idx1 & MASK])[2]; int64_t q = n / (d | 0x5); ((int64_t*)&l1[idx1 & MASK])[0] = n ^ q; + + if (VARIANT == xmrig::VARIANT_XHV) { + d = ~d; + } + idx1 = d ^ q; } + + if (VARIANT == xmrig::VARIANT_2) { + bx01 = bx00; + bx11 = bx10; + } + bx00 = cx0; + bx10 = cx1; } cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); @@ -639,75 +791,103 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si } -#define CN_STEP1(a, b, c, l, ptr, idx) \ +#define CN_STEP1(a, b0, b1, c, l, ptr, idx) \ ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \ c = _mm_load_si128(ptr); -#define CN_STEP2(a, b, c, l, ptr, idx) \ - if (SOFT_AES) { \ +#define CN_STEP2(a, b0, b1, c, l, ptr, idx) \ + if (VARIANT == xmrig::VARIANT_TUBE) { \ + c = aes_round_tweak_div(c, a); \ + } \ + else if (SOFT_AES) { \ c = soft_aesenc(c, a); \ } else { \ c = _mm_aesenc_si128(c, a); \ } \ \ - b = _mm_xor_si128(b, c); \ - \ - if (VARIANT > 0) { \ - cryptonight_monero_tweak(reinterpret_cast(ptr), b); \ + if (IS_V1 || (VARIANT == xmrig::VARIANT_2)) { \ + cryptonight_monero_tweak((uint64_t*)ptr, l, idx & MASK, a, b0, b1, c); \ } else { \ - _mm_store_si128(ptr, b); \ + _mm_store_si128(ptr, _mm_xor_si128(b0, c)); \ } -#define CN_STEP3(a, b, c, l, ptr, idx) \ - idx = EXTRACT64(c); \ +#define CN_STEP3(part, a, b0, b1, c, l, ptr, idx) \ + idx = _mm_cvtsi128_si64(c); \ ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \ - b = _mm_load_si128(ptr); + uint64_t cl##part = ((uint64_t*)ptr)[0]; \ + uint64_t ch##part = ((uint64_t*)ptr)[1]; -#define CN_STEP4(a, b, c, l, mc, ptr, idx) \ - lo = __umul128(idx, EXTRACT64(b), &hi); \ +#define CN_STEP4(part, a, b0, b1, c, l, mc, ptr, idx) \ + if (VARIANT == xmrig::VARIANT_2) { \ + VARIANT2_INTEGER_MATH(part, cl##part, c); \ + lo = __umul128(idx, cl##part, &hi); \ + VARIANT2_SHUFFLE2(l, idx & MASK, a, b0, b1, hi, lo); \ + } else { \ + lo = __umul128(idx, cl##part, &hi); \ + } \ a = _mm_add_epi64(a, _mm_set_epi64x(lo, hi)); \ \ - if (VARIANT > 0) { \ + if (IS_V1) { \ _mm_store_si128(ptr, _mm_xor_si128(a, mc)); \ \ - if (VARIANT == xmrig::VARIANT_IPBC) { \ + if (VARIANT == xmrig::VARIANT_TUBE || \ + VARIANT == xmrig::VARIANT_RTO) { \ ((uint64_t*)ptr)[1] ^= ((uint64_t*)ptr)[0]; \ } \ } else { \ _mm_store_si128(ptr, a); \ } \ \ - a = _mm_xor_si128(a, b); \ - idx = EXTRACT64(a); \ + a = _mm_xor_si128(a, _mm_set_epi64x(ch##part, cl##part)); \ + idx = _mm_cvtsi128_si64(a); \ \ if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { \ int64_t n = ((int64_t*)&l[idx & MASK])[0]; \ int32_t d = ((int32_t*)&l[idx & MASK])[2]; \ int64_t q = n / (d | 0x5); \ ((int64_t*)&l[idx & MASK])[0] = n ^ q; \ + if (VARIANT == xmrig::VARIANT_XHV) { \ + d = ~d; \ + } \ + \ idx = d ^ q; \ - } + } \ + if (VARIANT == xmrig::VARIANT_2) { \ + b1 = b0; \ + } \ + b0 = c; #define CONST_INIT(ctx, n) \ __m128i mc##n; \ - if (VARIANT > 0) { \ + __m128i division_result_xmm_##n; \ + __m128i sqrt_result_xmm_##n; \ + if (IS_V1) { \ mc##n = _mm_set_epi64x(*reinterpret_cast(input + n * size + 35) ^ \ *(reinterpret_cast((ctx)->state) + 24), 0); \ - } + } \ + if (VARIANT == xmrig::VARIANT_2) { \ + division_result_xmm_##n = _mm_cvtsi64_si128(h##n[12]); \ + sqrt_result_xmm_##n = _mm_cvtsi64_si128(h##n[13]); \ + } \ + __m128i ax##n = _mm_set_epi64x(h##n[1] ^ h##n[5], h##n[0] ^ h##n[4]); \ + __m128i bx##n##0 = _mm_set_epi64x(h##n[3] ^ h##n[7], h##n[2] ^ h##n[6]); \ + __m128i bx##n##1 = _mm_set_epi64x(h##n[9] ^ h##n[11], h##n[8] ^ h##n[10]); \ + __m128i cx##n = _mm_setzero_si128(); -template +template inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr bool IS_V1 = xmrig::cn_base_variant() == xmrig::VARIANT_1; - if (VARIANT > 0 && size < 43) { + if (IS_V1 && size < 43) { memset(output, 0, 32 * 3); return; } @@ -717,10 +897,6 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } - CONST_INIT(ctx[0], 0); - CONST_INIT(ctx[1], 1); - CONST_INIT(ctx[2], 2); - uint8_t* l0 = ctx[0]->memory; uint8_t* l1 = ctx[1]->memory; uint8_t* l2 = ctx[2]->memory; @@ -728,58 +904,35 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si uint64_t* h1 = reinterpret_cast(ctx[1]->state); uint64_t* h2 = reinterpret_cast(ctx[2]->state); - __m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); - __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); - __m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); - __m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]); - __m128i cx0 = _mm_set_epi64x(0, 0); - __m128i cx1 = _mm_set_epi64x(0, 0); - __m128i cx2 = _mm_set_epi64x(0, 0); + CONST_INIT(ctx[0], 0); + CONST_INIT(ctx[1], 1); + CONST_INIT(ctx[2], 2); + VARIANT2_SET_ROUNDING_MODE(); uint64_t idx0, idx1, idx2; - idx0 = EXTRACT64(ax0); - idx1 = EXTRACT64(ax1); - idx2 = EXTRACT64(ax2); + idx0 = _mm_cvtsi128_si64(ax0); + idx1 = _mm_cvtsi128_si64(ax1); + idx2 = _mm_cvtsi128_si64(ax2); - for (size_t i = 0; i < ITERATIONS / 2; i++) { + for (size_t i = 0; i < ITERATIONS; i++) { uint64_t hi, lo; __m128i *ptr0, *ptr1, *ptr2; - // EVEN ROUND - CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); - CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); - CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP1(ax0, bx00, bx01, cx0, l0, ptr0, idx0); + CN_STEP1(ax1, bx10, bx11, cx1, l1, ptr1, idx1); + CN_STEP1(ax2, bx20, bx21, cx2, l2, ptr2, idx2); - CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); - CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); - CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP2(ax0, bx00, bx01, cx0, l0, ptr0, idx0); + CN_STEP2(ax1, bx10, bx11, cx1, l1, ptr1, idx1); + CN_STEP2(ax2, bx20, bx21, cx2, l2, ptr2, idx2); - CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); - CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); - CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP3(0, ax0, bx00, bx01, cx0, l0, ptr0, idx0); + CN_STEP3(1, ax1, bx10, bx11, cx1, l1, ptr1, idx1); + CN_STEP3(2, ax2, bx20, bx21, cx2, l2, ptr2, idx2); - CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); - CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); - CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); - - // ODD ROUND - CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0); - CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1); - CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2); - - CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0); - CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1); - CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2); - - CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0); - CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1); - CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2); - - CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0); - CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1); - CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2); + CN_STEP4(0, ax0, bx00, bx01, cx0, l0, mc0, ptr0, idx0); + CN_STEP4(1, ax1, bx10, bx11, cx1, l1, mc1, ptr1, idx1); + CN_STEP4(2, ax2, bx20, bx21, cx2, l2, mc2, ptr2, idx2); } for (size_t i = 0; i < 3; i++) { @@ -790,14 +943,15 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si } -template +template inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr bool IS_V1 = xmrig::cn_base_variant() == xmrig::VARIANT_1;; - if (VARIANT > 0 && size < 43) { + if (IS_V1 && size < 43) { memset(output, 0, 32 * 4); return; } @@ -807,11 +961,6 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } - CONST_INIT(ctx[0], 0); - CONST_INIT(ctx[1], 1); - CONST_INIT(ctx[2], 2); - CONST_INIT(ctx[3], 3); - uint8_t* l0 = ctx[0]->memory; uint8_t* l1 = ctx[1]->memory; uint8_t* l2 = ctx[2]->memory; @@ -821,71 +970,42 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size uint64_t* h2 = reinterpret_cast(ctx[2]->state); uint64_t* h3 = reinterpret_cast(ctx[3]->state); - __m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); - __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); - __m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); - __m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]); - __m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]); - __m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]); - __m128i cx0 = _mm_set_epi64x(0, 0); - __m128i cx1 = _mm_set_epi64x(0, 0); - __m128i cx2 = _mm_set_epi64x(0, 0); - __m128i cx3 = _mm_set_epi64x(0, 0); + CONST_INIT(ctx[0], 0); + CONST_INIT(ctx[1], 1); + CONST_INIT(ctx[2], 2); + CONST_INIT(ctx[3], 3); + VARIANT2_SET_ROUNDING_MODE(); uint64_t idx0, idx1, idx2, idx3; - idx0 = EXTRACT64(ax0); - idx1 = EXTRACT64(ax1); - idx2 = EXTRACT64(ax2); - idx3 = EXTRACT64(ax3); + idx0 = _mm_cvtsi128_si64(ax0); + idx1 = _mm_cvtsi128_si64(ax1); + idx2 = _mm_cvtsi128_si64(ax2); + idx3 = _mm_cvtsi128_si64(ax3); - for (size_t i = 0; i < ITERATIONS / 2; i++) + for (size_t i = 0; i < ITERATIONS; i++) { uint64_t hi, lo; __m128i *ptr0, *ptr1, *ptr2, *ptr3; - // EVEN ROUND - CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); - CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); - CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); - CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3); + CN_STEP1(ax0, bx00, bx01, cx0, l0, ptr0, idx0); + CN_STEP1(ax1, bx10, bx11, cx1, l1, ptr1, idx1); + CN_STEP1(ax2, bx20, bx21, cx2, l2, ptr2, idx2); + CN_STEP1(ax3, bx30, bx31, cx3, l3, ptr3, idx3); - CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); - CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); - CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); - CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3); + CN_STEP2(ax0, bx00, bx01, cx0, l0, ptr0, idx0); + CN_STEP2(ax1, bx10, bx11, cx1, l1, ptr1, idx1); + CN_STEP2(ax2, bx20, bx21, cx2, l2, ptr2, idx2); + CN_STEP2(ax3, bx30, bx31, cx3, l3, ptr3, idx3); - CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); - CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); - CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); - CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3); + CN_STEP3(0, ax0, bx00, bx01, cx0, l0, ptr0, idx0); + CN_STEP3(1, ax1, bx10, bx11, cx1, l1, ptr1, idx1); + CN_STEP3(2, ax2, bx20, bx21, cx2, l2, ptr2, idx2); + CN_STEP3(3, ax3, bx30, bx31, cx3, l3, ptr3, idx3); - CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); - CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); - CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); - CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3); - - // ODD ROUND - CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0); - CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1); - CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2); - CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3); - - CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0); - CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1); - CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2); - CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3); - - CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0); - CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1); - CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2); - CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3); - - CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0); - CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1); - CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2); - CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3); + CN_STEP4(0, ax0, bx00, bx01, cx0, l0, mc0, ptr0, idx0); + CN_STEP4(1, ax1, bx10, bx11, cx1, l1, mc1, ptr1, idx1); + CN_STEP4(2, ax2, bx20, bx21, cx2, l2, mc2, ptr2, idx2); + CN_STEP4(3, ax3, bx30, bx31, cx3, l3, mc3, ptr3, idx3); } for (size_t i = 0; i < 4; i++) { @@ -896,14 +1016,15 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size } -template +template inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr bool IS_V1 = xmrig::cn_base_variant() == xmrig::VARIANT_1; - if (VARIANT > 0 && size < 43) { + if (IS_V1 && size < 43) { memset(output, 0, 32 * 5); return; } @@ -913,12 +1034,6 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } - CONST_INIT(ctx[0], 0); - CONST_INIT(ctx[1], 1); - CONST_INIT(ctx[2], 2); - CONST_INIT(ctx[3], 3); - CONST_INIT(ctx[4], 4); - uint8_t* l0 = ctx[0]->memory; uint8_t* l1 = ctx[1]->memory; uint8_t* l2 = ctx[2]->memory; @@ -930,83 +1045,48 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz uint64_t* h3 = reinterpret_cast(ctx[3]->state); uint64_t* h4 = reinterpret_cast(ctx[4]->state); - __m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); - __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); - __m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); - __m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]); - __m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]); - __m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]); - __m128i ax4 = _mm_set_epi64x(h4[1] ^ h4[5], h4[0] ^ h4[4]); - __m128i bx4 = _mm_set_epi64x(h4[3] ^ h4[7], h4[2] ^ h4[6]); - __m128i cx0 = _mm_set_epi64x(0, 0); - __m128i cx1 = _mm_set_epi64x(0, 0); - __m128i cx2 = _mm_set_epi64x(0, 0); - __m128i cx3 = _mm_set_epi64x(0, 0); - __m128i cx4 = _mm_set_epi64x(0, 0); + CONST_INIT(ctx[0], 0); + CONST_INIT(ctx[1], 1); + CONST_INIT(ctx[2], 2); + CONST_INIT(ctx[3], 3); + CONST_INIT(ctx[4], 4); + VARIANT2_SET_ROUNDING_MODE(); uint64_t idx0, idx1, idx2, idx3, idx4; - idx0 = EXTRACT64(ax0); - idx1 = EXTRACT64(ax1); - idx2 = EXTRACT64(ax2); - idx3 = EXTRACT64(ax3); - idx4 = EXTRACT64(ax4); + idx0 = _mm_cvtsi128_si64(ax0); + idx1 = _mm_cvtsi128_si64(ax1); + idx2 = _mm_cvtsi128_si64(ax2); + idx3 = _mm_cvtsi128_si64(ax3); + idx4 = _mm_cvtsi128_si64(ax4); - for (size_t i = 0; i < ITERATIONS / 2; i++) + for (size_t i = 0; i < ITERATIONS; i++) { uint64_t hi, lo; __m128i *ptr0, *ptr1, *ptr2, *ptr3, *ptr4; - // EVEN ROUND - CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); - CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); - CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); - CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3); - CN_STEP1(ax4, bx4, cx4, l4, ptr4, idx4); + CN_STEP1(ax0, bx00, bx01, cx0, l0, ptr0, idx0); + CN_STEP1(ax1, bx10, bx11, cx1, l1, ptr1, idx1); + CN_STEP1(ax2, bx20, bx21, cx2, l2, ptr2, idx2); + CN_STEP1(ax3, bx30, bx31, cx3, l3, ptr3, idx3); + CN_STEP1(ax4, bx40, bx41, cx4, l4, ptr4, idx4); - CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); - CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); - CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); - CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3); - CN_STEP2(ax4, bx4, cx4, l4, ptr4, idx4); + CN_STEP2(ax0, bx00, bx01, cx0, l0, ptr0, idx0); + CN_STEP2(ax1, bx10, bx11, cx1, l1, ptr1, idx1); + CN_STEP2(ax2, bx20, bx21, cx2, l2, ptr2, idx2); + CN_STEP2(ax3, bx30, bx31, cx3, l3, ptr3, idx3); + CN_STEP2(ax4, bx40, bx41, cx4, l4, ptr4, idx4); - CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); - CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); - CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); - CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3); - CN_STEP3(ax4, bx4, cx4, l4, ptr4, idx4); + CN_STEP3(0, ax0, bx00, bx01, cx0, l0, ptr0, idx0); + CN_STEP3(1, ax1, bx10, bx11, cx1, l1, ptr1, idx1); + CN_STEP3(2, ax2, bx20, bx21, cx2, l2, ptr2, idx2); + CN_STEP3(3, ax3, bx30, bx31, cx3, l3, ptr3, idx3); + CN_STEP3(4, ax4, bx40, bx41, cx4, l4, ptr4, idx4); - CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); - CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); - CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); - CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3); - CN_STEP4(ax4, bx4, cx4, l4, mc4, ptr4, idx4); - - // ODD ROUND - CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0); - CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1); - CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2); - CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3); - CN_STEP1(ax4, cx4, bx4, l4, ptr4, idx4); - - CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0); - CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1); - CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2); - CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3); - CN_STEP2(ax4, cx4, bx4, l4, ptr4, idx4); - - CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0); - CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1); - CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2); - CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3); - CN_STEP3(ax4, cx4, bx4, l4, ptr4, idx4); - - CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0); - CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1); - CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2); - CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3); - CN_STEP4(ax4, cx4, bx4, l4, mc4, ptr4, idx4); + CN_STEP4(0, ax0, bx00, bx01, cx0, l0, mc0, ptr0, idx0); + CN_STEP4(1, ax1, bx10, bx11, cx1, l1, mc1, ptr1, idx1); + CN_STEP4(2, ax2, bx20, bx21, cx2, l2, mc2, ptr2, idx2); + CN_STEP4(3, ax3, bx30, bx31, cx3, l3, mc3, ptr3, idx3); + CN_STEP4(4, ax4, bx40, bx41, cx4, l4, mc4, ptr4, idx4); } for (size_t i = 0; i < 5; i++) { @@ -1016,4 +1096,4 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz } } -#endif /* __CRYPTONIGHT_X86_H__ */ +#endif /* XMRIG_CRYPTONIGHT_X86_H */ diff --git a/src/crypto/asm/cnv2_double_main_loop_sandybridge.inc b/src/crypto/asm/cnv2_double_main_loop_sandybridge.inc new file mode 100644 index 00000000..e8251bc7 --- /dev/null +++ b/src/crypto/asm/cnv2_double_main_loop_sandybridge.inc @@ -0,0 +1,410 @@ + mov rax, rsp + push rbx + push rbp + push rsi + push rdi + push r12 + push r13 + push r14 + push r15 + sub rsp, 184 + + stmxcsr DWORD PTR [rsp+272] + mov DWORD PTR [rsp+276], 24448 + ldmxcsr DWORD PTR [rsp+276] + + mov r13, QWORD PTR [rcx+224] + mov r9, rdx + mov r10, QWORD PTR [rcx+32] + mov r8, rcx + xor r10, QWORD PTR [rcx] + mov r14d, 524288 + mov r11, QWORD PTR [rcx+40] + xor r11, QWORD PTR [rcx+8] + mov rsi, QWORD PTR [rdx+224] + mov rdx, QWORD PTR [rcx+56] + xor rdx, QWORD PTR [rcx+24] + mov rdi, QWORD PTR [r9+32] + xor rdi, QWORD PTR [r9] + mov rbp, QWORD PTR [r9+40] + xor rbp, QWORD PTR [r9+8] + movq xmm0, rdx + movaps XMMWORD PTR [rax-88], xmm6 + movaps XMMWORD PTR [rax-104], xmm7 + movaps XMMWORD PTR [rax-120], xmm8 + movaps XMMWORD PTR [rsp+112], xmm9 + movaps XMMWORD PTR [rsp+96], xmm10 + movaps XMMWORD PTR [rsp+80], xmm11 + movaps XMMWORD PTR [rsp+64], xmm12 + movaps XMMWORD PTR [rsp+48], xmm13 + movaps XMMWORD PTR [rsp+32], xmm14 + movaps XMMWORD PTR [rsp+16], xmm15 + mov rdx, r10 + movq xmm4, QWORD PTR [r8+96] + and edx, 2097136 + mov rax, QWORD PTR [rcx+48] + xorps xmm13, xmm13 + xor rax, QWORD PTR [rcx+16] + mov rcx, QWORD PTR [rcx+88] + xor rcx, QWORD PTR [r8+72] + movq xmm5, QWORD PTR [r8+104] + movq xmm7, rax + + mov eax, 1 + shl rax, 52 + movq xmm14, rax + punpcklqdq xmm14, xmm14 + + mov eax, 1023 + shl rax, 52 + movq xmm12, rax + punpcklqdq xmm12, xmm12 + + mov rax, QWORD PTR [r8+80] + xor rax, QWORD PTR [r8+64] + punpcklqdq xmm7, xmm0 + movq xmm0, rcx + mov rcx, QWORD PTR [r9+56] + xor rcx, QWORD PTR [r9+24] + movq xmm3, rax + mov rax, QWORD PTR [r9+48] + xor rax, QWORD PTR [r9+16] + punpcklqdq xmm3, xmm0 + movq xmm0, rcx + mov QWORD PTR [rsp], r13 + mov rcx, QWORD PTR [r9+88] + xor rcx, QWORD PTR [r9+72] + movq xmm6, rax + mov rax, QWORD PTR [r9+80] + xor rax, QWORD PTR [r9+64] + punpcklqdq xmm6, xmm0 + movq xmm0, rcx + mov QWORD PTR [rsp+256], r10 + mov rcx, rdi + mov QWORD PTR [rsp+264], r11 + movq xmm8, rax + and ecx, 2097136 + punpcklqdq xmm8, xmm0 + movq xmm0, QWORD PTR [r9+96] + punpcklqdq xmm4, xmm0 + movq xmm0, QWORD PTR [r9+104] + lea r8, QWORD PTR [rcx+rsi] + movdqu xmm11, XMMWORD PTR [r8] + punpcklqdq xmm5, xmm0 + lea r9, QWORD PTR [rdx+r13] + movdqu xmm15, XMMWORD PTR [r9] + + ALIGN 16 +main_loop_double_sandybridge: + movdqu xmm9, xmm15 + mov eax, edx + mov ebx, edx + xor eax, 16 + xor ebx, 32 + xor edx, 48 + + movq xmm0, r11 + movq xmm2, r10 + punpcklqdq xmm2, xmm0 + aesenc xmm9, xmm2 + + movdqu xmm0, XMMWORD PTR [rax+r13] + movdqu xmm1, XMMWORD PTR [rbx+r13] + paddq xmm0, xmm7 + paddq xmm1, xmm2 + movdqu XMMWORD PTR [rbx+r13], xmm0 + movdqu xmm0, XMMWORD PTR [rdx+r13] + movdqu XMMWORD PTR [rdx+r13], xmm1 + paddq xmm0, xmm3 + movdqu XMMWORD PTR [rax+r13], xmm0 + + movq r11, xmm9 + mov edx, r11d + and edx, 2097136 + movdqa xmm0, xmm9 + pxor xmm0, xmm7 + movdqu XMMWORD PTR [r9], xmm0 + + lea rbx, QWORD PTR [rdx+r13] + mov r10, QWORD PTR [rdx+r13] + + movdqu xmm10, xmm11 + movq xmm0, rbp + movq xmm11, rdi + punpcklqdq xmm11, xmm0 + aesenc xmm10, xmm11 + + mov eax, ecx + mov r12d, ecx + xor eax, 16 + xor r12d, 32 + xor ecx, 48 + + movdqu xmm0, XMMWORD PTR [rax+rsi] + paddq xmm0, xmm6 + movdqu xmm1, XMMWORD PTR [r12+rsi] + movdqu XMMWORD PTR [r12+rsi], xmm0 + paddq xmm1, xmm11 + movdqu xmm0, XMMWORD PTR [rcx+rsi] + movdqu XMMWORD PTR [rcx+rsi], xmm1 + paddq xmm0, xmm8 + movdqu XMMWORD PTR [rax+rsi], xmm0 + + movq rcx, xmm10 + and ecx, 2097136 + + movdqa xmm0, xmm10 + pxor xmm0, xmm6 + movdqu XMMWORD PTR [r8], xmm0 + mov r12, QWORD PTR [rcx+rsi] + + mov r9, QWORD PTR [rbx+8] + + xor edx, 16 + mov r8d, edx + mov r15d, edx + + movq rdx, xmm5 + shl rdx, 32 + movq rax, xmm4 + xor rdx, rax + xor r10, rdx + mov rax, r10 + mul r11 + mov r11d, r8d + xor r11d, 48 + movq xmm0, rdx + xor rdx, [r11+r13] + movq xmm1, rax + xor rax, [r11+r13+8] + punpcklqdq xmm0, xmm1 + + pxor xmm0, XMMWORD PTR [r8+r13] + xor r8d, 32 + movdqu xmm1, XMMWORD PTR [r11+r13] + paddq xmm0, xmm7 + paddq xmm1, xmm2 + movdqu XMMWORD PTR [r11+r13], xmm0 + movdqu xmm0, XMMWORD PTR [r8+r13] + movdqu XMMWORD PTR [r8+r13], xmm1 + paddq xmm0, xmm3 + movdqu XMMWORD PTR [r15+r13], xmm0 + + mov r11, QWORD PTR [rsp+256] + add r11, rdx + mov rdx, QWORD PTR [rsp+264] + add rdx, rax + mov QWORD PTR [rbx], r11 + xor r11, r10 + mov QWORD PTR [rbx+8], rdx + xor rdx, r9 + mov QWORD PTR [rsp+256], r11 + and r11d, 2097136 + mov QWORD PTR [rsp+264], rdx + mov QWORD PTR [rsp+8], r11 + lea r15, QWORD PTR [r11+r13] + movdqu xmm15, XMMWORD PTR [r11+r13] + lea r13, QWORD PTR [rsi+rcx] + movdqa xmm0, xmm5 + psrldq xmm0, 8 + movaps xmm2, xmm13 + movq r10, xmm0 + psllq xmm5, 1 + shl r10, 32 + movdqa xmm0, xmm9 + psrldq xmm0, 8 + movdqa xmm1, xmm10 + movq r11, xmm0 + psrldq xmm1, 8 + movq r8, xmm1 + psrldq xmm4, 8 + movaps xmm0, xmm13 + movq rax, xmm4 + xor r10, rax + movaps xmm1, xmm13 + xor r10, r12 + lea rax, QWORD PTR [r11+1] + shr rax, 1 + movdqa xmm3, xmm9 + punpcklqdq xmm3, xmm10 + paddq xmm5, xmm3 + movq rdx, xmm5 + psrldq xmm5, 8 + cvtsi2sd xmm2, rax + or edx, -2147483647 + lea rax, QWORD PTR [r8+1] + shr rax, 1 + movq r9, xmm5 + cvtsi2sd xmm0, rax + or r9d, -2147483647 + cvtsi2sd xmm1, rdx + unpcklpd xmm2, xmm0 + movaps xmm0, xmm13 + cvtsi2sd xmm0, r9 + unpcklpd xmm1, xmm0 + divpd xmm2, xmm1 + paddq xmm2, xmm14 + cvttsd2si rax, xmm2 + psrldq xmm2, 8 + mov rbx, rax + imul rax, rdx + sub r11, rax + js div_fix_1_sandybridge +div_fix_1_ret_sandybridge: + + cvttsd2si rdx, xmm2 + mov rax, rdx + imul rax, r9 + movd xmm2, r11d + movd xmm4, ebx + sub r8, rax + js div_fix_2_sandybridge +div_fix_2_ret_sandybridge: + + movd xmm1, r8d + movd xmm0, edx + punpckldq xmm2, xmm1 + punpckldq xmm4, xmm0 + punpckldq xmm4, xmm2 + paddq xmm3, xmm4 + movdqa xmm0, xmm3 + psrlq xmm0, 12 + paddq xmm0, xmm12 + sqrtpd xmm1, xmm0 + movq r9, xmm1 + movdqa xmm5, xmm1 + psrlq xmm5, 19 + test r9, 524287 + je sqrt_fix_1_sandybridge +sqrt_fix_1_ret_sandybridge: + + movq r9, xmm10 + psrldq xmm1, 8 + movq r8, xmm1 + test r8, 524287 + je sqrt_fix_2_sandybridge +sqrt_fix_2_ret_sandybridge: + + mov r12d, ecx + mov r8d, ecx + xor r12d, 16 + xor r8d, 32 + xor ecx, 48 + mov rax, r10 + mul r9 + movq xmm0, rax + movq xmm3, rdx + punpcklqdq xmm3, xmm0 + + movdqu xmm0, XMMWORD PTR [r12+rsi] + pxor xmm0, xmm3 + movdqu xmm1, XMMWORD PTR [r8+rsi] + xor rdx, [r8+rsi] + xor rax, [r8+rsi+8] + movdqu xmm3, XMMWORD PTR [rcx+rsi] + paddq xmm0, xmm6 + paddq xmm1, xmm11 + paddq xmm3, xmm8 + movdqu XMMWORD PTR [r8+rsi], xmm0 + movdqu XMMWORD PTR [rcx+rsi], xmm1 + movdqu XMMWORD PTR [r12+rsi], xmm3 + + add rdi, rdx + mov QWORD PTR [r13], rdi + xor rdi, r10 + mov ecx, edi + and ecx, 2097136 + lea r8, QWORD PTR [rcx+rsi] + + mov rdx, QWORD PTR [r13+8] + add rbp, rax + mov QWORD PTR [r13+8], rbp + movdqu xmm11, XMMWORD PTR [rcx+rsi] + xor rbp, rdx + mov r13, QWORD PTR [rsp] + movdqa xmm3, xmm7 + mov rdx, QWORD PTR [rsp+8] + movdqa xmm8, xmm6 + mov r10, QWORD PTR [rsp+256] + movdqa xmm7, xmm9 + mov r11, QWORD PTR [rsp+264] + movdqa xmm6, xmm10 + mov r9, r15 + dec r14d + jne main_loop_double_sandybridge + + ldmxcsr DWORD PTR [rsp+272] + movaps xmm13, XMMWORD PTR [rsp+48] + lea r11, QWORD PTR [rsp+184] + movaps xmm6, XMMWORD PTR [r11-24] + movaps xmm7, XMMWORD PTR [r11-40] + movaps xmm8, XMMWORD PTR [r11-56] + movaps xmm9, XMMWORD PTR [r11-72] + movaps xmm10, XMMWORD PTR [r11-88] + movaps xmm11, XMMWORD PTR [r11-104] + movaps xmm12, XMMWORD PTR [r11-120] + movaps xmm14, XMMWORD PTR [rsp+32] + movaps xmm15, XMMWORD PTR [rsp+16] + mov rsp, r11 + pop r15 + pop r14 + pop r13 + pop r12 + pop rdi + pop rsi + pop rbp + pop rbx + jmp cnv2_double_mainloop_asm_sandybridge_endp + +div_fix_1_sandybridge: + dec rbx + add r11, rdx + jmp div_fix_1_ret_sandybridge + +div_fix_2_sandybridge: + dec rdx + add r8, r9 + jmp div_fix_2_ret_sandybridge + +sqrt_fix_1_sandybridge: + movq r8, xmm3 + movdqa xmm0, xmm5 + psrldq xmm0, 8 + dec r9 + mov r11d, -1022 + shl r11, 32 + mov rax, r9 + shr r9, 19 + shr rax, 20 + mov rdx, r9 + sub rdx, rax + lea rdx, [rdx+r11+1] + add rax, r11 + imul rdx, rax + sub rdx, r8 + adc r9, 0 + movq xmm5, r9 + punpcklqdq xmm5, xmm0 + jmp sqrt_fix_1_ret_sandybridge + +sqrt_fix_2_sandybridge: + psrldq xmm3, 8 + movq r11, xmm3 + dec r8 + mov ebx, -1022 + shl rbx, 32 + mov rax, r8 + shr r8, 19 + shr rax, 20 + mov rdx, r8 + sub rdx, rax + lea rdx, [rdx+rbx+1] + add rax, rbx + imul rdx, rax + sub rdx, r11 + adc r8, 0 + movq xmm0, r8 + punpcklqdq xmm5, xmm0 + jmp sqrt_fix_2_ret_sandybridge + +cnv2_double_mainloop_asm_sandybridge_endp: diff --git a/src/crypto/asm/cnv2_main_loop.S b/src/crypto/asm/cnv2_main_loop.S new file mode 100644 index 00000000..4dbcbbda --- /dev/null +++ b/src/crypto/asm/cnv2_main_loop.S @@ -0,0 +1,37 @@ +#define ALIGN .align +.intel_syntax noprefix +#ifdef __APPLE__ +# define FN_PREFIX(fn) _ ## fn +.text +#else +# define FN_PREFIX(fn) fn +.section .text +#endif +.global FN_PREFIX(cnv2_mainloop_ivybridge_asm) +.global FN_PREFIX(cnv2_mainloop_ryzen_asm) +.global FN_PREFIX(cnv2_double_mainloop_sandybridge_asm) + +ALIGN 16 +FN_PREFIX(cnv2_mainloop_ivybridge_asm): + sub rsp, 48 + mov rcx, rdi + #include "cnv2_main_loop_ivybridge.inc" + add rsp, 48 + ret 0 + +ALIGN 16 +FN_PREFIX(cnv2_mainloop_ryzen_asm): + sub rsp, 48 + mov rcx, rdi + #include "cnv2_main_loop_ryzen.inc" + add rsp, 48 + ret 0 + +ALIGN 16 +FN_PREFIX(cnv2_double_mainloop_sandybridge_asm): + sub rsp, 48 + mov rcx, rdi + mov rdx, rsi + #include "cnv2_double_main_loop_sandybridge.inc" + add rsp, 48 + ret 0 diff --git a/src/crypto/asm/cnv2_main_loop.asm b/src/crypto/asm/cnv2_main_loop.asm new file mode 100644 index 00000000..d9522267 --- /dev/null +++ b/src/crypto/asm/cnv2_main_loop.asm @@ -0,0 +1,25 @@ +_TEXT_CNV2_MAINLOOP SEGMENT PAGE READ EXECUTE +PUBLIC cnv2_mainloop_ivybridge_asm +PUBLIC cnv2_mainloop_ryzen_asm +PUBLIC cnv2_double_mainloop_sandybridge_asm + +ALIGN 64 +cnv2_mainloop_ivybridge_asm PROC + INCLUDE cnv2_main_loop_ivybridge.inc + ret 0 +cnv2_mainloop_ivybridge_asm ENDP + +ALIGN 64 +cnv2_mainloop_ryzen_asm PROC + INCLUDE cnv2_main_loop_ryzen.inc + ret 0 +cnv2_mainloop_ryzen_asm ENDP + +ALIGN 64 +cnv2_double_mainloop_sandybridge_asm PROC + INCLUDE cnv2_double_main_loop_sandybridge.inc + ret 0 +cnv2_double_mainloop_sandybridge_asm ENDP + +_TEXT_CNV2_MAINLOOP ENDS +END diff --git a/src/crypto/asm/cnv2_main_loop_ivybridge.inc b/src/crypto/asm/cnv2_main_loop_ivybridge.inc new file mode 100644 index 00000000..8c2c2d3b --- /dev/null +++ b/src/crypto/asm/cnv2_main_loop_ivybridge.inc @@ -0,0 +1,186 @@ + mov QWORD PTR [rsp+24], rbx + push rbp + push rsi + push rdi + push r12 + push r13 + push r14 + push r15 + sub rsp, 80 + + stmxcsr DWORD PTR [rsp] + mov DWORD PTR [rsp+4], 24448 + ldmxcsr DWORD PTR [rsp+4] + + mov rax, QWORD PTR [rcx+48] + mov r9, rcx + xor rax, QWORD PTR [rcx+16] + mov esi, 524288 + mov r8, QWORD PTR [rcx+32] + mov r13d, -2147483647 + xor r8, QWORD PTR [rcx] + mov r11, QWORD PTR [rcx+40] + mov r10, r8 + mov rdx, QWORD PTR [rcx+56] + movq xmm4, rax + xor rdx, QWORD PTR [rcx+24] + xor r11, QWORD PTR [rcx+8] + mov rbx, QWORD PTR [rcx+224] + mov rax, QWORD PTR [r9+80] + xor rax, QWORD PTR [r9+64] + movq xmm0, rdx + mov rcx, QWORD PTR [rcx+88] + xor rcx, QWORD PTR [r9+72] + movq xmm3, QWORD PTR [r9+104] + movaps XMMWORD PTR [rsp+64], xmm6 + movaps XMMWORD PTR [rsp+48], xmm7 + movaps XMMWORD PTR [rsp+32], xmm8 + and r10d, 2097136 + movq xmm5, rax + + xor eax, eax + mov QWORD PTR [rsp+16], rax + + mov ax, 1023 + shl rax, 52 + movq xmm8, rax + mov r15, QWORD PTR [r9+96] + punpcklqdq xmm4, xmm0 + movq xmm0, rcx + punpcklqdq xmm5, xmm0 + movdqu xmm6, XMMWORD PTR [r10+rbx] + + ALIGN 16 +main_loop_ivybridge: + lea rdx, QWORD PTR [r10+rbx] + mov ecx, r10d + mov eax, r10d + mov rdi, r15 + xor ecx, 16 + xor eax, 32 + xor r10d, 48 + movq xmm0, r11 + movq xmm7, r8 + punpcklqdq xmm7, xmm0 + aesenc xmm6, xmm7 + movq rbp, xmm6 + mov r9, rbp + and r9d, 2097136 + movdqu xmm2, XMMWORD PTR [rcx+rbx] + movdqu xmm1, XMMWORD PTR [rax+rbx] + movdqu xmm0, XMMWORD PTR [r10+rbx] + paddq xmm1, xmm7 + paddq xmm0, xmm5 + paddq xmm2, xmm4 + movdqu XMMWORD PTR [rcx+rbx], xmm0 + movdqu XMMWORD PTR [rax+rbx], xmm2 + movdqu XMMWORD PTR [r10+rbx], xmm1 + mov r10, r9 + xor r10d, 32 + movq rcx, xmm3 + mov rax, rcx + shl rax, 32 + xor rdi, rax + movdqa xmm0, xmm6 + pxor xmm0, xmm4 + movdqu XMMWORD PTR [rdx], xmm0 + xor rdi, QWORD PTR [r9+rbx] + lea r14, QWORD PTR [r9+rbx] + mov r12, QWORD PTR [r14+8] + xor edx, edx + lea r9d, DWORD PTR [ecx+ecx] + add r9d, ebp + movdqa xmm0, xmm6 + psrldq xmm0, 8 + or r9d, r13d + movq rax, xmm0 + div r9 + xorps xmm3, xmm3 + mov eax, eax + shl rdx, 32 + add rdx, rax + lea r9, QWORD PTR [rdx+rbp] + mov r15, rdx + mov rax, r9 + shr rax, 12 + movq xmm0, rax + paddq xmm0, xmm8 + sqrtsd xmm3, xmm0 + psubq xmm3, XMMWORD PTR [rsp+16] + movq rdx, xmm3 + test edx, 524287 + je sqrt_fixup_ivybridge + psrlq xmm3, 19 +sqrt_fixup_ivybridge_ret: + + mov ecx, r10d + mov rax, rdi + mul rbp + movq xmm2, rdx + xor rdx, [rcx+rbx] + add r8, rdx + mov QWORD PTR [r14], r8 + xor r8, rdi + mov edi, r8d + and edi, 2097136 + movq xmm0, rax + xor rax, [rcx+rbx+8] + add r11, rax + mov QWORD PTR [r14+8], r11 + punpcklqdq xmm2, xmm0 + + mov r9d, r10d + xor r9d, 48 + xor r10d, 16 + pxor xmm2, XMMWORD PTR [r9+rbx] + movdqu xmm0, XMMWORD PTR [r10+rbx] + paddq xmm0, xmm5 + movdqu xmm1, XMMWORD PTR [rcx+rbx] + paddq xmm2, xmm4 + paddq xmm1, xmm7 + movdqa xmm5, xmm4 + movdqu XMMWORD PTR [r9+rbx], xmm0 + movdqa xmm4, xmm6 + movdqu XMMWORD PTR [rcx+rbx], xmm2 + movdqu XMMWORD PTR [r10+rbx], xmm1 + movdqu xmm6, [rdi+rbx] + mov r10d, edi + xor r11, r12 + dec rsi + jne main_loop_ivybridge + + ldmxcsr DWORD PTR [rsp] + mov rbx, QWORD PTR [rsp+160] + movaps xmm6, XMMWORD PTR [rsp+64] + movaps xmm7, XMMWORD PTR [rsp+48] + movaps xmm8, XMMWORD PTR [rsp+32] + add rsp, 80 + pop r15 + pop r14 + pop r13 + pop r12 + pop rdi + pop rsi + pop rbp + jmp cnv2_main_loop_ivybridge_endp + +sqrt_fixup_ivybridge: + dec rdx + mov r13d, -1022 + shl r13, 32 + mov rax, rdx + shr rdx, 19 + shr rax, 20 + mov rcx, rdx + sub rcx, rax + add rax, r13 + not r13 + sub rcx, r13 + mov r13d, -2147483647 + imul rcx, rax + sub rcx, r9 + adc rdx, 0 + movq xmm3, rdx + jmp sqrt_fixup_ivybridge_ret + +cnv2_main_loop_ivybridge_endp: diff --git a/src/crypto/asm/cnv2_main_loop_ryzen.inc b/src/crypto/asm/cnv2_main_loop_ryzen.inc new file mode 100644 index 00000000..d386aa2d --- /dev/null +++ b/src/crypto/asm/cnv2_main_loop_ryzen.inc @@ -0,0 +1,179 @@ + mov QWORD PTR [rsp+16], rbx + mov QWORD PTR [rsp+24], rbp + mov QWORD PTR [rsp+32], rsi + push rdi + push r12 + push r13 + push r14 + push r15 + sub rsp, 64 + + stmxcsr DWORD PTR [rsp] + mov DWORD PTR [rsp+4], 24448 + ldmxcsr DWORD PTR [rsp+4] + + mov rax, QWORD PTR [rcx+48] + mov r9, rcx + xor rax, QWORD PTR [rcx+16] + mov ebp, 524288 + mov r8, QWORD PTR [rcx+32] + xor r8, QWORD PTR [rcx] + mov r11, QWORD PTR [rcx+40] + mov r10, r8 + mov rdx, QWORD PTR [rcx+56] + movq xmm3, rax + xor rdx, QWORD PTR [rcx+24] + xor r11, QWORD PTR [rcx+8] + mov rbx, QWORD PTR [rcx+224] + mov rax, QWORD PTR [r9+80] + xor rax, QWORD PTR [r9+64] + movq xmm0, rdx + mov rcx, QWORD PTR [rcx+88] + xor rcx, QWORD PTR [r9+72] + mov rdi, QWORD PTR [r9+104] + and r10d, 2097136 + movaps XMMWORD PTR [rsp+48], xmm6 + movq xmm4, rax + movaps XMMWORD PTR [rsp+32], xmm7 + movaps XMMWORD PTR [rsp+16], xmm8 + xorps xmm8, xmm8 + mov ax, 1023 + shl rax, 52 + movq xmm7, rax + mov r15, QWORD PTR [r9+96] + punpcklqdq xmm3, xmm0 + movq xmm0, rcx + punpcklqdq xmm4, xmm0 + + ALIGN 16 +main_loop_ryzen: + movdqa xmm5, XMMWORD PTR [r10+rbx] + movq xmm0, r11 + movq xmm6, r8 + punpcklqdq xmm6, xmm0 + lea rdx, QWORD PTR [r10+rbx] + lea r9, QWORD PTR [rdi+rdi] + shl rdi, 32 + + mov ecx, r10d + mov eax, r10d + xor ecx, 16 + xor eax, 32 + xor r10d, 48 + aesenc xmm5, xmm6 + movdqa xmm2, XMMWORD PTR [rcx+rbx] + movdqa xmm1, XMMWORD PTR [rax+rbx] + movdqa xmm0, XMMWORD PTR [r10+rbx] + paddq xmm2, xmm3 + paddq xmm1, xmm6 + paddq xmm0, xmm4 + movdqa XMMWORD PTR [rcx+rbx], xmm0 + movdqa XMMWORD PTR [rax+rbx], xmm2 + movdqa XMMWORD PTR [r10+rbx], xmm1 + + movaps xmm1, xmm8 + mov rsi, r15 + xor rsi, rdi + movq r14, xmm5 + movdqa xmm0, xmm5 + pxor xmm0, xmm3 + mov r10, r14 + and r10d, 2097136 + movdqa XMMWORD PTR [rdx], xmm0 + xor rsi, QWORD PTR [r10+rbx] + lea r12, QWORD PTR [r10+rbx] + mov r13, QWORD PTR [r10+rbx+8] + + add r9d, r14d + or r9d, -2147483647 + xor edx, edx + movdqa xmm0, xmm5 + psrldq xmm0, 8 + movq rax, xmm0 + + div r9 + movq xmm0, rax + movq xmm1, rdx + punpckldq xmm0, xmm1 + movq r15, xmm0 + paddq xmm0, xmm5 + movdqa xmm2, xmm0 + psrlq xmm0, 12 + paddq xmm0, xmm7 + sqrtsd xmm1, xmm0 + movq rdi, xmm1 + test rdi, 524287 + je sqrt_fixup_ryzen + shr rdi, 19 + +sqrt_fixup_ryzen_ret: + mov rax, rsi + mul r14 + movq xmm1, rax + movq xmm0, rdx + punpcklqdq xmm0, xmm1 + + mov r9d, r10d + mov ecx, r10d + xor r9d, 16 + xor ecx, 32 + xor r10d, 48 + movdqa xmm1, XMMWORD PTR [rcx+rbx] + xor rdx, [rcx+rbx] + xor rax, [rcx+rbx+8] + movdqa xmm2, XMMWORD PTR [r9+rbx] + pxor xmm2, xmm0 + paddq xmm4, XMMWORD PTR [r10+rbx] + paddq xmm2, xmm3 + paddq xmm1, xmm6 + movdqa XMMWORD PTR [r9+rbx], xmm4 + movdqa XMMWORD PTR [rcx+rbx], xmm2 + movdqa XMMWORD PTR [r10+rbx], xmm1 + + movdqa xmm4, xmm3 + add r8, rdx + add r11, rax + mov QWORD PTR [r12], r8 + xor r8, rsi + mov QWORD PTR [r12+8], r11 + mov r10, r8 + xor r11, r13 + and r10d, 2097136 + movdqa xmm3, xmm5 + dec ebp + jne main_loop_ryzen + + ldmxcsr DWORD PTR [rsp] + movaps xmm6, XMMWORD PTR [rsp+48] + lea r11, QWORD PTR [rsp+64] + mov rbx, QWORD PTR [r11+56] + mov rbp, QWORD PTR [r11+64] + mov rsi, QWORD PTR [r11+72] + movaps xmm8, XMMWORD PTR [r11-48] + movaps xmm7, XMMWORD PTR [rsp+32] + mov rsp, r11 + pop r15 + pop r14 + pop r13 + pop r12 + pop rdi + jmp cnv2_main_loop_ryzen_endp + +sqrt_fixup_ryzen: + movq r9, xmm2 + dec rdi + mov edx, -1022 + shl rdx, 32 + mov rax, rdi + shr rdi, 19 + shr rax, 20 + mov rcx, rdi + sub rcx, rax + lea rcx, [rcx+rdx+1] + add rax, rdx + imul rcx, rax + sub rcx, r9 + adc rdi, 0 + jmp sqrt_fixup_ryzen_ret + +cnv2_main_loop_ryzen_endp: diff --git a/src/crypto/asm/win64/cnv2_double_main_loop_sandybridge.inc b/src/crypto/asm/win64/cnv2_double_main_loop_sandybridge.inc new file mode 100644 index 00000000..44ea8923 --- /dev/null +++ b/src/crypto/asm/win64/cnv2_double_main_loop_sandybridge.inc @@ -0,0 +1,410 @@ + mov rax, rsp + push rbx + push rbp + push rsi + push rdi + push r12 + push r13 + push r14 + push r15 + sub rsp, 184 + + stmxcsr DWORD PTR [rsp+272] + mov DWORD PTR [rsp+276], 24448 + ldmxcsr DWORD PTR [rsp+276] + + mov r13, QWORD PTR [rcx+224] + mov r9, rdx + mov r10, QWORD PTR [rcx+32] + mov r8, rcx + xor r10, QWORD PTR [rcx] + mov r14d, 524288 + mov r11, QWORD PTR [rcx+40] + xor r11, QWORD PTR [rcx+8] + mov rsi, QWORD PTR [rdx+224] + mov rdx, QWORD PTR [rcx+56] + xor rdx, QWORD PTR [rcx+24] + mov rdi, QWORD PTR [r9+32] + xor rdi, QWORD PTR [r9] + mov rbp, QWORD PTR [r9+40] + xor rbp, QWORD PTR [r9+8] + movd xmm0, rdx + movaps XMMWORD PTR [rax-88], xmm6 + movaps XMMWORD PTR [rax-104], xmm7 + movaps XMMWORD PTR [rax-120], xmm8 + movaps XMMWORD PTR [rsp+112], xmm9 + movaps XMMWORD PTR [rsp+96], xmm10 + movaps XMMWORD PTR [rsp+80], xmm11 + movaps XMMWORD PTR [rsp+64], xmm12 + movaps XMMWORD PTR [rsp+48], xmm13 + movaps XMMWORD PTR [rsp+32], xmm14 + movaps XMMWORD PTR [rsp+16], xmm15 + mov rdx, r10 + movd xmm4, QWORD PTR [r8+96] + and edx, 2097136 + mov rax, QWORD PTR [rcx+48] + xorps xmm13, xmm13 + xor rax, QWORD PTR [rcx+16] + mov rcx, QWORD PTR [rcx+88] + xor rcx, QWORD PTR [r8+72] + movd xmm5, QWORD PTR [r8+104] + movd xmm7, rax + + mov eax, 1 + shl rax, 52 + movd xmm14, rax + punpcklqdq xmm14, xmm14 + + mov eax, 1023 + shl rax, 52 + movd xmm12, rax + punpcklqdq xmm12, xmm12 + + mov rax, QWORD PTR [r8+80] + xor rax, QWORD PTR [r8+64] + punpcklqdq xmm7, xmm0 + movd xmm0, rcx + mov rcx, QWORD PTR [r9+56] + xor rcx, QWORD PTR [r9+24] + movd xmm3, rax + mov rax, QWORD PTR [r9+48] + xor rax, QWORD PTR [r9+16] + punpcklqdq xmm3, xmm0 + movd xmm0, rcx + mov QWORD PTR [rsp], r13 + mov rcx, QWORD PTR [r9+88] + xor rcx, QWORD PTR [r9+72] + movd xmm6, rax + mov rax, QWORD PTR [r9+80] + xor rax, QWORD PTR [r9+64] + punpcklqdq xmm6, xmm0 + movd xmm0, rcx + mov QWORD PTR [rsp+256], r10 + mov rcx, rdi + mov QWORD PTR [rsp+264], r11 + movd xmm8, rax + and ecx, 2097136 + punpcklqdq xmm8, xmm0 + movd xmm0, QWORD PTR [r9+96] + punpcklqdq xmm4, xmm0 + movd xmm0, QWORD PTR [r9+104] + lea r8, QWORD PTR [rcx+rsi] + movdqu xmm11, XMMWORD PTR [r8] + punpcklqdq xmm5, xmm0 + lea r9, QWORD PTR [rdx+r13] + movdqu xmm15, XMMWORD PTR [r9] + + ALIGN 16 +main_loop_double_sandybridge: + movdqu xmm9, xmm15 + mov eax, edx + mov ebx, edx + xor eax, 16 + xor ebx, 32 + xor edx, 48 + + movd xmm0, r11 + movd xmm2, r10 + punpcklqdq xmm2, xmm0 + aesenc xmm9, xmm2 + + movdqu xmm0, XMMWORD PTR [rax+r13] + movdqu xmm1, XMMWORD PTR [rbx+r13] + paddq xmm0, xmm7 + paddq xmm1, xmm2 + movdqu XMMWORD PTR [rbx+r13], xmm0 + movdqu xmm0, XMMWORD PTR [rdx+r13] + movdqu XMMWORD PTR [rdx+r13], xmm1 + paddq xmm0, xmm3 + movdqu XMMWORD PTR [rax+r13], xmm0 + + movd r11, xmm9 + mov edx, r11d + and edx, 2097136 + movdqa xmm0, xmm9 + pxor xmm0, xmm7 + movdqu XMMWORD PTR [r9], xmm0 + + lea rbx, QWORD PTR [rdx+r13] + mov r10, QWORD PTR [rdx+r13] + + movdqu xmm10, xmm11 + movd xmm0, rbp + movd xmm11, rdi + punpcklqdq xmm11, xmm0 + aesenc xmm10, xmm11 + + mov eax, ecx + mov r12d, ecx + xor eax, 16 + xor r12d, 32 + xor ecx, 48 + + movdqu xmm0, XMMWORD PTR [rax+rsi] + paddq xmm0, xmm6 + movdqu xmm1, XMMWORD PTR [r12+rsi] + movdqu XMMWORD PTR [r12+rsi], xmm0 + paddq xmm1, xmm11 + movdqu xmm0, XMMWORD PTR [rcx+rsi] + movdqu XMMWORD PTR [rcx+rsi], xmm1 + paddq xmm0, xmm8 + movdqu XMMWORD PTR [rax+rsi], xmm0 + + movd rcx, xmm10 + and ecx, 2097136 + + movdqa xmm0, xmm10 + pxor xmm0, xmm6 + movdqu XMMWORD PTR [r8], xmm0 + mov r12, QWORD PTR [rcx+rsi] + + mov r9, QWORD PTR [rbx+8] + + xor edx, 16 + mov r8d, edx + mov r15d, edx + + movd rdx, xmm5 + shl rdx, 32 + movd rax, xmm4 + xor rdx, rax + xor r10, rdx + mov rax, r10 + mul r11 + mov r11d, r8d + xor r11d, 48 + movd xmm0, rdx + xor rdx, [r11+r13] + movd xmm1, rax + xor rax, [r11+r13+8] + punpcklqdq xmm0, xmm1 + + pxor xmm0, XMMWORD PTR [r8+r13] + xor r8d, 32 + movdqu xmm1, XMMWORD PTR [r11+r13] + paddq xmm0, xmm7 + paddq xmm1, xmm2 + movdqu XMMWORD PTR [r11+r13], xmm0 + movdqu xmm0, XMMWORD PTR [r8+r13] + movdqu XMMWORD PTR [r8+r13], xmm1 + paddq xmm0, xmm3 + movdqu XMMWORD PTR [r15+r13], xmm0 + + mov r11, QWORD PTR [rsp+256] + add r11, rdx + mov rdx, QWORD PTR [rsp+264] + add rdx, rax + mov QWORD PTR [rbx], r11 + xor r11, r10 + mov QWORD PTR [rbx+8], rdx + xor rdx, r9 + mov QWORD PTR [rsp+256], r11 + and r11d, 2097136 + mov QWORD PTR [rsp+264], rdx + mov QWORD PTR [rsp+8], r11 + lea r15, QWORD PTR [r11+r13] + movdqu xmm15, XMMWORD PTR [r11+r13] + lea r13, QWORD PTR [rsi+rcx] + movdqa xmm0, xmm5 + psrldq xmm0, 8 + movaps xmm2, xmm13 + movd r10, xmm0 + psllq xmm5, 1 + shl r10, 32 + movdqa xmm0, xmm9 + psrldq xmm0, 8 + movdqa xmm1, xmm10 + movd r11, xmm0 + psrldq xmm1, 8 + movd r8, xmm1 + psrldq xmm4, 8 + movaps xmm0, xmm13 + movd rax, xmm4 + xor r10, rax + movaps xmm1, xmm13 + xor r10, r12 + lea rax, QWORD PTR [r11+1] + shr rax, 1 + movdqa xmm3, xmm9 + punpcklqdq xmm3, xmm10 + paddq xmm5, xmm3 + movd rdx, xmm5 + psrldq xmm5, 8 + cvtsi2sd xmm2, rax + or edx, -2147483647 + lea rax, QWORD PTR [r8+1] + shr rax, 1 + movd r9, xmm5 + cvtsi2sd xmm0, rax + or r9d, -2147483647 + cvtsi2sd xmm1, rdx + unpcklpd xmm2, xmm0 + movaps xmm0, xmm13 + cvtsi2sd xmm0, r9 + unpcklpd xmm1, xmm0 + divpd xmm2, xmm1 + paddq xmm2, xmm14 + cvttsd2si rax, xmm2 + psrldq xmm2, 8 + mov rbx, rax + imul rax, rdx + sub r11, rax + js div_fix_1_sandybridge +div_fix_1_ret_sandybridge: + + cvttsd2si rdx, xmm2 + mov rax, rdx + imul rax, r9 + movd xmm2, r11d + movd xmm4, ebx + sub r8, rax + js div_fix_2_sandybridge +div_fix_2_ret_sandybridge: + + movd xmm1, r8d + movd xmm0, edx + punpckldq xmm2, xmm1 + punpckldq xmm4, xmm0 + punpckldq xmm4, xmm2 + paddq xmm3, xmm4 + movdqa xmm0, xmm3 + psrlq xmm0, 12 + paddq xmm0, xmm12 + sqrtpd xmm1, xmm0 + movd r9, xmm1 + movdqa xmm5, xmm1 + psrlq xmm5, 19 + test r9, 524287 + je sqrt_fix_1_sandybridge +sqrt_fix_1_ret_sandybridge: + + movd r9, xmm10 + psrldq xmm1, 8 + movd r8, xmm1 + test r8, 524287 + je sqrt_fix_2_sandybridge +sqrt_fix_2_ret_sandybridge: + + mov r12d, ecx + mov r8d, ecx + xor r12d, 16 + xor r8d, 32 + xor ecx, 48 + mov rax, r10 + mul r9 + movd xmm0, rax + movd xmm3, rdx + punpcklqdq xmm3, xmm0 + + movdqu xmm0, XMMWORD PTR [r12+rsi] + pxor xmm0, xmm3 + movdqu xmm1, XMMWORD PTR [r8+rsi] + xor rdx, [r8+rsi] + xor rax, [r8+rsi+8] + movdqu xmm3, XMMWORD PTR [rcx+rsi] + paddq xmm0, xmm6 + paddq xmm1, xmm11 + paddq xmm3, xmm8 + movdqu XMMWORD PTR [r8+rsi], xmm0 + movdqu XMMWORD PTR [rcx+rsi], xmm1 + movdqu XMMWORD PTR [r12+rsi], xmm3 + + add rdi, rdx + mov QWORD PTR [r13], rdi + xor rdi, r10 + mov ecx, edi + and ecx, 2097136 + lea r8, QWORD PTR [rcx+rsi] + + mov rdx, QWORD PTR [r13+8] + add rbp, rax + mov QWORD PTR [r13+8], rbp + movdqu xmm11, XMMWORD PTR [rcx+rsi] + xor rbp, rdx + mov r13, QWORD PTR [rsp] + movdqa xmm3, xmm7 + mov rdx, QWORD PTR [rsp+8] + movdqa xmm8, xmm6 + mov r10, QWORD PTR [rsp+256] + movdqa xmm7, xmm9 + mov r11, QWORD PTR [rsp+264] + movdqa xmm6, xmm10 + mov r9, r15 + dec r14d + jne main_loop_double_sandybridge + + ldmxcsr DWORD PTR [rsp+272] + movaps xmm13, XMMWORD PTR [rsp+48] + lea r11, QWORD PTR [rsp+184] + movaps xmm6, XMMWORD PTR [r11-24] + movaps xmm7, XMMWORD PTR [r11-40] + movaps xmm8, XMMWORD PTR [r11-56] + movaps xmm9, XMMWORD PTR [r11-72] + movaps xmm10, XMMWORD PTR [r11-88] + movaps xmm11, XMMWORD PTR [r11-104] + movaps xmm12, XMMWORD PTR [r11-120] + movaps xmm14, XMMWORD PTR [rsp+32] + movaps xmm15, XMMWORD PTR [rsp+16] + mov rsp, r11 + pop r15 + pop r14 + pop r13 + pop r12 + pop rdi + pop rsi + pop rbp + pop rbx + jmp cnv2_double_mainloop_asm_sandybridge_endp + +div_fix_1_sandybridge: + dec rbx + add r11, rdx + jmp div_fix_1_ret_sandybridge + +div_fix_2_sandybridge: + dec rdx + add r8, r9 + jmp div_fix_2_ret_sandybridge + +sqrt_fix_1_sandybridge: + movd r8, xmm3 + movdqa xmm0, xmm5 + psrldq xmm0, 8 + dec r9 + mov r11d, -1022 + shl r11, 32 + mov rax, r9 + shr r9, 19 + shr rax, 20 + mov rdx, r9 + sub rdx, rax + lea rdx, [rdx+r11+1] + add rax, r11 + imul rdx, rax + sub rdx, r8 + adc r9, 0 + movd xmm5, r9 + punpcklqdq xmm5, xmm0 + jmp sqrt_fix_1_ret_sandybridge + +sqrt_fix_2_sandybridge: + psrldq xmm3, 8 + movd r11, xmm3 + dec r8 + mov ebx, -1022 + shl rbx, 32 + mov rax, r8 + shr r8, 19 + shr rax, 20 + mov rdx, r8 + sub rdx, rax + lea rdx, [rdx+rbx+1] + add rax, rbx + imul rdx, rax + sub rdx, r11 + adc r8, 0 + movd xmm0, r8 + punpcklqdq xmm5, xmm0 + jmp sqrt_fix_2_ret_sandybridge + +cnv2_double_mainloop_asm_sandybridge_endp: diff --git a/src/crypto/asm/win64/cnv2_main_loop.S b/src/crypto/asm/win64/cnv2_main_loop.S new file mode 100644 index 00000000..78eb1185 --- /dev/null +++ b/src/crypto/asm/win64/cnv2_main_loop.S @@ -0,0 +1,21 @@ +#define ALIGN .align +.intel_syntax noprefix +.section .text +.global cnv2_mainloop_ivybridge_asm +.global cnv2_mainloop_ryzen_asm +.global cnv2_double_mainloop_sandybridge_asm + +ALIGN 16 +cnv2_mainloop_ivybridge_asm: + #include "../cnv2_main_loop_ivybridge.inc" + ret 0 + +ALIGN 16 +cnv2_mainloop_ryzen_asm: + #include "../cnv2_main_loop_ryzen.inc" + ret 0 + +ALIGN 16 +cnv2_double_mainloop_sandybridge_asm: + #include "../cnv2_double_main_loop_sandybridge.inc" + ret 0 diff --git a/src/crypto/asm/win64/cnv2_main_loop.asm b/src/crypto/asm/win64/cnv2_main_loop.asm new file mode 100644 index 00000000..d9522267 --- /dev/null +++ b/src/crypto/asm/win64/cnv2_main_loop.asm @@ -0,0 +1,25 @@ +_TEXT_CNV2_MAINLOOP SEGMENT PAGE READ EXECUTE +PUBLIC cnv2_mainloop_ivybridge_asm +PUBLIC cnv2_mainloop_ryzen_asm +PUBLIC cnv2_double_mainloop_sandybridge_asm + +ALIGN 64 +cnv2_mainloop_ivybridge_asm PROC + INCLUDE cnv2_main_loop_ivybridge.inc + ret 0 +cnv2_mainloop_ivybridge_asm ENDP + +ALIGN 64 +cnv2_mainloop_ryzen_asm PROC + INCLUDE cnv2_main_loop_ryzen.inc + ret 0 +cnv2_mainloop_ryzen_asm ENDP + +ALIGN 64 +cnv2_double_mainloop_sandybridge_asm PROC + INCLUDE cnv2_double_main_loop_sandybridge.inc + ret 0 +cnv2_double_mainloop_sandybridge_asm ENDP + +_TEXT_CNV2_MAINLOOP ENDS +END diff --git a/src/crypto/asm/win64/cnv2_main_loop_ivybridge.inc b/src/crypto/asm/win64/cnv2_main_loop_ivybridge.inc new file mode 100644 index 00000000..c925ca24 --- /dev/null +++ b/src/crypto/asm/win64/cnv2_main_loop_ivybridge.inc @@ -0,0 +1,186 @@ + mov QWORD PTR [rsp+24], rbx + push rbp + push rsi + push rdi + push r12 + push r13 + push r14 + push r15 + sub rsp, 80 + + stmxcsr DWORD PTR [rsp] + mov DWORD PTR [rsp+4], 24448 + ldmxcsr DWORD PTR [rsp+4] + + mov rax, QWORD PTR [rcx+48] + mov r9, rcx + xor rax, QWORD PTR [rcx+16] + mov esi, 524288 + mov r8, QWORD PTR [rcx+32] + mov r13d, -2147483647 + xor r8, QWORD PTR [rcx] + mov r11, QWORD PTR [rcx+40] + mov r10, r8 + mov rdx, QWORD PTR [rcx+56] + movd xmm4, rax + xor rdx, QWORD PTR [rcx+24] + xor r11, QWORD PTR [rcx+8] + mov rbx, QWORD PTR [rcx+224] + mov rax, QWORD PTR [r9+80] + xor rax, QWORD PTR [r9+64] + movd xmm0, rdx + mov rcx, QWORD PTR [rcx+88] + xor rcx, QWORD PTR [r9+72] + movd xmm3, QWORD PTR [r9+104] + movaps XMMWORD PTR [rsp+64], xmm6 + movaps XMMWORD PTR [rsp+48], xmm7 + movaps XMMWORD PTR [rsp+32], xmm8 + and r10d, 2097136 + movd xmm5, rax + + xor eax, eax + mov QWORD PTR [rsp+16], rax + + mov ax, 1023 + shl rax, 52 + movd xmm8, rax + mov r15, QWORD PTR [r9+96] + punpcklqdq xmm4, xmm0 + movd xmm0, rcx + punpcklqdq xmm5, xmm0 + movdqu xmm6, XMMWORD PTR [r10+rbx] + + ALIGN 16 +main_loop_ivybridge: + lea rdx, QWORD PTR [r10+rbx] + mov ecx, r10d + mov eax, r10d + mov rdi, r15 + xor ecx, 16 + xor eax, 32 + xor r10d, 48 + movd xmm0, r11 + movd xmm7, r8 + punpcklqdq xmm7, xmm0 + aesenc xmm6, xmm7 + movd rbp, xmm6 + mov r9, rbp + and r9d, 2097136 + movdqu xmm2, XMMWORD PTR [rcx+rbx] + movdqu xmm1, XMMWORD PTR [rax+rbx] + movdqu xmm0, XMMWORD PTR [r10+rbx] + paddq xmm1, xmm7 + paddq xmm0, xmm5 + paddq xmm2, xmm4 + movdqu XMMWORD PTR [rcx+rbx], xmm0 + movdqu XMMWORD PTR [rax+rbx], xmm2 + movdqu XMMWORD PTR [r10+rbx], xmm1 + mov r10, r9 + xor r10d, 32 + movd rcx, xmm3 + mov rax, rcx + shl rax, 32 + xor rdi, rax + movdqa xmm0, xmm6 + pxor xmm0, xmm4 + movdqu XMMWORD PTR [rdx], xmm0 + xor rdi, QWORD PTR [r9+rbx] + lea r14, QWORD PTR [r9+rbx] + mov r12, QWORD PTR [r14+8] + xor edx, edx + lea r9d, DWORD PTR [ecx+ecx] + add r9d, ebp + movdqa xmm0, xmm6 + psrldq xmm0, 8 + or r9d, r13d + movd rax, xmm0 + div r9 + xorps xmm3, xmm3 + mov eax, eax + shl rdx, 32 + add rdx, rax + lea r9, QWORD PTR [rdx+rbp] + mov r15, rdx + mov rax, r9 + shr rax, 12 + movd xmm0, rax + paddq xmm0, xmm8 + sqrtsd xmm3, xmm0 + psubq xmm3, XMMWORD PTR [rsp+16] + movd rdx, xmm3 + test edx, 524287 + je sqrt_fixup_ivybridge + psrlq xmm3, 19 +sqrt_fixup_ivybridge_ret: + + mov ecx, r10d + mov rax, rdi + mul rbp + movd xmm2, rdx + xor rdx, [rcx+rbx] + add r8, rdx + mov QWORD PTR [r14], r8 + xor r8, rdi + mov edi, r8d + and edi, 2097136 + movd xmm0, rax + xor rax, [rcx+rbx+8] + add r11, rax + mov QWORD PTR [r14+8], r11 + punpcklqdq xmm2, xmm0 + + mov r9d, r10d + xor r9d, 48 + xor r10d, 16 + pxor xmm2, XMMWORD PTR [r9+rbx] + movdqu xmm0, XMMWORD PTR [r10+rbx] + paddq xmm0, xmm5 + movdqu xmm1, XMMWORD PTR [rcx+rbx] + paddq xmm2, xmm4 + paddq xmm1, xmm7 + movdqa xmm5, xmm4 + movdqu XMMWORD PTR [r9+rbx], xmm0 + movdqa xmm4, xmm6 + movdqu XMMWORD PTR [rcx+rbx], xmm2 + movdqu XMMWORD PTR [r10+rbx], xmm1 + movdqu xmm6, [rdi+rbx] + mov r10d, edi + xor r11, r12 + dec rsi + jne main_loop_ivybridge + + ldmxcsr DWORD PTR [rsp] + mov rbx, QWORD PTR [rsp+160] + movaps xmm6, XMMWORD PTR [rsp+64] + movaps xmm7, XMMWORD PTR [rsp+48] + movaps xmm8, XMMWORD PTR [rsp+32] + add rsp, 80 + pop r15 + pop r14 + pop r13 + pop r12 + pop rdi + pop rsi + pop rbp + jmp cnv2_main_loop_ivybridge_endp + +sqrt_fixup_ivybridge: + dec rdx + mov r13d, -1022 + shl r13, 32 + mov rax, rdx + shr rdx, 19 + shr rax, 20 + mov rcx, rdx + sub rcx, rax + add rax, r13 + not r13 + sub rcx, r13 + mov r13d, -2147483647 + imul rcx, rax + sub rcx, r9 + adc rdx, 0 + movd xmm3, rdx + jmp sqrt_fixup_ivybridge_ret + +cnv2_main_loop_ivybridge_endp: diff --git a/src/crypto/asm/win64/cnv2_main_loop_ryzen.inc b/src/crypto/asm/win64/cnv2_main_loop_ryzen.inc new file mode 100644 index 00000000..d1cd26c4 --- /dev/null +++ b/src/crypto/asm/win64/cnv2_main_loop_ryzen.inc @@ -0,0 +1,179 @@ + mov QWORD PTR [rsp+16], rbx + mov QWORD PTR [rsp+24], rbp + mov QWORD PTR [rsp+32], rsi + push rdi + push r12 + push r13 + push r14 + push r15 + sub rsp, 64 + + stmxcsr DWORD PTR [rsp] + mov DWORD PTR [rsp+4], 24448 + ldmxcsr DWORD PTR [rsp+4] + + mov rax, QWORD PTR [rcx+48] + mov r9, rcx + xor rax, QWORD PTR [rcx+16] + mov ebp, 524288 + mov r8, QWORD PTR [rcx+32] + xor r8, QWORD PTR [rcx] + mov r11, QWORD PTR [rcx+40] + mov r10, r8 + mov rdx, QWORD PTR [rcx+56] + movd xmm3, rax + xor rdx, QWORD PTR [rcx+24] + xor r11, QWORD PTR [rcx+8] + mov rbx, QWORD PTR [rcx+224] + mov rax, QWORD PTR [r9+80] + xor rax, QWORD PTR [r9+64] + movd xmm0, rdx + mov rcx, QWORD PTR [rcx+88] + xor rcx, QWORD PTR [r9+72] + mov rdi, QWORD PTR [r9+104] + and r10d, 2097136 + movaps XMMWORD PTR [rsp+48], xmm6 + movd xmm4, rax + movaps XMMWORD PTR [rsp+32], xmm7 + movaps XMMWORD PTR [rsp+16], xmm8 + xorps xmm8, xmm8 + mov ax, 1023 + shl rax, 52 + movd xmm7, rax + mov r15, QWORD PTR [r9+96] + punpcklqdq xmm3, xmm0 + movd xmm0, rcx + punpcklqdq xmm4, xmm0 + + ALIGN 16 +main_loop_ryzen: + movdqa xmm5, XMMWORD PTR [r10+rbx] + movd xmm0, r11 + movd xmm6, r8 + punpcklqdq xmm6, xmm0 + lea rdx, QWORD PTR [r10+rbx] + lea r9, QWORD PTR [rdi+rdi] + shl rdi, 32 + + mov ecx, r10d + mov eax, r10d + xor ecx, 16 + xor eax, 32 + xor r10d, 48 + aesenc xmm5, xmm6 + movdqa xmm2, XMMWORD PTR [rcx+rbx] + movdqa xmm1, XMMWORD PTR [rax+rbx] + movdqa xmm0, XMMWORD PTR [r10+rbx] + paddq xmm2, xmm3 + paddq xmm1, xmm6 + paddq xmm0, xmm4 + movdqa XMMWORD PTR [rcx+rbx], xmm0 + movdqa XMMWORD PTR [rax+rbx], xmm2 + movdqa XMMWORD PTR [r10+rbx], xmm1 + + movaps xmm1, xmm8 + mov rsi, r15 + xor rsi, rdi + movd r14, xmm5 + movdqa xmm0, xmm5 + pxor xmm0, xmm3 + mov r10, r14 + and r10d, 2097136 + movdqa XMMWORD PTR [rdx], xmm0 + xor rsi, QWORD PTR [r10+rbx] + lea r12, QWORD PTR [r10+rbx] + mov r13, QWORD PTR [r10+rbx+8] + + add r9d, r14d + or r9d, -2147483647 + xor edx, edx + movdqa xmm0, xmm5 + psrldq xmm0, 8 + movd rax, xmm0 + + div r9 + movd xmm0, rax + movd xmm1, rdx + punpckldq xmm0, xmm1 + movd r15, xmm0 + paddq xmm0, xmm5 + movdqa xmm2, xmm0 + psrlq xmm0, 12 + paddq xmm0, xmm7 + sqrtsd xmm1, xmm0 + movd rdi, xmm1 + test rdi, 524287 + je sqrt_fixup_ryzen + shr rdi, 19 + +sqrt_fixup_ryzen_ret: + mov rax, rsi + mul r14 + movd xmm1, rax + movd xmm0, rdx + punpcklqdq xmm0, xmm1 + + mov r9d, r10d + mov ecx, r10d + xor r9d, 16 + xor ecx, 32 + xor r10d, 48 + movdqa xmm1, XMMWORD PTR [rcx+rbx] + xor rdx, [rcx+rbx] + xor rax, [rcx+rbx+8] + movdqa xmm2, XMMWORD PTR [r9+rbx] + pxor xmm2, xmm0 + paddq xmm4, XMMWORD PTR [r10+rbx] + paddq xmm2, xmm3 + paddq xmm1, xmm6 + movdqa XMMWORD PTR [r9+rbx], xmm4 + movdqa XMMWORD PTR [rcx+rbx], xmm2 + movdqa XMMWORD PTR [r10+rbx], xmm1 + + movdqa xmm4, xmm3 + add r8, rdx + add r11, rax + mov QWORD PTR [r12], r8 + xor r8, rsi + mov QWORD PTR [r12+8], r11 + mov r10, r8 + xor r11, r13 + and r10d, 2097136 + movdqa xmm3, xmm5 + dec ebp + jne main_loop_ryzen + + ldmxcsr DWORD PTR [rsp] + movaps xmm6, XMMWORD PTR [rsp+48] + lea r11, QWORD PTR [rsp+64] + mov rbx, QWORD PTR [r11+56] + mov rbp, QWORD PTR [r11+64] + mov rsi, QWORD PTR [r11+72] + movaps xmm8, XMMWORD PTR [r11-48] + movaps xmm7, XMMWORD PTR [rsp+32] + mov rsp, r11 + pop r15 + pop r14 + pop r13 + pop r12 + pop rdi + jmp cnv2_main_loop_ryzen_endp + +sqrt_fixup_ryzen: + movd r9, xmm2 + dec rdi + mov edx, -1022 + shl rdx, 32 + mov rax, rdi + shr rdi, 19 + shr rax, 20 + mov rcx, rdi + sub rcx, rax + lea rcx, [rcx+rdx+1] + add rax, rdx + imul rcx, rax + sub rcx, r9 + adc rdi, 0 + jmp sqrt_fixup_ryzen_ret + +cnv2_main_loop_ryzen_endp: diff --git a/src/interfaces/IThread.h b/src/interfaces/IThread.h index 2e9e3c39..3a8708e6 100644 --- a/src/interfaces/IThread.h +++ b/src/interfaces/IThread.h @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef __ITHREAD_H__ -#define __ITHREAD_H__ +#ifndef XMRIG_ITHREAD_H +#define XMRIG_ITHREAD_H #include @@ -64,10 +64,14 @@ public: # ifndef XMRIG_NO_API virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0; # endif + +# ifdef APP_DEBUG + virtual void print() const = 0; +# endif }; } /* namespace xmrig */ -#endif // __ITHREAD_H__ +#endif // XMRIG_ITHREAD_H diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 7293a0ac..828203a1 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -101,7 +101,15 @@ void Network::onActive(IStrategy *strategy, Client *client) m_state.setPool(client->host(), client->port(), client->ip()); - LOG_INFO(isColors() ? "\x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "use pool %s:%d %s", client->host(), client->port(), client->ip()); + const char *tlsVersion = client->tlsVersion(); + LOG_INFO(isColors() ? WHITE_BOLD("use pool ") CYAN_BOLD("%s:%d ") GREEN_BOLD("%s") " \x1B[1;30m%s " + : "use pool %s:%d %s %s", + client->host(), client->port(), tlsVersion ? tlsVersion : "", client->ip()); + + const char *fingerprint = client->tlsFingerprint(); + if (fingerprint != nullptr) { + LOG_INFO("%sfingerprint (SHA-256): \"%s\"", isColors() ? "\x1B[1;30m" : "", fingerprint); + } } diff --git a/src/net/Network.h b/src/net/Network.h index 353edc77..51e95d6d 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -30,8 +30,8 @@ #include "api/NetworkState.h" +#include "common/interfaces/IStrategyListener.h" #include "interfaces/IJobResultListener.h" -#include "interfaces/IStrategyListener.h" class IStrategy; diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index b4b41938..6fc90842 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -23,20 +23,16 @@ #include "common/crypto/keccak.h" +#include "common/interfaces/IStrategyListener.h" #include "common/net/Client.h" #include "common/net/Job.h" #include "common/net/strategies/FailoverStrategy.h" #include "common/net/strategies/SinglePoolStrategy.h" #include "common/Platform.h" #include "common/xmrig.h" -#include "interfaces/IStrategyListener.h" #include "net/strategies/DonateStrategy.h" -const static char *kDonatePool1 = "miner.fee.xmrig.com"; -const static char *kDonatePool2 = "emergency.fee.xmrig.com"; - - static inline float randomf(float min, float max) { return (max - min) * ((((float) rand()) / (float) RAND_MAX)) + min; } @@ -55,20 +51,14 @@ DonateStrategy::DonateStrategy(int level, const char *user, xmrig::Algo algo, IS xmrig::keccak(reinterpret_cast(user), strlen(user), hash); Job::toHex(hash, 32, userId); - if (algo == xmrig::CRYPTONIGHT) { - m_pools.push_back(Pool(kDonatePool1, 6666, userId, nullptr, false, true)); - m_pools.push_back(Pool(kDonatePool1, 80, userId, nullptr, false, true)); - m_pools.push_back(Pool(kDonatePool2, 5555, "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", "emergency", false, false)); - } - else if (algo == xmrig::CRYPTONIGHT_HEAVY) { - m_pools.push_back(Pool(kDonatePool1, 8888, userId, nullptr, false, true)); - } - else { - m_pools.push_back(Pool(kDonatePool1, 5555, userId, nullptr, false, true)); - } +# ifndef XMRIG_NO_TLS + m_pools.push_back(Pool("donate.ssl.xmrig.com", 443, userId, nullptr, false, true, true)); +# endif + + m_pools.push_back(Pool("donate.v2.xmrig.com", 3333, userId, nullptr, false, true)); for (Pool &pool : m_pools) { - pool.algorithm().setAlgo(algo); + pool.adjust(xmrig::Algorithm(algo, xmrig::VARIANT_AUTO)); } if (m_pools.size() > 1) { diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index 66c0375c..e75e41a4 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -21,8 +21,8 @@ * along with this program. If not, see . */ -#ifndef __DONATESTRATEGY_H__ -#define __DONATESTRATEGY_H__ +#ifndef XMRIG_DONATESTRATEGY_H +#define XMRIG_DONATESTRATEGY_H #include @@ -30,9 +30,9 @@ #include "common/net/Pool.h" -#include "interfaces/IClientListener.h" -#include "interfaces/IStrategy.h" -#include "interfaces/IStrategyListener.h" +#include "common/interfaces/IClientListener.h" +#include "common/interfaces/IStrategy.h" +#include "common/interfaces/IStrategyListener.h" class Client; @@ -76,4 +76,4 @@ private: uv_timer_t m_timer; }; -#endif /* __DONATESTRATEGY_H__ */ +#endif /* XMRIG_DONATESTRATEGY_H */ diff --git a/src/version.h b/src/version.h index c6c42e46..0ca746dd 100644 --- a/src/version.h +++ b/src/version.h @@ -21,22 +21,21 @@ * along with this program. If not, see . */ -#ifndef __VERSION_H__ -#define __VERSION_H__ +#ifndef XMRIG_VERSION_H +#define XMRIG_VERSION_H #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig CPU miner" -#define APP_VERSION "2.6.0-beta3" +#define APP_VERSION "2.8.1" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com" #define APP_KIND "cpu" #define APP_VER_MAJOR 2 -#define APP_VER_MINOR 6 -#define APP_VER_BUILD 0 -#define APP_VER_REV 3 +#define APP_VER_MINOR 8 +#define APP_VER_PATCH 1 #ifdef _MSC_VER # if (_MSC_VER >= 1910) @@ -54,4 +53,4 @@ # endif #endif -#endif /* __VERSION_H__ */ +#endif /* XMRIG_VERSION_H */ diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index e42139c0..4b528148 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -24,7 +24,10 @@ #include +#include "common/cpu/Cpu.h" +#include "common/log/Log.h" #include "common/net/Pool.h" +#include "crypto/Asm.h" #include "rapidjson/document.h" #include "workers/CpuThread.h" @@ -36,9 +39,10 @@ #endif -xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch) : +xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) : m_algorithm(algorithm), m_av(av), + m_assembly(assembly), m_prefetch(prefetch), m_softAES(softAES), m_priority(priority), @@ -49,22 +53,23 @@ xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiw } -xmrig::CpuThread::~CpuThread() -{ -} - - bool xmrig::CpuThread::isSoftAES(AlgoVariant av) { return av == AV_SINGLE_SOFT || av == AV_DOUBLE_SOFT || av > AV_PENTA; } -xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) +xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly) { - assert(variant == VARIANT_0 || variant == VARIANT_1 || variant == VARIANT_IPBC || variant == VARIANT_XTL); + assert(variant >= VARIANT_0 && variant < VARIANT_MAX); - static const cn_hash_fun func_table[90] = { +# ifndef XMRIG_NO_ASM + constexpr const size_t count = VARIANT_MAX * 10 * 3 + 3; +# else + constexpr const size_t count = VARIANT_MAX * 10 * 3; +# endif + + static const cn_hash_fun func_table[count] = { cryptonight_single_hash, cryptonight_double_hash, cryptonight_single_hash, @@ -87,7 +92,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a cryptonight_quad_hash, cryptonight_penta_hash, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TUBE cryptonight_single_hash, cryptonight_double_hash, @@ -100,6 +105,52 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a cryptonight_quad_hash, cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + # ifndef XMRIG_NO_AEON cryptonight_single_hash, cryptonight_double_hash, @@ -123,23 +174,23 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a cryptonight_quad_hash, cryptonight_penta_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TUBE + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XTL + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_MSR + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2 # else nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, # endif # ifndef XMRIG_NO_SUMO @@ -153,20 +204,57 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a cryptonight_triple_hash, cryptonight_quad_hash, cryptonight_penta_hash, + + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1 + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XTL + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_MSR + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2 # else nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, +# endif +# ifndef XMRIG_NO_ASM + cryptonight_single_hash_asm, + cryptonight_single_hash_asm, + cryptonight_double_hash_asm # endif }; -# ifndef XMRIG_NO_SUMO - if (algorithm == CRYPTONIGHT_HEAVY) { - variant = VARIANT_0; - } -# endif - - const size_t index = 40 * algorithm + 10 * variant + av - 1; - # ifndef NDEBUG + const size_t index = fnIndex(algorithm, av, variant, assembly); cn_hash_fun func = func_table[index]; assert(index < sizeof(func_table) / sizeof(func_table[0])); @@ -174,12 +262,12 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a return func; # else - return func_table[index]; + return func_table[fnIndex(algorithm, av, variant, assembly)]; # endif } -xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority) +xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly) { assert(av > AV_AUTO && av < AV_MAX); @@ -202,7 +290,7 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A } } - return new CpuThread(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false); + return new CpuThread(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false, assembly); } @@ -220,7 +308,7 @@ xmrig::CpuThread *xmrig::CpuThread::createFromData(size_t index, Algo algorithm, assert(av > AV_AUTO && av < AV_MAX); - return new CpuThread(index, algorithm, static_cast(av), multiway, data.affinity, priority, softAES, false); + return new CpuThread(index, algorithm, static_cast(av), multiway, data.affinity, priority, softAES, false, data.assembly); } @@ -242,11 +330,14 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) } const auto &affinity = object["affine_to_cpu"]; - if (affinity.IsUint64()) { data.affinity = affinity.GetInt64(); } +# ifndef XMRIG_NO_ASM + data.assembly = Asm::parse(object["asm"]); +# endif + return data; } @@ -282,6 +373,21 @@ xmrig::IThread::Multiway xmrig::CpuThread::multiway(AlgoVariant av) } +#ifdef APP_DEBUG +void xmrig::CpuThread::print() const +{ + LOG_DEBUG(GREEN_BOLD("CPU thread: ") " index " WHITE_BOLD("%zu") ", multiway " WHITE_BOLD("%d") ", av " WHITE_BOLD("%d") ",", + index(), static_cast(multiway()), static_cast(m_av)); + +# ifndef XMRIG_NO_ASM + LOG_DEBUG(" assembly: %s, affine_to_cpu: %" PRId64, Asm::toString(m_assembly), affinity()); +# else + LOG_DEBUG(" affine_to_cpu: %" PRId64, affinity()); +# endif +} +#endif + + #ifndef XMRIG_NO_API rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const { @@ -312,5 +418,39 @@ rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const obj.AddMember("low_power_mode", multiway(), allocator); obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator); +# ifndef XMRIG_NO_ASM + obj.AddMember("asm", Asm::toJSON(m_assembly), allocator); +# endif + return obj; } + + +size_t xmrig::CpuThread::fnIndex(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly) +{ + const size_t index = VARIANT_MAX * 10 * algorithm + 10 * variant + av - 1; + +# ifndef XMRIG_NO_ASM + if (assembly == ASM_AUTO) { + assembly = Cpu::info()->assembly(); + } + + if (assembly == ASM_NONE) { + return index; + } + + constexpr const size_t offset = VARIANT_MAX * 10 * 3; + + if (algorithm == CRYPTONIGHT && variant == VARIANT_2) { + if (av == AV_SINGLE) { + return offset + assembly - 2; + } + + if (av == AV_DOUBLE) { + return offset + 2; + } + } +# endif + + return index; +} diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index 0e364764..29ab9696 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -21,8 +21,8 @@ * along with this program. If not, see . */ -#ifndef __CPUTHREAD_H__ -#define __CPUTHREAD_H__ +#ifndef XMRIG_CPUTHREAD_H +#define XMRIG_CPUTHREAD_H #include "common/xmrig.h" @@ -40,7 +40,7 @@ class CpuThread : public IThread public: struct Data { - inline Data() : valid(false), affinity(-1L), multiway(SingleWay) {} + inline Data() : assembly(ASM_AUTO), valid(false), affinity(-1L), multiway(SingleWay) {} inline void setMultiway(int value) { @@ -50,27 +50,27 @@ public: } } + Assembly assembly; bool valid; int64_t affinity; Multiway multiway; }; - CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch); - ~CpuThread(); + CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly); typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx); static bool isSoftAES(AlgoVariant av); - static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); - static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); + static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly); + static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly); static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES); static Data parse(const rapidjson::Value &object); static Multiway multiway(AlgoVariant av); inline bool isPrefetch() const { return m_prefetch; } inline bool isSoftAES() const { return m_softAES; } - inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant); } + inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant, m_assembly); } inline Algo algorithm() const override { return m_algorithm; } inline int priority() const override { return m_priority; } @@ -80,6 +80,10 @@ public: inline Type type() const override { return CPU; } protected: +# ifdef APP_DEBUG + void print() const override; +# endif + # ifndef XMRIG_NO_API rapidjson::Value toAPI(rapidjson::Document &doc) const override; # endif @@ -87,8 +91,11 @@ protected: rapidjson::Value toConfig(rapidjson::Document &doc) const override; private: + static size_t fnIndex(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly); + const Algo m_algorithm; const AlgoVariant m_av; + const Assembly m_assembly; const bool m_prefetch; const bool m_softAES; const int m_priority; @@ -101,4 +108,4 @@ private: } /* namespace xmrig */ -#endif /* __CPUTHREAD_H__ */ +#endif /* XMRIG_CPUTHREAD_H */ diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 42068eb7..2a750318 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -35,7 +35,7 @@ #include "workers/Hashrate.h" -inline const char *format(double h, char* buf, size_t size) +inline static const char *format(double h, char *buf, size_t size) { if (isnormal(h)) { snprintf(buf, size, "%03.1f", h); @@ -91,6 +91,9 @@ double Hashrate::calc(size_t ms) const double Hashrate::calc(size_t threadId, size_t ms) const { assert(threadId < m_threads); + if (threadId >= m_threads) { + return nan(""); + } using namespace std::chrono; const uint64_t now = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); @@ -149,14 +152,15 @@ void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp) } -void Hashrate::print() +void Hashrate::print() const { char num1[8] = { 0 }; char num2[8] = { 0 }; char num3[8] = { 0 }; char num4[8] = { 0 }; - LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s max: %s H/s", + LOG_INFO(m_controller->config()->isColors() ? WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("H/s") " max " CYAN_BOLD("%s H/s") + : "speed 10s/60s/15m %s %s %s H/s max %s H/s", format(calc(ShortInterval), num1, sizeof(num1)), format(calc(MediumInterval), num2, sizeof(num2)), format(calc(LargeInterval), num3, sizeof(num3)), @@ -180,6 +184,12 @@ void Hashrate::updateHighest() } +const char *Hashrate::format(double h, char *buf, size_t size) +{ + return ::format(h, buf, size); +} + + void Hashrate::onReport(uv_timer_t *handle) { static_cast(handle->data)->print(); diff --git a/src/workers/Hashrate.h b/src/workers/Hashrate.h index e79c757a..e766f117 100644 --- a/src/workers/Hashrate.h +++ b/src/workers/Hashrate.h @@ -38,7 +38,7 @@ class Hashrate { public: enum Intervals { - ShortInterval = 2500, + ShortInterval = 10000, MediumInterval = 60000, LargeInterval = 900000 }; @@ -47,13 +47,15 @@ public: double calc(size_t ms) const; double calc(size_t threadId, size_t ms) const; void add(size_t threadId, uint64_t count, uint64_t timestamp); - void print(); + void print() const; void stop(); void updateHighest(); inline double highest() const { return m_highest; } inline size_t threads() const { return m_threads; } + static const char *format(double h, char *buf, size_t size); + private: static void onReport(uv_timer_t *handle); diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index c0f88446..a6dbc73a 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -50,39 +51,34 @@ MultiWorker::~MultiWorker() template bool MultiWorker::selfTest() { - if (m_thread->fn(xmrig::VARIANT_0) == nullptr) { - return false; - } + using namespace xmrig; - m_thread->fn(xmrig::VARIANT_0)(test_input, 76, m_hash, m_ctx); - - if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, sizeof m_hash) == 0) { - m_thread->fn(xmrig::VARIANT_1)(test_input, 76, m_hash, m_ctx); - if (memcmp(m_hash, test_output_v1, sizeof m_hash) != 0) { - return false; - } - - m_thread->fn(xmrig::VARIANT_XTL)(test_input, 76, m_hash, m_ctx); - return memcmp(m_hash, test_output_xtl, sizeof m_hash) == 0; + if (m_thread->algorithm() == CRYPTONIGHT) { + return verify(VARIANT_0, test_output_v0) && + verify(VARIANT_1, test_output_v1) && + verify(VARIANT_2, test_output_v2) && + verify(VARIANT_XTL, test_output_xtl) && + verify(VARIANT_MSR, test_output_msr) && + verify(VARIANT_XAO, test_output_xao) && + verify(VARIANT_RTO, test_output_rto); } # ifndef XMRIG_NO_AEON - if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, sizeof m_hash) == 0) { - m_thread->fn(xmrig::VARIANT_1)(test_input, 76, m_hash, m_ctx); - if (memcmp(m_hash, test_output_v1_lite, sizeof m_hash) != 0) { - return false; - } - - m_thread->fn(xmrig::VARIANT_IPBC)(test_input, 76, m_hash, m_ctx); - return memcmp(m_hash, test_output_ipbc_lite, sizeof m_hash) == 0; + if (m_thread->algorithm() == CRYPTONIGHT_LITE) { + return verify(VARIANT_0, test_output_v0_lite) && + verify(VARIANT_1, test_output_v1_lite); } # endif # ifndef XMRIG_NO_SUMO - return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_hash, test_output_heavy, sizeof m_hash) == 0; -# else - return false; + if (m_thread->algorithm() == CRYPTONIGHT_HEAVY) { + return verify(VARIANT_0, test_output_v0_heavy) && + verify(VARIANT_XHV, test_output_xhv_heavy) && + verify(VARIANT_TUBE, test_output_tube_heavy); + } # endif + + return false; } @@ -108,7 +104,7 @@ void MultiWorker::start() storeStats(); } - m_thread->fn(m_state.job.variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx); + m_thread->fn(m_state.job.algorithm().variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx); for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { @@ -140,6 +136,20 @@ bool MultiWorker::resume(const Job &job) } +template +bool MultiWorker::verify(xmrig::Variant variant, const uint8_t *referenceValue) +{ + + xmrig::CpuThread::cn_hash_fun func = m_thread->fn(variant); + if (!func) { + return false; + } + + func(test_input, 76, m_hash, m_ctx); + return memcmp(m_hash, referenceValue, sizeof m_hash) == 0; +} + + template void MultiWorker::consumeJob() { diff --git a/src/workers/MultiWorker.h b/src/workers/MultiWorker.h index d89bbb33..c08e4fbe 100644 --- a/src/workers/MultiWorker.h +++ b/src/workers/MultiWorker.h @@ -6,6 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett + * Copyright 2018 SChernykh * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -22,8 +23,8 @@ * along with this program. If not, see . */ -#ifndef __MULTIWORKER_H__ -#define __MULTIWORKER_H__ +#ifndef XMRIG_MULTIWORKER_H +#define XMRIG_MULTIWORKER_H #include "common/net/Job.h" @@ -48,6 +49,7 @@ protected: private: bool resume(const Job &job); + bool verify(xmrig::Variant variant, const uint8_t *referenceValue); void consumeJob(); void save(const Job &job); @@ -70,4 +72,4 @@ private: }; -#endif /* __MULTIWORKER_H__ */ +#endif /* XMRIG_MULTIWORKER_H */ diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 567b3e08..c569908c 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -24,8 +24,8 @@ #include +#include "common/cpu/Cpu.h" #include "common/Platform.h" -#include "Cpu.h" #include "workers/CpuThread.h" #include "workers/Handle.h" #include "workers/Worker.h" @@ -41,7 +41,7 @@ Worker::Worker(Handle *handle) : m_sequence(0), m_thread(static_cast(handle->config())) { - if (Cpu::threads() > 1 && m_thread->affinity() != -1L) { + if (xmrig::Cpu::info()->threads() > 1 && m_thread->affinity() != -1L) { Platform::setThreadAffinity(m_thread->affinity()); } diff --git a/src/workers/Worker.h b/src/workers/Worker.h index aad9e3c5..73e25033 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -21,8 +21,8 @@ * along with this program. If not, see . */ -#ifndef __WORKER_H__ -#define __WORKER_H__ +#ifndef XMRIG_WORKER_H +#define XMRIG_WORKER_H #include @@ -33,7 +33,6 @@ #include "Mem.h" -struct cryptonight_ctx; class Handle; @@ -67,4 +66,4 @@ protected: }; -#endif /* __WORKER_H__ */ +#endif /* XMRIG_WORKER_H */ diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 497e3060..a5109e9b 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -22,6 +22,7 @@ */ #include +#include #include @@ -55,6 +56,7 @@ uv_async_t Workers::m_async; uv_mutex_t Workers::m_mutex; uv_rwlock_t Workers::m_rwlock; uv_timer_t Workers::m_timer; +xmrig::Controller *Workers::m_controller = nullptr; Job Workers::job() @@ -89,6 +91,33 @@ size_t Workers::threads() void Workers::printHashrate(bool detail) { + assert(m_controller != nullptr); + if (!m_controller) { + return; + } + + if (detail) { + const bool isColors = m_controller->config()->isColors(); + char num1[8] = { 0 }; + char num2[8] = { 0 }; + char num3[8] = { 0 }; + + Log::i()->text("%s| THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |", isColors ? "\x1B[1;37m" : ""); + + size_t i = 0; + for (const xmrig::IThread *thread : m_controller->config()->threads()) { + Log::i()->text("| %6zu | %8" PRId64 " | %7s | %7s | %7s |", + thread->index(), + thread->affinity(), + Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::ShortInterval), num1, sizeof num1), + Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::MediumInterval), num2, sizeof num2), + Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::LargeInterval), num3, sizeof num3) + ); + + i++; + } + } + m_hashrate->print(); } @@ -131,6 +160,16 @@ void Workers::setJob(const Job &job, bool donate) void Workers::start(xmrig::Controller *controller) { +# ifdef APP_DEBUG + LOG_NOTICE("THREADS ------------------------------------------------------------------"); + for (const xmrig::IThread *thread : controller->config()->threads()) { + thread->print(); + } + LOG_NOTICE("--------------------------------------------------------------------------"); +# endif + + m_controller = controller; + const std::vector &threads = controller->config()->threads(); m_status.algo = controller->config()->algorithm().algo(); m_status.colors = controller->config()->isColors(); @@ -161,6 +200,10 @@ void Workers::start(xmrig::Controller *controller) m_workers.push_back(handle); handle->start(Workers::onReady); } + + if (controller->config()->isShouldSave()) { + controller->config()->save(); + } } @@ -301,13 +344,13 @@ void Workers::start(IWorker *worker) const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo) / 1048576; if (m_status.colors) { - LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\e[0m memory " CYAN_BOLD("%zu.0 MB") "", + LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu.0 MB") "", m_status.threads, m_status.ways, - (m_status.hugePages == m_status.pages ? "\e[1;32m" : (m_status.hugePages == 0 ? "\e[1;31m" : "\e[1;33m")), + (m_status.hugePages == m_status.pages ? "\x1B[1;32m" : (m_status.hugePages == 0 ? "\x1B[1;31m" : "\x1B[1;33m")), m_status.hugePages, m_status.pages, percent, memory); } else { - LOG_INFO("READY (CPU) threads %zu(%zu) huge pages %zu/%zu %f%% memory %zu.0 MB", + LOG_INFO("READY (CPU) threads %zu(%zu) huge pages %zu/%zu %1.0f%% memory %zu.0 MB", m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, memory); } } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index ca01e698..1d619cea 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -114,6 +114,7 @@ private: static uv_mutex_t m_mutex; static uv_rwlock_t m_rwlock; static uv_timer_t m_timer; + static xmrig::Controller *m_controller; }; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index b30cfb0b..00000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -project("xmrig-test" C) -cmake_minimum_required(VERSION 3.0) - -include(CTest) - -add_subdirectory(unity) -add_subdirectory(cryptonight) -add_subdirectory(cryptonight_lite) -add_subdirectory(autoconf) \ No newline at end of file diff --git a/test/autoconf/CMakeLists.txt b/test/autoconf/CMakeLists.txt deleted file mode 100644 index b956a9de..00000000 --- a/test/autoconf/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(SOURCES - autoconf.c - ../../cpu.h - ../../cpu.c - ) - -add_executable(autoconf_app ${SOURCES}) -target_link_libraries(autoconf_app unity) - -include_directories(../..) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2") -add_definitions(-DBUILD_TEST) - -add_test(autoconf_test autoconf_app) diff --git a/test/autoconf/autoconf.c b/test/autoconf/autoconf.c deleted file mode 100644 index 86ced5f0..00000000 --- a/test/autoconf/autoconf.c +++ /dev/null @@ -1,152 +0,0 @@ -#include - -#include "cpu.h" -#include "options.h" - -struct cpu_info cpu_info = { 0 }; - - -static void set_cpu_info(int total_logical_cpus, int l2_cache, int l3_cache) { - cpu_info.total_cores = total_logical_cpus; - cpu_info.total_logical_cpus = total_logical_cpus; - cpu_info.l2_cache = l2_cache; - cpu_info.l3_cache = l3_cache; -} - - -void test_autoconf_should_GetOptimalThreadsCounti7(void) { - set_cpu_info(8, 1024, 8192); // 4C/8T 8 MB (Generic i7 CPU) - - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(5, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 60)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 50)); - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 35)); - TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 20)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 5)); -} - - -void test_autoconf_should_GetOptimalThreadsCounti5(void) { - set_cpu_info(4, 1024, 6144); // 2C/4T 6 MB (Generic i5 CPU) - - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75)); - - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75)); -} - - -void test_autoconf_should_GetOptimalThreadsCounti3(void) { - set_cpu_info(4, 512, 3072); // 2C/4T 3 MB (Generic i3 CPU) - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75)); - - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75)); -} - - -void test_autoconf_should_GetOptimalThreadsCountR7(void) { - set_cpu_info(16, 4096, 16384); // 8C/16T 16 MB (AMD Ryzen 7) - - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75)); - - TEST_ASSERT_EQUAL_INT(16, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75)); -} - - -void test_autoconf_should_GetOptimalThreadsCountTwoE5620(void) { - set_cpu_info(16, 2048, 24576); // 8C/16T 24 MB (Two E5620) - - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75)); - TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75)); - - TEST_ASSERT_EQUAL_INT(16, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75)); -} - - -void test_autoconf_should_GetOptimalThreadsCountVCPU(void) { - set_cpu_info(1, 1024, 15360); // 1C/1T 15 MB (Single core Virtual CPU) - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75)); - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75)); -} - - -void test_autoconf_should_GetOptimalThreadsCountNoL3(void) { - set_cpu_info(8, 8192, 0); // 4C/8T (Multi core Virtual CPU without L3 cache) - - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(5, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 60)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 50)); - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 35)); - TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 20)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 5)); -} - - -int main(void) -{ - UNITY_BEGIN(); - - RUN_TEST(test_autoconf_should_GetOptimalThreadsCounti7); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCounti5); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCounti3); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCountR7); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCountR7); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCountTwoE5620); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCountVCPU); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCountNoL3); - - return UNITY_END(); -} diff --git a/test/cryptonight/CMakeLists.txt b/test/cryptonight/CMakeLists.txt deleted file mode 100644 index 4ebbbcc9..00000000 --- a/test/cryptonight/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -set(SOURCES - cryptonight.c - ../../options.h - ../../algo/cryptonight/cryptonight.h - ../../algo/cryptonight/cryptonight.c - ../../algo/cryptonight/cryptonight_av1_aesni.c - ../../algo/cryptonight/cryptonight_av2_aesni_double.c - ../../algo/cryptonight/cryptonight_av3_softaes.c - ../../algo/cryptonight/cryptonight_av4_softaes_double.c - ../../crypto/c_keccak.c - ../../crypto/c_blake256.c - ../../crypto/c_groestl.c - ../../crypto/c_jh.c - ../../crypto/c_skein.c - ../../crypto/soft_aes.c - ) - -add_executable(cryptonight_app ${SOURCES}) -target_link_libraries(cryptonight_app unity) - -include_directories(../..) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -fno-strict-aliasing") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2") -add_definitions(-DBUILD_TEST) -add_definitions(-DXMRIG_NO_AEON) - -add_test(cryptonight_test cryptonight_app) diff --git a/test/cryptonight/cryptonight.c b/test/cryptonight/cryptonight.c deleted file mode 100644 index bcc0db30..00000000 --- a/test/cryptonight/cryptonight.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include - -#include "options.h" -#include "algo/cryptonight/cryptonight.h" - -bool opt_double_hash = false; - -const static char input1[152] = { - 0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00, - 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, - 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, - 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, - 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01, - 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, - 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, - 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, - 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, - 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, -}; - -const static char input2[] = "This is a test"; -const static char input3[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pellentesque metus."; - - -void cryptonight_av1_aesni(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_av2_aesni_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_av3_softaes(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_av4_softaes_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); - - -static char hash[64]; -#define RESULT1 "1a3ffbee909b420d91f7be6e5fb56db71b3110d886011e877ee5786afd080100" -#define RESULT1_DOUBLE "1a3ffbee909b420d91f7be6e5fb56db71b3110d886011e877ee5786afd0801001b606a3f4a07d6489a1bcd07697bd16696b61c8ae982f61a90160f4e52828a7f" -#define RESULT2 "a084f01d1437a09c6985401b60d43554ae105802c5f5d8a9b3253649c0be6605" -#define RESULT3 "0bbe54bd26caa92a1d436eec71cbef02560062fa689fe14d7efcf42566b411cf" - - -static char *bin2hex(const unsigned char *p, size_t len) -{ - char *s = malloc((len * 2) + 1); - if (!s) { - return NULL; - } - - for (int i = 0; i < len; i++) { - sprintf(s + (i * 2), "%02x", (unsigned int) p[i]); - } - - return s; -} - - -static void * create_ctx(int ratio) { - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16); - ctx->memory = (uint8_t *) _mm_malloc(MEMORY * ratio, 16); - - return ctx; -} - - -static void free_ctx(struct cryptonight_ctx *ctx) { - _mm_free(ctx->memory); - _mm_free(ctx); -} - - -void test_cryptonight_av1_should_CalcHash(void) { - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(1); - - cryptonight_av1_aesni(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1, bin2hex(hash, 32)); - - cryptonight_av1_aesni(input2, strlen(input2), &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT2, bin2hex(hash, 32)); - - cryptonight_av1_aesni(input3, strlen(input3), &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT3, bin2hex(hash, 32)); - - free_ctx(ctx); -} - - -void test_cryptonight_av2_should_CalcHash(void) -{ - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(2); - - cryptonight_av2_aesni_double(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1_DOUBLE, bin2hex(hash, 64)); - - free_ctx(ctx); -} - - -void test_cryptonight_av3_should_CalcHash(void) -{ - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(1); - - cryptonight_av3_softaes(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1, bin2hex(hash, 32)); - - cryptonight_av3_softaes(input2, strlen(input2), &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT2, bin2hex(hash, 32)); - - cryptonight_av3_softaes(input3, strlen(input3), &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT3, bin2hex(hash, 32)); - - free_ctx(ctx); -} - - -void test_cryptonight_av4_should_CalcHash(void) -{ - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(2); - - cryptonight_av4_softaes_double(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1_DOUBLE, bin2hex(hash, 64)); - - free_ctx(ctx); -} - - -int main(void) -{ - UNITY_BEGIN(); - - RUN_TEST(test_cryptonight_av1_should_CalcHash); - RUN_TEST(test_cryptonight_av2_should_CalcHash); - RUN_TEST(test_cryptonight_av3_should_CalcHash); - RUN_TEST(test_cryptonight_av4_should_CalcHash); - - return UNITY_END(); -} diff --git a/test/cryptonight_lite/CMakeLists.txt b/test/cryptonight_lite/CMakeLists.txt deleted file mode 100644 index 9a83ecbc..00000000 --- a/test/cryptonight_lite/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -set(SOURCES - cryptonight_lite.c - ../../options.h - ../../algo/cryptonight/cryptonight.h - ../../algo/cryptonight/cryptonight.c - ../../algo/cryptonight-lite/cryptonight_lite_av1_aesni.c - ../../algo/cryptonight-lite/cryptonight_lite_av2_aesni_double.c - ../../algo/cryptonight-lite/cryptonight_lite_av3_softaes.c - ../../algo/cryptonight-lite/cryptonight_lite_av4_softaes_double.c - ../../crypto/c_keccak.c - ../../crypto/c_blake256.c - ../../crypto/c_groestl.c - ../../crypto/c_jh.c - ../../crypto/c_skein.c - ../../crypto/soft_aes.c - ) - -add_executable(cryptonight_lite_app ${SOURCES}) -target_link_libraries(cryptonight_lite_app unity) - -include_directories(../..) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -fno-strict-aliasing") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2") -add_definitions(-DBUILD_TEST) - -add_test(cryptonight_lite_test cryptonight_lite_app) diff --git a/test/cryptonight_lite/cryptonight_lite.c b/test/cryptonight_lite/cryptonight_lite.c deleted file mode 100644 index a6d5b554..00000000 --- a/test/cryptonight_lite/cryptonight_lite.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include -#include - -#include "options.h" -#include "algo/cryptonight/cryptonight.h" - -bool opt_double_hash = false; -enum mining_algo opt_algo = ALGO_CRYPTONIGHT_LITE; - -const static char input1[152] = { - 0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00, - 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, - 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, - 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, - 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01, - 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, - 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, - 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, - 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, - 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, -}; - - -void cryptonight_av1_aesni(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx) {} -void cryptonight_av2_aesni_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx) {} -void cryptonight_av3_softaes(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx) {} -void cryptonight_av4_softaes_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx) {} - -void cryptonight_lite_av1_aesni(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_lite_av2_aesni_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_lite_av3_softaes(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_lite_av4_softaes_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); - - -static char hash[64]; -#define RESULT1 "3695b4b53bb00358b0ad38dc160feb9e004eece09b83a72ef6ba9864d3510c88" -#define RESULT1_DOUBLE "3695b4b53bb00358b0ad38dc160feb9e004eece09b83a72ef6ba9864d3510c8828a22bad3f93d1408fca472eb5ad1cbe75f21d053c8ce5b3af105a57713e21dd" - - -static char *bin2hex(const unsigned char *p, size_t len) -{ - char *s = malloc((len * 2) + 1); - if (!s) { - return NULL; - } - - for (int i = 0; i < len; i++) { - sprintf(s + (i * 2), "%02x", (unsigned int) p[i]); - } - - return s; -} - - -static void * create_ctx(int ratio) { - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16); - ctx->memory = (uint8_t *) _mm_malloc(MEMORY_LITE * ratio, 16); - - return ctx; -} - - -static void free_ctx(struct cryptonight_ctx *ctx) { - _mm_free(ctx->memory); - _mm_free(ctx); -} - - -void test_cryptonight_lite_av1_should_CalcHash(void) { - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(1); - - cryptonight_lite_av1_aesni(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1, bin2hex(hash, 32)); - - free_ctx(ctx); -} - - -void test_cryptonight_lite_av2_should_CalcHash(void) -{ - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(2); - - cryptonight_lite_av2_aesni_double(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1_DOUBLE, bin2hex(hash, 64)); - - free_ctx(ctx); -} - - -void test_cryptonight_lite_av3_should_CalcHash(void) { - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(1); - - cryptonight_lite_av3_softaes(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1, bin2hex(hash, 32)); - - free_ctx(ctx); -} - - -void test_cryptonight_lite_av4_should_CalcHash(void) -{ - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(2); - - cryptonight_lite_av4_softaes_double(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1_DOUBLE, bin2hex(hash, 64)); - - free_ctx(ctx); -} - - -int main(void) -{ - UNITY_BEGIN(); - - RUN_TEST(test_cryptonight_lite_av1_should_CalcHash); - RUN_TEST(test_cryptonight_lite_av2_should_CalcHash); - RUN_TEST(test_cryptonight_lite_av3_should_CalcHash); - RUN_TEST(test_cryptonight_lite_av4_should_CalcHash); - - return UNITY_END(); -} diff --git a/test/unity/CMakeLists.txt b/test/unity/CMakeLists.txt deleted file mode 100644 index 6e350179..00000000 --- a/test/unity/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_library(unity STATIC unity.c) -target_include_directories(unity PUBLIC .) diff --git a/test/unity/unity.c b/test/unity/unity.c deleted file mode 100644 index a43e33e1..00000000 --- a/test/unity/unity.c +++ /dev/null @@ -1,1446 +0,0 @@ -/* ========================================================================= - Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -============================================================================ */ - -#include "unity.h" -#include - -/* If omitted from header, declare overrideable prototypes here so they're ready for use */ -#ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION -void UNITY_OUTPUT_CHAR(int); -#endif - -/* Helpful macros for us to use here */ -#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; longjmp(Unity.AbortFrame, 1); } -#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; longjmp(Unity.AbortFrame, 1); } - -/* return prematurely if we are already in failure or ignore state */ -#define UNITY_SKIP_EXECUTION { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} } - -struct _Unity Unity; - -static const char UnityStrOk[] = "OK"; -static const char UnityStrPass[] = "PASS"; -static const char UnityStrFail[] = "FAIL"; -static const char UnityStrIgnore[] = "IGNORE"; -static const char UnityStrNull[] = "NULL"; -static const char UnityStrSpacer[] = ". "; -static const char UnityStrExpected[] = " Expected "; -static const char UnityStrWas[] = " Was "; -static const char UnityStrElement[] = " Element "; -static const char UnityStrByte[] = " Byte "; -static const char UnityStrMemory[] = " Memory Mismatch."; -static const char UnityStrDelta[] = " Values Not Within Delta "; -static const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; -static const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; -static const char UnityStrNullPointerForActual[] = " Actual pointer was NULL"; -#ifndef UNITY_EXCLUDE_FLOAT -static const char UnityStrNot[] = "Not "; -static const char UnityStrInf[] = "Infinity"; -static const char UnityStrNegInf[] = "Negative Infinity"; -static const char UnityStrNaN[] = "NaN"; -static const char UnityStrDet[] = "Determinate"; -static const char UnityStrInvalidFloatTrait[] = "Invalid Float Trait"; -#endif -const char UnityStrErrFloat[] = "Unity Floating Point Disabled"; -const char UnityStrErrDouble[] = "Unity Double Precision Disabled"; -const char UnityStrErr64[] = "Unity 64-bit Support Disabled"; -static const char UnityStrBreaker[] = "-----------------------"; -static const char UnityStrResultsTests[] = " Tests "; -static const char UnityStrResultsFailures[] = " Failures "; -static const char UnityStrResultsIgnored[] = " Ignored "; -static const char UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; -static const char UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; - -/* compiler-generic print formatting masks */ -static const _U_UINT UnitySizeMask[] = -{ - 255u, /* 0xFF */ - 65535u, /* 0xFFFF */ - 65535u, - 4294967295u, /* 0xFFFFFFFF */ - 4294967295u, - 4294967295u, - 4294967295u -#ifdef UNITY_SUPPORT_64 - ,0xFFFFFFFFFFFFFFFF -#endif -}; - -/*----------------------------------------------- - * Pretty Printers & Test Result Output Handlers - *-----------------------------------------------*/ - -void UnityPrint(const char* string) -{ - const char* pch = string; - - if (pch != NULL) - { - while (*pch) - { - /* printable characters plus CR & LF are printed */ - if ((*pch <= 126) && (*pch >= 32)) - { - UNITY_OUTPUT_CHAR(*pch); - } - /* write escaped carriage returns */ - else if (*pch == 13) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('r'); - } - /* write escaped line feeds */ - else if (*pch == 10) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('n'); - } - /* unprintable characters are shown as codes */ - else - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('x'); - UnityPrintNumberHex((_U_UINT)*pch, 2); - } - pch++; - } - } -} - -void UnityPrintLen(const char* string, const _UU32 length); -void UnityPrintLen(const char* string, const _UU32 length) -{ - const char* pch = string; - - if (pch != NULL) - { - while (*pch && (_UU32)(pch - string) < length) - { - /* printable characters plus CR & LF are printed */ - if ((*pch <= 126) && (*pch >= 32)) - { - UNITY_OUTPUT_CHAR(*pch); - } - /* write escaped carriage returns */ - else if (*pch == 13) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('r'); - } - /* write escaped line feeds */ - else if (*pch == 10) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('n'); - } - /* unprintable characters are shown as codes */ - else - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('x'); - UnityPrintNumberHex((_U_UINT)*pch, 2); - } - pch++; - } - } -} - -/*-----------------------------------------------*/ -void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style) -{ - if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) - { - UnityPrintNumber(number); - } - else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) - { - UnityPrintNumberUnsigned( (_U_UINT)number & UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1] ); - } - else - { - UNITY_OUTPUT_CHAR('0'); - UNITY_OUTPUT_CHAR('x'); - UnityPrintNumberHex((_U_UINT)number, (char)((style & 0x000F) << 1)); - } -} - -/*-----------------------------------------------*/ -void UnityPrintNumber(const _U_SINT number_to_print) -{ - _U_UINT number = (_U_UINT)number_to_print; - - if (number_to_print < 0) - { - /* A negative number, including MIN negative */ - UNITY_OUTPUT_CHAR('-'); - number = (_U_UINT)(-number_to_print); - } - UnityPrintNumberUnsigned(number); -} - -/*----------------------------------------------- - * basically do an itoa using as little ram as possible */ -void UnityPrintNumberUnsigned(const _U_UINT number) -{ - _U_UINT divisor = 1; - - /* figure out initial divisor */ - while (number / divisor > 9) - { - divisor *= 10; - } - - /* now mod and print, then divide divisor */ - do - { - UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); - divisor /= 10; - } - while (divisor > 0); -} - -/*-----------------------------------------------*/ -void UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print) -{ - _U_UINT nibble; - char nibbles = nibbles_to_print; - - while (nibbles > 0) - { - nibble = (number >> (--nibbles << 2)) & 0x0000000F; - if (nibble <= 9) - { - UNITY_OUTPUT_CHAR((char)('0' + nibble)); - } - else - { - UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); - } - } -} - -/*-----------------------------------------------*/ -void UnityPrintMask(const _U_UINT mask, const _U_UINT number) -{ - _U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1); - _US32 i; - - for (i = 0; i < UNITY_INT_WIDTH; i++) - { - if (current_bit & mask) - { - if (current_bit & number) - { - UNITY_OUTPUT_CHAR('1'); - } - else - { - UNITY_OUTPUT_CHAR('0'); - } - } - else - { - UNITY_OUTPUT_CHAR('X'); - } - current_bit = current_bit >> 1; - } -} - -/*-----------------------------------------------*/ -#ifdef UNITY_FLOAT_VERBOSE -#include - -#ifndef UNITY_VERBOSE_NUMBER_MAX_LENGTH -# ifdef UNITY_DOUBLE_VERBOSE -# define UNITY_VERBOSE_NUMBER_MAX_LENGTH 317 -# else -# define UNITY_VERBOSE_NUMBER_MAX_LENGTH 47 -# endif -#endif - -void UnityPrintFloat(_UD number) -{ - char TempBuffer[UNITY_VERBOSE_NUMBER_MAX_LENGTH + 1]; - snprintf(TempBuffer, sizeof(TempBuffer), "%.6f", number); - UnityPrint(TempBuffer); -} -#endif - -/*-----------------------------------------------*/ - -void UnityPrintFail(void); -void UnityPrintFail(void) -{ - UnityPrint(UnityStrFail); -} - -void UnityPrintOk(void); -void UnityPrintOk(void) -{ - UnityPrint(UnityStrOk); -} - -/*-----------------------------------------------*/ -static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line); -static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) -{ -#ifndef UNITY_FIXTURES - UnityPrint(file); - UNITY_OUTPUT_CHAR(':'); - UnityPrintNumber((_U_SINT)line); - UNITY_OUTPUT_CHAR(':'); - UnityPrint(Unity.CurrentTestName); - UNITY_OUTPUT_CHAR(':'); -#else - UNITY_UNUSED(file); - UNITY_UNUSED(line); -#endif -} - -/*-----------------------------------------------*/ -static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line); -static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) -{ -#ifndef UNITY_FIXTURES - UnityTestResultsBegin(Unity.TestFile, line); -#else - UNITY_UNUSED(line); -#endif - UnityPrint(UnityStrFail); - UNITY_OUTPUT_CHAR(':'); -} - -/*-----------------------------------------------*/ -void UnityConcludeTest(void) -{ - if (Unity.CurrentTestIgnored) - { - Unity.TestIgnores++; - } - else if (!Unity.CurrentTestFailed) - { - UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); - UnityPrint(UnityStrPass); - } - else - { - Unity.TestFailures++; - } - - Unity.CurrentTestFailed = 0; - Unity.CurrentTestIgnored = 0; - UNITY_PRINT_EOL(); - UNITY_FLUSH_CALL(); -} - -/*-----------------------------------------------*/ -static void UnityAddMsgIfSpecified(const char* msg); -static void UnityAddMsgIfSpecified(const char* msg) -{ - if (msg) - { - UnityPrint(UnityStrSpacer); -#ifndef UNITY_EXCLUDE_DETAILS - if (Unity.CurrentDetail1) - { - UnityPrint(UnityStrDetail1Name); - UnityPrint(Unity.CurrentDetail1); - if (Unity.CurrentDetail2) - { - UnityPrint(UnityStrDetail2Name); - UnityPrint(Unity.CurrentDetail2); - } - UnityPrint(UnityStrSpacer); - } -#endif - UnityPrint(msg); - } -} - -/*-----------------------------------------------*/ -static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual); -static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) -{ - UnityPrint(UnityStrExpected); - if (expected != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrint(expected); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } - UnityPrint(UnityStrWas); - if (actual != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrint(actual); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } -} - -/*-----------------------------------------------*/ -static void UnityPrintExpectedAndActualStringsLen(const char* expected, const char* actual, const _UU32 length) -{ - UnityPrint(UnityStrExpected); - if (expected != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrintLen(expected, length); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } - UnityPrint(UnityStrWas); - if (actual != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrintLen(actual, length); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } -} - - - -/*----------------------------------------------- - * Assertion & Control Helpers - *-----------------------------------------------*/ - -static int UnityCheckArraysForNull(UNITY_INTERNAL_PTR expected, UNITY_INTERNAL_PTR actual, const UNITY_LINE_TYPE lineNumber, const char* msg) -{ - /* return true if they are both NULL */ - if ((expected == NULL) && (actual == NULL)) - return 1; - - /* throw error if just expected is NULL */ - if (expected == NULL) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrNullPointerForExpected); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - /* throw error if just actual is NULL */ - if (actual == NULL) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrNullPointerForActual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - /* return false if neither is NULL */ - return 0; -} - -/*----------------------------------------------- - * Assertion Functions - *-----------------------------------------------*/ - -void UnityAssertBits(const _U_SINT mask, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_SKIP_EXECUTION; - - if ((mask & expected) != (mask & actual)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - UnityPrintMask((_U_UINT)mask, (_U_UINT)expected); - UnityPrint(UnityStrWas); - UnityPrintMask((_U_UINT)mask, (_U_UINT)actual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -/*-----------------------------------------------*/ -void UnityAssertEqualNumber(const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - UNITY_SKIP_EXECUTION; - - if (expected != actual) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(expected, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(actual, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -#define UnityPrintPointlessAndBail() \ -{ \ - UnityTestResultsFailBegin(lineNumber); \ - UnityPrint(UnityStrPointless); \ - UnityAddMsgIfSpecified(msg); \ - UNITY_FAIL_AND_BAIL; } - -/*-----------------------------------------------*/ -void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, - UNITY_INTERNAL_PTR actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - _UU32 elements = num_elements; - UNITY_INTERNAL_PTR ptr_exp = (UNITY_INTERNAL_PTR)expected; - UNITY_INTERNAL_PTR ptr_act = (UNITY_INTERNAL_PTR)actual; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityPrintPointlessAndBail(); - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - /* If style is UNITY_DISPLAY_STYLE_INT, we'll fall into the default case rather than the INT16 or INT32 (etc) case - * as UNITY_DISPLAY_STYLE_INT includes a flag for UNITY_DISPLAY_RANGE_AUTO, which the width-specific - * variants do not. Therefore remove this flag. */ - switch(style & (UNITY_DISPLAY_STYLE_T)(~UNITY_DISPLAY_RANGE_AUTO)) - { - case UNITY_DISPLAY_STYLE_HEX8: - case UNITY_DISPLAY_STYLE_INT8: - case UNITY_DISPLAY_STYLE_UINT8: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 1); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 1); - } - break; - case UNITY_DISPLAY_STYLE_HEX16: - case UNITY_DISPLAY_STYLE_INT16: - case UNITY_DISPLAY_STYLE_UINT16: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 2); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 2); - } - break; -#ifdef UNITY_SUPPORT_64 - case UNITY_DISPLAY_STYLE_HEX64: - case UNITY_DISPLAY_STYLE_INT64: - case UNITY_DISPLAY_STYLE_UINT64: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 8); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 8); - } - break; -#endif - default: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 4); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 4); - } - break; - } -} - -/*-----------------------------------------------*/ -/* Wrap this define in a function with variable types as float or double */ -#define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff) \ - if (isinf(expected) && isinf(actual) && (isneg(expected) == isneg(actual))) return 1; \ - if (isnan(expected) && isnan(actual)) return 1; \ - diff = actual - expected; \ - if (diff < 0.0f) diff = 0.0f - diff; \ - if (delta < 0.0f) delta = 0.0f - delta; \ - return !(isnan(diff) || isinf(diff) || (delta < diff)); - /* This first part of this condition will catch any NaN or Infinite values */ - -#ifndef UNITY_EXCLUDE_FLOAT -static int UnityFloatsWithin(_UF delta, _UF expected, _UF actual) -{ - _UF diff; - UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); -} - -void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, - UNITY_PTR_ATTRIBUTE const _UF* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 elements = num_elements; - UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected; - UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityPrintPointlessAndBail(); - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat(*ptr_expected); - UnityPrint(UnityStrWas); - UnityPrintFloat(*ptr_actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_expected++; - ptr_actual++; - } -} - -/*-----------------------------------------------*/ -void UnityAssertFloatsWithin(const _UF delta, - const _UF expected, - const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_SKIP_EXECUTION; - - - if (!UnityFloatsWithin(delta, expected, actual)) - { - UnityTestResultsFailBegin(lineNumber); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat(expected); - UnityPrint(UnityStrWas); - UnityPrintFloat(actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -/*-----------------------------------------------*/ -void UnityAssertFloatSpecial(const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style) -{ - const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; - _U_SINT should_be_trait = ((_U_SINT)style & 1); - _U_SINT is_trait = !should_be_trait; - _U_SINT trait_index = (_U_SINT)(style >> 1); - - UNITY_SKIP_EXECUTION; - - switch(style) - { - case UNITY_FLOAT_IS_INF: - case UNITY_FLOAT_IS_NOT_INF: - is_trait = isinf(actual) & ispos(actual); - break; - case UNITY_FLOAT_IS_NEG_INF: - case UNITY_FLOAT_IS_NOT_NEG_INF: - is_trait = isinf(actual) & isneg(actual); - break; - - case UNITY_FLOAT_IS_NAN: - case UNITY_FLOAT_IS_NOT_NAN: - is_trait = isnan(actual); - break; - - /* A determinate number is non infinite and not NaN. (therefore the opposite of the two above) */ - case UNITY_FLOAT_IS_DET: - case UNITY_FLOAT_IS_NOT_DET: - if (isinf(actual) | isnan(actual)) - is_trait = 0; - else - is_trait = 1; - break; - - default: - trait_index = 0; - trait_names[0] = UnityStrInvalidFloatTrait; - break; - } - - if (is_trait != should_be_trait) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - if (!should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); - UnityPrint(UnityStrWas); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrintFloat(actual); -#else - if (should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -#endif /* not UNITY_EXCLUDE_FLOAT */ - -/*-----------------------------------------------*/ -#ifndef UNITY_EXCLUDE_DOUBLE -static int UnityDoublesWithin(_UD delta, _UD expected, _UD actual) -{ - _UD diff; - UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); -} - -void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, - UNITY_PTR_ATTRIBUTE const _UD* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 elements = num_elements; - UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected; - UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityPrintPointlessAndBail(); - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat((float)(*ptr_expected)); - UnityPrint(UnityStrWas); - UnityPrintFloat((float)(*ptr_actual)); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_expected++; - ptr_actual++; - } -} - -/*-----------------------------------------------*/ -void UnityAssertDoublesWithin(const _UD delta, - const _UD expected, - const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_SKIP_EXECUTION; - - if (!UnityDoublesWithin(delta, expected, actual)) - { - UnityTestResultsFailBegin(lineNumber); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat((float)expected); - UnityPrint(UnityStrWas); - UnityPrintFloat((float)actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -/*-----------------------------------------------*/ - -void UnityAssertDoubleSpecial(const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style) -{ - const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; - _U_SINT should_be_trait = ((_U_SINT)style & 1); - _U_SINT is_trait = !should_be_trait; - _U_SINT trait_index = (_U_SINT)(style >> 1); - - UNITY_SKIP_EXECUTION; - - switch(style) - { - case UNITY_FLOAT_IS_INF: - case UNITY_FLOAT_IS_NOT_INF: - is_trait = isinf(actual) & ispos(actual); - break; - case UNITY_FLOAT_IS_NEG_INF: - case UNITY_FLOAT_IS_NOT_NEG_INF: - is_trait = isinf(actual) & isneg(actual); - break; - - case UNITY_FLOAT_IS_NAN: - case UNITY_FLOAT_IS_NOT_NAN: - is_trait = isnan(actual); - break; - - /* A determinate number is non infinite and not NaN. (therefore the opposite of the two above) */ - case UNITY_FLOAT_IS_DET: - case UNITY_FLOAT_IS_NOT_DET: - if (isinf(actual) | isnan(actual)) - is_trait = 0; - else - is_trait = 1; - break; - - default: - trait_index = 0; - trait_names[0] = UnityStrInvalidFloatTrait; - break; - } - - if (is_trait != should_be_trait) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - if (!should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); - UnityPrint(UnityStrWas); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrintFloat(actual); -#else - if (should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - - -#endif /* not UNITY_EXCLUDE_DOUBLE */ - -/*-----------------------------------------------*/ -void UnityAssertNumbersWithin( const _U_UINT delta, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - UNITY_SKIP_EXECUTION; - - if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) - { - if (actual > expected) - Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > delta); - else - Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > delta); - } - else - { - if ((_U_UINT)actual > (_U_UINT)expected) - Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > delta); - else - Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > delta); - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrDelta); - UnityPrintNumberByStyle((_U_SINT)delta, style); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(expected, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(actual, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -/*-----------------------------------------------*/ -void UnityAssertEqualString(const char* expected, - const char* actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i; - - UNITY_SKIP_EXECUTION; - - /* if both pointers not null compare the strings */ - if (expected && actual) - { - for (i = 0; expected[i] || actual[i]; i++) - { - if (expected[i] != actual[i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { /* handle case of one pointers being null (if both null, test should pass) */ - if (expected != actual) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrintExpectedAndActualStrings(expected, actual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -/*-----------------------------------------------*/ -void UnityAssertEqualStringLen(const char* expected, - const char* actual, - const _UU32 length, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i; - - UNITY_SKIP_EXECUTION; - - /* if both pointers not null compare the strings */ - if (expected && actual) - { - for (i = 0; (i < length) && (expected[i] || actual[i]); i++) - { - if (expected[i] != actual[i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { /* handle case of one pointers being null (if both null, test should pass) */ - if (expected != actual) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrintExpectedAndActualStringsLen(expected, actual, length); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - - -/*-----------------------------------------------*/ -void UnityAssertEqualStringArray( const char** expected, - const char** actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i, j = 0; - - UNITY_SKIP_EXECUTION; - - /* if no elements, it's an error */ - if (num_elements == 0) - { - UnityPrintPointlessAndBail(); - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - do - { - /* if both pointers not null compare the strings */ - if (expected[j] && actual[j]) - { - for (i = 0; expected[j][i] || actual[j][i]; i++) - { - if (expected[j][i] != actual[j][i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { /* handle case of one pointers being null (if both null, test should pass) */ - if (expected[j] != actual[j]) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - if (num_elements > 1) - { - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(j); - } - UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j])); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - } while (++j < num_elements); -} - -/*-----------------------------------------------*/ -void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, - UNITY_INTERNAL_PTR actual, - const _UU32 length, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; - UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; - _UU32 elements = num_elements; - _UU32 bytes; - - UNITY_SKIP_EXECUTION; - - if ((elements == 0) || (length == 0)) - { - UnityPrintPointlessAndBail(); - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - bytes = length; - while (bytes--) - { - if (*ptr_exp != *ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrMemory); - if (num_elements > 1) - { - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); - } - UnityPrint(UnityStrByte); - UnityPrintNumberUnsigned(length - bytes - 1); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 1); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 1); - } - } -} - -/*----------------------------------------------- - * Control Functions - *-----------------------------------------------*/ - -void UnityFail(const char* msg, const UNITY_LINE_TYPE line) -{ - UNITY_SKIP_EXECUTION; - - UnityTestResultsBegin(Unity.TestFile, line); - UnityPrintFail(); - if (msg != NULL) - { - UNITY_OUTPUT_CHAR(':'); - -#ifndef UNITY_EXCLUDE_DETAILS - if (Unity.CurrentDetail1) - { - UnityPrint(UnityStrDetail1Name); - UnityPrint(Unity.CurrentDetail1); - if (Unity.CurrentDetail2) - { - UnityPrint(UnityStrDetail2Name); - UnityPrint(Unity.CurrentDetail2); - } - UnityPrint(UnityStrSpacer); - } -#endif - if (msg[0] != ' ') - { - UNITY_OUTPUT_CHAR(' '); - } - UnityPrint(msg); - } - - UNITY_FAIL_AND_BAIL; -} - -/*-----------------------------------------------*/ -void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) -{ - UNITY_SKIP_EXECUTION; - - UnityTestResultsBegin(Unity.TestFile, line); - UnityPrint(UnityStrIgnore); - if (msg != NULL) - { - UNITY_OUTPUT_CHAR(':'); - UNITY_OUTPUT_CHAR(' '); - UnityPrint(msg); - } - UNITY_IGNORE_AND_BAIL; -} - -/*-----------------------------------------------*/ -#if defined(UNITY_WEAK_ATTRIBUTE) - UNITY_WEAK_ATTRIBUTE void setUp(void) { } - UNITY_WEAK_ATTRIBUTE void tearDown(void) { } -#elif defined(UNITY_WEAK_PRAGMA) -# pragma weak setUp - void setUp(void) { } -# pragma weak tearDown - void tearDown(void) { } -#endif -/*-----------------------------------------------*/ -void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) -{ - Unity.CurrentTestName = FuncName; - Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; - Unity.NumberOfTests++; - UNITY_CLR_DETAILS(); - if (TEST_PROTECT()) - { - setUp(); - Func(); - } - if (TEST_PROTECT() && !(Unity.CurrentTestIgnored)) - { - tearDown(); - } - UnityConcludeTest(); -} - -/*-----------------------------------------------*/ -void UnityBegin(const char* filename) -{ - Unity.TestFile = filename; - Unity.CurrentTestName = NULL; - Unity.CurrentTestLineNumber = 0; - Unity.NumberOfTests = 0; - Unity.TestFailures = 0; - Unity.TestIgnores = 0; - Unity.CurrentTestFailed = 0; - Unity.CurrentTestIgnored = 0; - - UNITY_CLR_DETAILS(); - UNITY_OUTPUT_START(); -} - -/*-----------------------------------------------*/ -int UnityEnd(void) -{ - UNITY_PRINT_EOL(); - UnityPrint(UnityStrBreaker); - UNITY_PRINT_EOL(); - UnityPrintNumber((_U_SINT)(Unity.NumberOfTests)); - UnityPrint(UnityStrResultsTests); - UnityPrintNumber((_U_SINT)(Unity.TestFailures)); - UnityPrint(UnityStrResultsFailures); - UnityPrintNumber((_U_SINT)(Unity.TestIgnores)); - UnityPrint(UnityStrResultsIgnored); - UNITY_PRINT_EOL(); - if (Unity.TestFailures == 0U) - { - UnityPrintOk(); - } - else - { - UnityPrintFail(); -#ifdef UNITY_DIFFERENTIATE_FINAL_FAIL - UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D'); -#endif - } - UNITY_PRINT_EOL(); - UNITY_FLUSH_CALL(); - UNITY_OUTPUT_COMPLETE(); - return (int)(Unity.TestFailures); -} - -/*----------------------------------------------- - * Command Line Argument Support - *-----------------------------------------------*/ -#ifdef UNITY_USE_COMMAND_LINE_ARGS - -char* UnityOptionIncludeNamed = NULL; -char* UnityOptionExcludeNamed = NULL; -int UnityVerbosity = 1; - -int UnityParseOptions(int argc, char** argv) -{ - UnityOptionIncludeNamed = NULL; - UnityOptionExcludeNamed = NULL; - - for (int i = 1; i < argc; i++) - { - if (argv[i][0] == '-') - { - switch(argv[i][1]) - { - case 'l': /* list tests */ - return -1; - case 'n': /* include tests with name including this string */ - case 'f': /* an alias for -n */ - if (argv[i][2] == '=') - UnityOptionIncludeNamed = &argv[i][3]; - else if (++i < argc) - UnityOptionIncludeNamed = argv[i]; - else - { - UnityPrint("ERROR: No Test String to Include Matches For"); - UNITY_PRINT_EOL(); - return 1; - } - break; - case 'q': /* quiet */ - UnityVerbosity = 0; - break; - case 'v': /* verbose */ - UnityVerbosity = 2; - break; - case 'x': /* exclude tests with name including this string */ - if (argv[i][2] == '=') - UnityOptionExcludeNamed = &argv[i][3]; - else if (++i < argc) - UnityOptionExcludeNamed = argv[i]; - else - { - UnityPrint("ERROR: No Test String to Exclude Matches For"); - UNITY_PRINT_EOL(); - return 1; - } - break; - default: - UnityPrint("ERROR: Unknown Option "); - UNITY_OUTPUT_CHAR(argv[i][1]); - UNITY_PRINT_EOL(); - return 1; - } - } - } - - return 0; -} - -int IsStringInBiggerString(const char* longstring, const char* shortstring) -{ - char* lptr = (char*)longstring; - char* sptr = (char*)shortstring; - char* lnext = lptr; - - if (*sptr == '*') - return 1; - - while (*lptr) - { - lnext = lptr + 1; - - /* If they current bytes match, go on to the next bytes */ - while (*lptr && *sptr && (*lptr == *sptr)) - { - lptr++; - sptr++; - - /* We're done if we match the entire string or up to a wildcard */ - if (*sptr == '*') - return 1; - if (*sptr == ',') - return 1; - if (*sptr == '"') - return 1; - if (*sptr == '\'') - return 1; - if (*sptr == ':') - return 2; - if (*sptr == 0) - return 1; - } - - /* Otherwise we start in the long pointer 1 character further and try again */ - lptr = lnext; - sptr = (char*)shortstring; - } - return 0; -} - -int UnityStringArgumentMatches(const char* str) -{ - int retval; - const char* ptr1; - const char* ptr2; - const char* ptrf; - - /* Go through the options and get the substrings for matching one at a time */ - ptr1 = str; - while (ptr1[0] != 0) - { - if ((ptr1[0] == '"') || (ptr1[0] == '\'')) - ptr1++; - - /* look for the start of the next partial */ - ptr2 = ptr1; - ptrf = 0; - do { - ptr2++; - if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')) - ptrf = &ptr2[1]; - } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')); - while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ','))) - ptr2++; - - /* done if complete filename match */ - retval = IsStringInBiggerString(Unity.TestFile, ptr1); - if (retval == 1) - return retval; - - /* done if testname match after filename partial match */ - if ((retval == 2) && (ptrf != 0)) - { - if (IsStringInBiggerString(Unity.CurrentTestName, ptrf)) - return 1; - } - - /* done if complete testname match */ - if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1) - return 1; - - ptr1 = ptr2; - } - - /* we couldn't find a match for any substrings */ - return 0; -} - -int UnityTestMatches(void) -{ - /* Check if this test name matches the included test pattern */ - int retval; - if (UnityOptionIncludeNamed) - { - retval = UnityStringArgumentMatches(UnityOptionIncludeNamed); - } - else - retval = 1; - - /* Check if this test name matches the excluded test pattern */ - if (UnityOptionExcludeNamed) - { - if (UnityStringArgumentMatches(UnityOptionExcludeNamed)) - retval = 0; - } - return retval; -} - -#endif /* UNITY_USE_COMMAND_LINE_ARGS */ -/*-----------------------------------------------*/ diff --git a/test/unity/unity.h b/test/unity/unity.h deleted file mode 100644 index 031ccc92..00000000 --- a/test/unity/unity.h +++ /dev/null @@ -1,293 +0,0 @@ -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#ifndef UNITY_FRAMEWORK_H -#define UNITY_FRAMEWORK_H -#define UNITY - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "unity_internals.h" - -void setUp(void); -void tearDown(void); - -/*------------------------------------------------------- - * Configuration Options - *------------------------------------------------------- - * All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above. - - * Integers/longs/pointers - * - Unity attempts to automatically discover your integer sizes - * - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in - * - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in - * - If you cannot use the automatic methods above, you can force Unity by using these options: - * - define UNITY_SUPPORT_64 - * - set UNITY_INT_WIDTH - * - set UNITY_LONG_WIDTH - * - set UNITY_POINTER_WIDTH - - * Floats - * - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons - * - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT - * - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats - * - define UNITY_FLOAT_VERBOSE to print floating point values in errors (uses sprintf) - * - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons - * - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default) - * - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE - * - define UNITY_DOUBLE_TYPE to specify something other than double - * - define UNITY_DOUBLE_VERBOSE to print floating point values in errors (uses sprintf) - * - define UNITY_VERBOSE_NUMBER_MAX_LENGTH to change maximum length of printed numbers (used by sprintf) - - * Output - * - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired - * - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure - - * Optimization - * - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge - * - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests. - - * Test Cases - * - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script - - * Parameterized Tests - * - you'll want to create a define of TEST_CASE(...) which basically evaluates to nothing - - * Tests with Arguments - * - you'll want to define UNITY_USE_COMMAND_LINE_ARGS if you have the test runner passing arguments to Unity - - *------------------------------------------------------- - * Basic Fail and Ignore - *-------------------------------------------------------*/ - -#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, (message)) -#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL) -#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message)) -#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL) -#define TEST_ONLY() - -/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails. - * This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */ -#define TEST_PASS() longjmp(Unity.AbortFrame, 1) - -/*------------------------------------------------------- - * Test Asserts (simple) - *-------------------------------------------------------*/ - -/* Boolean */ -#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE") -#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE") -#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE") -#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE") -#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL") -#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL") - -/* Integers (of all sizes) */ -#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") -#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, NULL) -#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, NULL) -#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(-1), (actual), __LINE__, NULL) -#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(0), (actual), __LINE__, NULL) - -/* Integer Ranges (of all sizes) */ -#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL) - -/* Structs and Strings */ -#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, NULL) - -/* Arrays */ -#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL) - -/* Floating Point (If Enabled) */ -#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, NULL) - -/* Double (If Enabled) */ -#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL) - -/*------------------------------------------------------- - * Test Asserts (with additional messages) - *-------------------------------------------------------*/ - -/* Boolean */ -#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) -#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) -#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) -#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) -#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, (message)) -#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, (message)) - -/* Integers (of all sizes) */ -#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, (message)) -#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, (message)) -#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(-1), (actual), __LINE__, (message)) -#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(0), (actual), __LINE__, (message)) - -/* Integer Ranges (of all sizes) */ -#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message)) - -/* Structs and Strings */ -#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, (message)) - -/* Arrays */ -#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message)) - -/* Floating Point (If Enabled) */ -#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, (message)) - -/* Double (If Enabled) */ -#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message)) - -/* end of UNITY_FRAMEWORK_H */ -#ifdef __cplusplus -} -#endif -#endif diff --git a/test/unity/unity_internals.h b/test/unity/unity_internals.h deleted file mode 100644 index 8ccd66d5..00000000 --- a/test/unity/unity_internals.h +++ /dev/null @@ -1,749 +0,0 @@ -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#ifndef UNITY_INTERNALS_H -#define UNITY_INTERNALS_H - -#ifdef UNITY_INCLUDE_CONFIG_H -#include "unity_config.h" -#endif - -#include - -#ifndef UNITY_EXCLUDE_MATH_H -#include -#endif - -/* Unity Attempts to Auto-Detect Integer Types - * Attempt 1: UINT_MAX, ULONG_MAX in , or default to 32 bits - * Attempt 2: UINTPTR_MAX in , or default to same size as long - * The user may override any of these derived constants: - * UNITY_INT_WIDTH, UNITY_LONG_WIDTH, UNITY_POINTER_WIDTH */ -#ifndef UNITY_EXCLUDE_STDINT_H -#include -#endif - -#ifndef UNITY_EXCLUDE_LIMITS_H -#include -#endif - -/*------------------------------------------------------- - * Guess Widths If Not Specified - *-------------------------------------------------------*/ - -/* Determine the size of an int, if not already specified. - * We cannot use sizeof(int), because it is not yet defined - * at this stage in the translation of the C program. - * Therefore, infer it from UINT_MAX if possible. */ -#ifndef UNITY_INT_WIDTH - #ifdef UINT_MAX - #if (UINT_MAX == 0xFFFF) - #define UNITY_INT_WIDTH (16) - #elif (UINT_MAX == 0xFFFFFFFF) - #define UNITY_INT_WIDTH (32) - #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF) - #define UNITY_INT_WIDTH (64) - #endif - #else /* Set to default */ - #define UNITY_INT_WIDTH (32) - #endif /* UINT_MAX */ -#endif - -/* Determine the size of a long, if not already specified. */ -#ifndef UNITY_LONG_WIDTH - #ifdef ULONG_MAX - #if (ULONG_MAX == 0xFFFF) - #define UNITY_LONG_WIDTH (16) - #elif (ULONG_MAX == 0xFFFFFFFF) - #define UNITY_LONG_WIDTH (32) - #elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF) - #define UNITY_LONG_WIDTH (64) - #endif - #else /* Set to default */ - #define UNITY_LONG_WIDTH (32) - #endif /* ULONG_MAX */ -#endif - -/* Determine the size of a pointer, if not already specified. */ -#ifndef UNITY_POINTER_WIDTH - #ifdef UINTPTR_MAX - #if (UINTPTR_MAX <= 0xFFFF) - #define UNITY_POINTER_WIDTH (16) - #elif (UINTPTR_MAX <= 0xFFFFFFFF) - #define UNITY_POINTER_WIDTH (32) - #elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF) - #define UNITY_POINTER_WIDTH (64) - #endif - #else /* Set to default */ - #define UNITY_POINTER_WIDTH UNITY_LONG_WIDTH - #endif /* UINTPTR_MAX */ -#endif - -/*------------------------------------------------------- - * Int Support (Define types based on detected sizes) - *-------------------------------------------------------*/ - -#if (UNITY_INT_WIDTH == 32) - typedef unsigned char _UU8; - typedef unsigned short _UU16; - typedef unsigned int _UU32; - typedef signed char _US8; - typedef signed short _US16; - typedef signed int _US32; -#elif (UNITY_INT_WIDTH == 16) - typedef unsigned char _UU8; - typedef unsigned int _UU16; - typedef unsigned long _UU32; - typedef signed char _US8; - typedef signed int _US16; - typedef signed long _US32; -#else - #error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported) -#endif - -/*------------------------------------------------------- - * 64-bit Support - *-------------------------------------------------------*/ - -#ifndef UNITY_SUPPORT_64 - #if UNITY_LONG_WIDTH == 64 || UNITY_POINTER_WIDTH == 64 - #define UNITY_SUPPORT_64 - #endif -#endif - -#ifndef UNITY_SUPPORT_64 - /* No 64-bit Support */ - typedef _UU32 _U_UINT; - typedef _US32 _U_SINT; -#else - - /* 64-bit Support */ - #if (UNITY_LONG_WIDTH == 32) - typedef unsigned long long _UU64; - typedef signed long long _US64; - #elif (UNITY_LONG_WIDTH == 64) - typedef unsigned long _UU64; - typedef signed long _US64; - #else - #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported) - #endif - typedef _UU64 _U_UINT; - typedef _US64 _U_SINT; - -#endif - -/*------------------------------------------------------- - * Pointer Support - *-------------------------------------------------------*/ - -#if (UNITY_POINTER_WIDTH == 32) - typedef _UU32 _UP; -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 -#elif (UNITY_POINTER_WIDTH == 64) - typedef _UU64 _UP; -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 -#elif (UNITY_POINTER_WIDTH == 16) - typedef _UU16 _UP; -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 -#else - #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) -#endif - -#ifndef UNITY_PTR_ATTRIBUTE -#define UNITY_PTR_ATTRIBUTE -#endif - -#ifndef UNITY_INTERNAL_PTR -#define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const void* -/* #define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const _UU8* */ -#endif - -/*------------------------------------------------------- - * Float Support - *-------------------------------------------------------*/ - -#ifdef UNITY_EXCLUDE_FLOAT - -/* No Floating Point Support */ -#undef UNITY_INCLUDE_FLOAT -#undef UNITY_FLOAT_PRECISION -#undef UNITY_FLOAT_TYPE -#undef UNITY_FLOAT_VERBOSE - -#else - -#ifndef UNITY_INCLUDE_FLOAT -#define UNITY_INCLUDE_FLOAT -#endif - -/* Floating Point Support */ -#ifndef UNITY_FLOAT_PRECISION -#define UNITY_FLOAT_PRECISION (0.00001f) -#endif -#ifndef UNITY_FLOAT_TYPE -#define UNITY_FLOAT_TYPE float -#endif -typedef UNITY_FLOAT_TYPE _UF; - -#ifndef isinf -/* The value of Inf - Inf is NaN */ -#define isinf(n) (isnan((n) - (n)) && !isnan(n)) -#endif - -#ifndef isnan -/* NaN is the only floating point value that does NOT equal itself. - * Therefore if n != n, then it is NaN. */ -#define isnan(n) ((n != n) ? 1 : 0) -#endif - -#ifndef isneg -#define isneg(n) ((n < 0.0f) ? 1 : 0) -#endif - -#ifndef ispos -#define ispos(n) ((n > 0.0f) ? 1 : 0) -#endif - -#endif - -/*------------------------------------------------------- - * Double Float Support - *-------------------------------------------------------*/ - -/* unlike FLOAT, we DON'T include by default */ -#ifndef UNITY_EXCLUDE_DOUBLE - #ifndef UNITY_INCLUDE_DOUBLE - #define UNITY_EXCLUDE_DOUBLE - #endif -#endif - -#ifdef UNITY_EXCLUDE_DOUBLE - - /* No Floating Point Support */ - #undef UNITY_DOUBLE_PRECISION - #undef UNITY_DOUBLE_TYPE - #undef UNITY_DOUBLE_VERBOSE - - #ifdef UNITY_INCLUDE_DOUBLE - #undef UNITY_INCLUDE_DOUBLE - #endif - - #ifdef UNITY_FLOAT_VERBOSE - typedef _UF _UD; - /* For parameter in UnityPrintFloat, double promotion required */ - #endif - -#else - - /* Double Floating Point Support */ - #ifndef UNITY_DOUBLE_PRECISION - #define UNITY_DOUBLE_PRECISION (1e-12f) - #endif - - #ifndef UNITY_DOUBLE_TYPE - #define UNITY_DOUBLE_TYPE double - #endif - typedef UNITY_DOUBLE_TYPE _UD; - -#endif - -#ifdef UNITY_DOUBLE_VERBOSE -#ifndef UNITY_FLOAT_VERBOSE -#define UNITY_FLOAT_VERBOSE -#endif -#endif - -/*------------------------------------------------------- - * Output Method: stdout (DEFAULT) - *-------------------------------------------------------*/ -#ifndef UNITY_OUTPUT_CHAR -/* Default to using putchar, which is defined in stdio.h */ -#include -#define UNITY_OUTPUT_CHAR(a) (void)putchar(a) -#else - /* If defined as something else, make sure we declare it here so it's ready for use */ - #ifndef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION -extern void UNITY_OUTPUT_CHAR(int); - #endif -#endif - -#ifndef UNITY_OUTPUT_FLUSH -/* Default to using fflush, which is defined in stdio.h */ -#include -#define UNITY_OUTPUT_FLUSH (void)fflush(stdout) -#else - /* If defined as something else, make sure we declare it here so it's ready for use */ - #ifndef UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION -extern void UNITY_OUTPUT_FLUSH(void); - #endif -#endif - -#ifndef UNITY_OUTPUT_FLUSH -#define UNITY_FLUSH_CALL() -#else -#define UNITY_FLUSH_CALL() UNITY_OUTPUT_FLUSH -#endif - -#ifndef UNITY_PRINT_EOL -#define UNITY_PRINT_EOL() UNITY_OUTPUT_CHAR('\n') -#endif - -#ifndef UNITY_OUTPUT_START -#define UNITY_OUTPUT_START() -#endif - -#ifndef UNITY_OUTPUT_COMPLETE -#define UNITY_OUTPUT_COMPLETE() -#endif - -/*------------------------------------------------------- - * Footprint - *-------------------------------------------------------*/ - -#ifndef UNITY_LINE_TYPE -#define UNITY_LINE_TYPE _U_UINT -#endif - -#ifndef UNITY_COUNTER_TYPE -#define UNITY_COUNTER_TYPE _U_UINT -#endif - -/*------------------------------------------------------- - * Language Features Available - *-------------------------------------------------------*/ -#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA) -# ifdef __GNUC__ /* includes clang */ -# if !(defined(__WIN32__) && defined(__clang__)) && !defined(__TMS470__) -# define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) -# endif -# endif -#endif - -#ifdef UNITY_NO_WEAK -# undef UNITY_WEAK_ATTRIBUTE -# undef UNITY_WEAK_PRAGMA -#endif - - -/*------------------------------------------------------- - * Internal Structs Needed - *-------------------------------------------------------*/ - -typedef void (*UnityTestFunction)(void); - -#define UNITY_DISPLAY_RANGE_INT (0x10) -#define UNITY_DISPLAY_RANGE_UINT (0x20) -#define UNITY_DISPLAY_RANGE_HEX (0x40) -#define UNITY_DISPLAY_RANGE_AUTO (0x80) - -typedef enum -{ -UNITY_DISPLAY_STYLE_INT = sizeof(int)+ UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, - UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT, - UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT, - UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT, -#ifdef UNITY_SUPPORT_64 - UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT, -#endif - -UNITY_DISPLAY_STYLE_UINT = sizeof(unsigned) + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, - UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT, - UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT, - UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT, -#ifdef UNITY_SUPPORT_64 - UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT, -#endif - - UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX, - UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX, - UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX, -#ifdef UNITY_SUPPORT_64 - UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX, -#endif - - UNITY_DISPLAY_STYLE_UNKNOWN -} UNITY_DISPLAY_STYLE_T; - -#ifndef UNITY_EXCLUDE_FLOAT -typedef enum _UNITY_FLOAT_TRAIT_T -{ - UNITY_FLOAT_IS_NOT_INF = 0, - UNITY_FLOAT_IS_INF, - UNITY_FLOAT_IS_NOT_NEG_INF, - UNITY_FLOAT_IS_NEG_INF, - UNITY_FLOAT_IS_NOT_NAN, - UNITY_FLOAT_IS_NAN, - UNITY_FLOAT_IS_NOT_DET, - UNITY_FLOAT_IS_DET, - UNITY_FLOAT_INVALID_TRAIT -} UNITY_FLOAT_TRAIT_T; -#endif - -struct _Unity -{ - const char* TestFile; - const char* CurrentTestName; -#ifndef UNITY_EXCLUDE_DETAILS - const char* CurrentDetail1; - const char* CurrentDetail2; -#endif - UNITY_LINE_TYPE CurrentTestLineNumber; - UNITY_COUNTER_TYPE NumberOfTests; - UNITY_COUNTER_TYPE TestFailures; - UNITY_COUNTER_TYPE TestIgnores; - UNITY_COUNTER_TYPE CurrentTestFailed; - UNITY_COUNTER_TYPE CurrentTestIgnored; - jmp_buf AbortFrame; -}; - -extern struct _Unity Unity; - -/*------------------------------------------------------- - * Test Suite Management - *-------------------------------------------------------*/ - -void UnityBegin(const char* filename); -int UnityEnd(void); -void UnityConcludeTest(void); -void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum); - -/*------------------------------------------------------- - * Details Support - *-------------------------------------------------------*/ - -#ifdef UNITY_EXCLUDE_DETAILS -#define UNITY_CLR_DETAILS() -#define UNITY_SET_DETAIL(d1) -#define UNITY_SET_DETAILS(d1,d2) -#else -#define UNITY_CLR_DETAILS() { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } -#define UNITY_SET_DETAIL(d1) { Unity.CurrentDetail1 = d1; Unity.CurrentDetail2 = 0; } -#define UNITY_SET_DETAILS(d1,d2) { Unity.CurrentDetail1 = d1; Unity.CurrentDetail2 = d2; } - -#ifndef UNITY_DETAIL1_NAME -#define UNITY_DETAIL1_NAME "Function" -#endif - -#ifndef UNITY_DETAIL2_NAME -#define UNITY_DETAIL2_NAME "Argument" -#endif -#endif - -/*------------------------------------------------------- - * Test Output - *-------------------------------------------------------*/ - -void UnityPrint(const char* string); -void UnityPrintMask(const _U_UINT mask, const _U_UINT number); -void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style); -void UnityPrintNumber(const _U_SINT number); -void UnityPrintNumberUnsigned(const _U_UINT number); -void UnityPrintNumberHex(const _U_UINT number, const char nibbles); - -#ifdef UNITY_FLOAT_VERBOSE -void UnityPrintFloat(const _UD number); -#endif - -/*------------------------------------------------------- - * Test Assertion Functions - *------------------------------------------------------- - * Use the macros below this section instead of calling - * these directly. The macros have a consistent naming - * convention and will pull in file and line information - * for you. */ - -void UnityAssertEqualNumber(const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style); - -void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, - UNITY_INTERNAL_PTR actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style); - -void UnityAssertBits(const _U_SINT mask, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualString(const char* expected, - const char* actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualStringLen(const char* expected, - const char* actual, - const _UU32 length, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualStringArray( const char** expected, - const char** actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, - UNITY_INTERNAL_PTR actual, - const _UU32 length, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertNumbersWithin(const _U_UINT delta, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style); - -void UnityFail(const char* message, const UNITY_LINE_TYPE line); - -void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); - -#ifndef UNITY_EXCLUDE_FLOAT -void UnityAssertFloatsWithin(const _UF delta, - const _UF expected, - const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, - UNITY_PTR_ATTRIBUTE const _UF* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertFloatSpecial(const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style); -#endif - -#ifndef UNITY_EXCLUDE_DOUBLE -void UnityAssertDoublesWithin(const _UD delta, - const _UD expected, - const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, - UNITY_PTR_ATTRIBUTE const _UD* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertDoubleSpecial(const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style); -#endif - -/*------------------------------------------------------- - * Error Strings We Might Need - *-------------------------------------------------------*/ - -extern const char UnityStrErrFloat[]; -extern const char UnityStrErrDouble[]; -extern const char UnityStrErr64[]; - -/*------------------------------------------------------- - * Test Running Macros - *-------------------------------------------------------*/ - -#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0) - -#define TEST_ABORT() {longjmp(Unity.AbortFrame, 1);} - -/* This tricky series of macros gives us an optional line argument to treat it as RUN_TEST(func, num=__LINE__) */ -#ifndef RUN_TEST -#ifdef __STDC_VERSION__ -#if __STDC_VERSION__ >= 199901L -#define RUN_TEST(...) UnityDefaultTestRun(RUN_TEST_FIRST(__VA_ARGS__), RUN_TEST_SECOND(__VA_ARGS__)) -#define RUN_TEST_FIRST(...) RUN_TEST_FIRST_HELPER(__VA_ARGS__, throwaway) -#define RUN_TEST_FIRST_HELPER(first, ...) (first), #first -#define RUN_TEST_SECOND(...) RUN_TEST_SECOND_HELPER(__VA_ARGS__, __LINE__, throwaway) -#define RUN_TEST_SECOND_HELPER(first, second, ...) (second) -#endif -#endif -#endif - -/* If we can't do the tricky version, we'll just have to require them to always include the line number */ -#ifndef RUN_TEST -#ifdef CMOCK -#define RUN_TEST(func, num) UnityDefaultTestRun(func, #func, num) -#else -#define RUN_TEST(func) UnityDefaultTestRun(func, #func, __LINE__) -#endif -#endif - -#define TEST_LINE_NUM (Unity.CurrentTestLineNumber) -#define TEST_IS_IGNORED (Unity.CurrentTestIgnored) -#define UNITY_NEW_TEST(a) \ - Unity.CurrentTestName = (a); \ - Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)(__LINE__); \ - Unity.NumberOfTests++; - -#ifndef UNITY_BEGIN -#define UNITY_BEGIN() UnityBegin(__FILE__) -#endif - -#ifndef UNITY_END -#define UNITY_END() UnityEnd() -#endif - -#define UNITY_UNUSED(x) (void)(sizeof(x)) - -/*----------------------------------------------- - * Command Line Argument Support - *-----------------------------------------------*/ - -#ifdef UNITY_USE_COMMAND_LINE_ARGS -int UnityParseOptions(int argc, char** argv); -int UnityTestMatches(void); -#endif - -/*------------------------------------------------------- - * Basic Fail and Ignore - *-------------------------------------------------------*/ - -#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)(line)) - -/*------------------------------------------------------- - * Test Asserts - *-------------------------------------------------------*/ - -#define UNITY_TEST_ASSERT(condition, line, message) if (condition) {} else {UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), (message));} -#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)(line), (message)) -#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)(line), (message)) - -#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) -#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU8 )(expected), (_U_SINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) -#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU16)(expected), (_U_SINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) -#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU32)(expected), (_U_SINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) -#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) -#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) -#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) -#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((_U_SINT)(mask), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line)) - -#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU8 )(delta), (_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU16)(delta), (_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU32)(delta), (_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) -#define UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) -#define UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) -#define UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) -#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) -#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) -#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) - -#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UP)(expected), (_U_SINT)(_UP)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) -#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len, line, message) UnityAssertEqualStringLen((const char*)(expected), (const char*)(actual), (_UU32)(len), (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(len), 1, (message), (UNITY_LINE_TYPE)(line)) - -#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) -#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) -#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) -#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) -#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) -#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) -#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) -#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(_UP*)(expected), (UNITY_INTERNAL_PTR)(_UP*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) -#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((const char**)(expected), (const char**)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(len), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line)) - -#ifdef UNITY_SUPPORT_64 -#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) -#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) -#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) -#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) -#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) -#else -#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#endif - -#ifdef UNITY_EXCLUDE_FLOAT -#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#else -#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((_UF)(delta), (_UF)(expected), (_UF)(actual), (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((_UF)(expected) * (_UF)UNITY_FLOAT_PRECISION, (_UF)(expected), (_UF)(actual), (UNITY_LINE_TYPE)(line), (message)) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((_UF*)(expected), (_UF*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) -#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) -#endif - -#ifdef UNITY_EXCLUDE_DOUBLE -#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#else -#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((_UD)(delta), (_UD)(expected), (_UD)(actual), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((_UD)(expected) * (_UD)UNITY_DOUBLE_PRECISION, (_UD)expected, (_UD)actual, (UNITY_LINE_TYPE)(line), message) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((_UD*)(expected), (_UD*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) -#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) -#endif - -/* End of UNITY_INTERNALS_H */ -#endif