Przeglądaj źródła

Simplified division in interpreted mode
Fixed incorrect condition code in JitCompilerX86
Refactoring

tevador 7 lat temu
rodzic
commit
447e8a1d4f

+ 2 - 2
src/AssemblyGeneratorX86.cpp

@@ -431,8 +431,8 @@ namespace RandomX {
 		asmCode << "\tldmxcsr dword ptr [rsp-8]" << std::endl;
 	}
 
-	static inline const char* condition(Instruction& instr, bool invert = false) {
-		switch (((instr.mod >> 2) & 7) ^ invert)
+	static inline const char* condition(Instruction& instr) {
+		switch ((instr.mod >> 2) & 7)
 		{
 			case 0:
 				return "be";

+ 24 - 31
src/InterpretedVirtualMachine.cpp

@@ -33,7 +33,6 @@ along with RandomX.  If not, see<http://www.gnu.org/licenses/>.
 #ifdef STATS
 #include <algorithm>
 #endif
-#include "divideByConstantCodegen.h"
 
 #ifdef FPUCHECK
 constexpr bool fpuCheck = true;
@@ -136,25 +135,23 @@ namespace RandomX {
 			} break;
 
 			case InstructionType::IDIV_C: {
-				if (ibc.signedMultiplier != 0) {
-					int_reg_t dividend = *ibc.idst;
-					int_reg_t quotient = dividend >> ibc.preShift;
-					if (ibc.increment) {
-						quotient = quotient == UINT64_MAX ? UINT64_MAX : quotient + 1;
-					}
-					quotient = mulh(quotient, ibc.signedMultiplier);
-					quotient >>= ibc.postShift;
+				uint64_t dividend = *ibc.idst;
+				uint64_t quotient = dividend / ibc.imm;
+				*ibc.idst += quotient;
+			} break;
+
+			case InstructionType::ISDIV_C: {
+				if (ibc.simm != -1) {
+					int64_t dividend = unsigned64ToSigned2sCompl(*ibc.idst);
+					int64_t quotient = dividend / ibc.simm;
 					*ibc.idst += quotient;
 				}
 				else {
-					*ibc.idst += *ibc.idst >> ibc.shift;
+					uint64_t quotient = ~(*ibc.idst) + 1;
+					*ibc.idst += quotient;
 				}
 			} break;
 
-			case InstructionType::ISDIV_C: {
-
-			} break;
-
 			case InstructionType::INEG_R: {
 				*ibc.idst = ~(*ibc.idst) + 1; //two's complement negative
 			} break;
@@ -204,8 +201,8 @@ namespace RandomX {
 			} break;
 
 			case InstructionType::FSCAL_R: {
-				const __m128d signMask = _mm_castsi128_pd(_mm_set1_epi64x(0x81F0000000000000));
-				*ibc.fdst = _mm_xor_pd(*ibc.fdst, signMask);
+				const __m128d mask = _mm_castsi128_pd(_mm_set1_epi64x(0x81F0000000000000));
+				*ibc.fdst = _mm_xor_pd(*ibc.fdst, mask);
 			} break;
 
 			case InstructionType::FMUL_R: {
@@ -516,20 +513,7 @@ namespace RandomX {
 						auto dst = instr.dst % RegistersCount;
 						ibc.type = InstructionType::IDIV_C;
 						ibc.idst = &r[dst];
-						if (divisor & (divisor - 1)) {
-							magicu_info mi = compute_unsigned_magic_info(divisor, sizeof(uint64_t) * 8);
-							ibc.signedMultiplier = mi.multiplier;
-							ibc.preShift = mi.pre_shift;
-							ibc.postShift = mi.post_shift;
-							ibc.increment = mi.increment;
-						}
-						else {
-							ibc.signedMultiplier = 0;
-							int shift = 0;
-							while (divisor >>= 1)
-								++shift;
-							ibc.shift = shift;
-						}
+						ibc.imm = divisor;
 					}
 					else {
 						ibc.type = InstructionType::NOP;
@@ -537,7 +521,16 @@ namespace RandomX {
 				} break;
 
 				CASE_REP(ISDIV_C) {
-					ibc.type = InstructionType::NOP;
+					int32_t divisor = unsigned32ToSigned2sCompl(instr.imm32);
+					if (divisor != 0) {
+						auto dst = instr.dst % RegistersCount;
+						ibc.type = InstructionType::ISDIV_C;
+						ibc.idst = &r[dst];
+						ibc.simm = divisor;
+					}
+					else {
+						ibc.type = InstructionType::NOP;
+					}
 				} break;
 
 				CASE_REP(INEG_R) {

+ 5 - 10
src/InterpretedVirtualMachine.hpp

@@ -38,23 +38,18 @@ namespace RandomX {
 
 	typedef void(InterpretedVirtualMachine::*InstructionHandler)(Instruction&);
 
-	struct alignas(16) InstructionByteCode {
+	struct alignas(8) InstructionByteCode {
 		int_reg_t* idst;
 		int_reg_t* isrc;
-		int_reg_t imm;
+		union {
+			uint64_t imm;
+			int64_t simm;
+		};
 		__m128d* fdst;
 		__m128d* fsrc;
 		uint32_t condition;
 		uint32_t memMask;
 		uint32_t type;
-		union {
-			uint64_t unsignedMultiplier;
-			int64_t signedMultiplier;
-		};
-		unsigned shift;
-		unsigned preShift;
-		unsigned postShift;
-		bool increment;
 	};
 
 	constexpr int asedwfagdewsa = sizeof(InstructionByteCode);

+ 2 - 2
src/JitCompilerX86.cpp

@@ -666,8 +666,8 @@ namespace RandomX {
 		emit(AND_OR_MOV_LDMXCSR);
 	}
 
-	static inline uint8_t condition(Instruction& instr, bool invert = false) {
-		switch ((instr.mod & 7) ^ invert)
+	static inline uint8_t condition(Instruction& instr) {
+		switch ((instr.mod >> 2) & 7)
 		{
 			case 0:
 				return 0x96; //setbe

+ 1 - 1
src/main.cpp

@@ -102,7 +102,7 @@ public:
 		os << std::endl;
 	}
 private:
-	void print(std::atomic<uint64_t>& hash, std::ostream& os) {
+	static void print(std::atomic<uint64_t>& hash, std::ostream& os) {
 		auto h = hash.load();
 		outputHex(std::cout, (char*)&h, sizeof(h));
 	}