mirror of
				https://git.wownero.com/wownero/RandomWOW.git
				synced 2024-08-15 00:23:14 +00:00 
			
		
		
		
	Merge pull request #182 from tevador/pr-restore-fpstate
Preserve floating point state when calling randomx_calculate_hash
This commit is contained in:
		
						commit
						7741eb1e97
					
				
					 5 changed files with 39 additions and 0 deletions
				
			
		|  | @ -157,6 +157,21 @@ void rx_set_rounding_mode(uint32_t mode) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| uint32_t rx_get_rounding_mode() { | ||||
| 	switch (fegetround()) { | ||||
| 	case FE_DOWNWARD: | ||||
| 		return RoundDown; | ||||
| 	case FE_UPWARD: | ||||
| 		return RoundUp; | ||||
| 	case FE_TOWARDZERO: | ||||
| 		return RoundToZero; | ||||
| 	case FE_TONEAREST: | ||||
| 		return RoundToNearest; | ||||
| 	default: | ||||
| 		UNREACHABLE; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef RANDOMX_USE_X87 | ||||
|  |  | |||
|  | @ -173,6 +173,10 @@ FORCE_INLINE void rx_set_rounding_mode(uint32_t mode) { | |||
| 	_mm_setcsr(rx_mxcsr_default | (mode << 13)); | ||||
| } | ||||
| 
 | ||||
| FORCE_INLINE uint32_t rx_get_rounding_mode() { | ||||
| 	return (_mm_getcsr() >> 13) & 3; | ||||
| } | ||||
| 
 | ||||
| #elif defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) //sadly only POWER7 and newer will be able to use SIMD acceleration. Earlier processors cant use doubles or 64 bit integers with SIMD
 | ||||
| #include <cstdint> | ||||
| #include <stdexcept> | ||||
|  | @ -736,6 +740,8 @@ void rx_reset_float_state(); | |||
| 
 | ||||
| void rx_set_rounding_mode(uint32_t mode); | ||||
| 
 | ||||
| uint32_t rx_get_rounding_mode(); | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| double loadDoublePortable(const void* addr); | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| #include "cpu.hpp" | ||||
| #include <cassert> | ||||
| #include <limits> | ||||
| #include <cfenv> | ||||
| 
 | ||||
| extern "C" { | ||||
| 
 | ||||
|  | @ -349,6 +350,8 @@ extern "C" { | |||
| 		assert(machine != nullptr); | ||||
| 		assert(inputSize == 0 || input != nullptr); | ||||
| 		assert(output != nullptr); | ||||
| 		fenv_t fpstate; | ||||
| 		fegetenv(&fpstate); | ||||
| 		alignas(16) uint64_t tempHash[8]; | ||||
| 		int blakeResult = blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0); | ||||
| 		assert(blakeResult == 0); | ||||
|  | @ -361,6 +364,7 @@ extern "C" { | |||
| 		} | ||||
| 		machine->run(&tempHash); | ||||
| 		machine->getFinalResult(output, RANDOMX_HASH_SIZE); | ||||
| 		fesetenv(&fpstate); | ||||
| 	} | ||||
| 
 | ||||
| 	void randomx_calculate_hash_first(randomx_vm* machine, const void* input, size_t inputSize) { | ||||
|  |  | |||
|  | @ -246,6 +246,8 @@ RANDOMX_EXPORT void randomx_calculate_hash(randomx_vm *machine, const void *inpu | |||
|  *                              and begin the calculation of the next hash. | ||||
|  * randomx_calculate_hash_last  will output the hash value of the previous input. | ||||
|  * | ||||
|  * WARNING: These functions may alter the floating point rounding mode of the calling thread. | ||||
|  * | ||||
|  * @param machine is a pointer to a randomx_vm structure. Must not be NULL. | ||||
|  * @param input is a pointer to memory to be hashed. Must not be NULL. | ||||
|  * @param inputSize is the number of bytes to be hashed. | ||||
|  |  | |||
|  | @ -1051,6 +1051,10 @@ int main() { | |||
| 		assert(cacheMemory[33554431] == 0x1f47f056d05cd99b); | ||||
| 	}); | ||||
| 
 | ||||
| 	if (cache != nullptr) | ||||
| 		randomx_release_cache(cache); | ||||
| 	cache = randomx_alloc_cache(RANDOMX_FLAG_DEFAULT); | ||||
| 
 | ||||
| 	runTest("Hash batch test", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), []() { | ||||
| 		char hash1[RANDOMX_HASH_SIZE]; | ||||
| 		char hash2[RANDOMX_HASH_SIZE]; | ||||
|  | @ -1070,6 +1074,14 @@ int main() { | |||
| 		assert(equalsHex(hash3, "c36d4ed4191e617309867ed66a443be4075014e2b061bcdaf9ce7b721d2b77a8")); | ||||
| 	}); | ||||
| 
 | ||||
| 	runTest("Preserve rounding mode", RANDOMX_FREQ_CFROUND > 0, []() { | ||||
| 		rx_set_rounding_mode(RoundToNearest); | ||||
| 		char hash[RANDOMX_HASH_SIZE]; | ||||
| 		calcStringHash("test key 000", "Lorem ipsum dolor sit amet", &hash); | ||||
| 		assert(equalsHex(hash, "300a0adb47603dedb42228ccb2b211104f4da45af709cd7547cd049e9489c969")); | ||||
| 		assert(rx_get_rounding_mode() == RoundToNearest); | ||||
| 	}); | ||||
| 
 | ||||
| 	randomx_destroy_vm(vm); | ||||
| 	vm = nullptr; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue