Sfoglia il codice sorgente

Fixed an infinite loop bug

tevador 7 anni fa
parent
commit
428b845a3d

+ 2 - 2
src/AssemblyGeneratorX86.cpp

@@ -475,7 +475,7 @@ namespace RandomX {
 	//4 uOPs
 	void AssemblyGeneratorX86::h_COND_R(Instruction& instr, int i) {
 		handleCondition(instr, i);
-		asmCode << "\txor ecx, ecx" << std::endl;
+		asmCode << "\txor rcx, rcx" << std::endl;
 		asmCode << "\tcmp " << regR32[instr.src] << ", " << (int32_t)instr.getImm32() << std::endl;
 		asmCode << "\tset" << condition(instr) << " cl" << std::endl;
 		asmCode << "\tadd " << regR[instr.dst] << ", rcx" << std::endl;
@@ -485,7 +485,7 @@ namespace RandomX {
 	//6 uOPs
 	void AssemblyGeneratorX86::h_COND_M(Instruction& instr, int i) {
 		handleCondition(instr, i);
-		asmCode << "\txor ecx, ecx" << std::endl;
+		asmCode << "\txor rcx, rcx" << std::endl;
 		genAddressReg(instr);
 		asmCode << "\tcmp dword ptr [rsi+rax], " << (int32_t)instr.getImm32() << std::endl;
 		asmCode << "\tset" << condition(instr) << " cl" << std::endl;

+ 23 - 7
src/LightProgramGenerator.cpp

@@ -111,10 +111,10 @@ namespace RandomX {
 
 	class Blake2Generator {
 	public:
-		Blake2Generator(const void* seed) : dataIndex(sizeof(data)) {
+		Blake2Generator(const void* seed, int nonce) : dataIndex(sizeof(data)) {
 			memset(data, 0, sizeof(data));
 			memcpy(data, seed, SeedSize);
-			data[60] = 39;
+			store32(&data[60], nonce);
 		}
 
 		uint8_t getByte() {
@@ -434,7 +434,7 @@ namespace RandomX {
 	const LightInstructionInfo* slot_3L[] = { &LightInstructionInfo::IADD_R, &LightInstructionInfo::ISUB_R, &LightInstructionInfo::IXOR_R, &LightInstructionInfo::IMULH_R, &LightInstructionInfo::ISMULH_R, &LightInstructionInfo::IXOR_R, &LightInstructionInfo::IMULH_R, &LightInstructionInfo::ISMULH_R };
 	const LightInstructionInfo* slot_3F[] = { &LightInstructionInfo::IADD_R, &LightInstructionInfo::ISUB_R, &LightInstructionInfo::IXOR_R, &LightInstructionInfo::IROR_R };
 	const LightInstructionInfo* slot_4[]  = { &LightInstructionInfo::IMUL_R, &LightInstructionInfo::IROR_C };
-	const LightInstructionInfo* slot_7[]  = { &LightInstructionInfo::IADD_C, &LightInstructionInfo::IMUL_C, &LightInstructionInfo::IXOR_C, &LightInstructionInfo::IXOR_C };
+	const LightInstructionInfo* slot_7[]  = { &LightInstructionInfo::IADD_C, &LightInstructionInfo::IMUL_C, &LightInstructionInfo::IXOR_C, &LightInstructionInfo::IMUL_C };
 	const LightInstructionInfo* slot_7L   = &LightInstructionInfo::COND_R;
 	const LightInstructionInfo* slot_8[]  = { &LightInstructionInfo::IADD_RC, &LightInstructionInfo::IMUL_9C };
 	const LightInstructionInfo* slot_10   = &LightInstructionInfo::IMUL_RCP;
@@ -771,12 +771,12 @@ namespace RandomX {
 		}
 	}
 
-	void generateLightProg2(LightProgram& prog, const void* seed, int indexRegister) {
+	void generateLightProg2(LightProgram& prog, const void* seed, int indexRegister, int nonce) {
 
 		ExecutionPort::type portBusy[RANDOMX_LPROG_LATENCY + 1][3];
 		memset(portBusy, 0, sizeof(portBusy));
 		RegisterInfo registers[8];
-		Blake2Generator gen(seed);
+		Blake2Generator gen(seed, nonce);
 		std::vector<LightInstruction> instructions;
 
 		DecoderBuffer& fetchLine = DecoderBuffer::Default;
@@ -790,6 +790,8 @@ namespace RandomX {
 		int mopIndex = 0;
 		bool portsSaturated = false;
 		int outIndex = 0;
+		int attempts = 0;
+		constexpr int MAX_ATTEMPTS = 4;
 
 		while(!portsSaturated) {
 			fetchLine = fetchLine.fetchNext(currentInstruction.getType(), gen);
@@ -798,6 +800,7 @@ namespace RandomX {
 			mopIndex = 0;
 			
 			while (!portsSaturated && mopIndex < fetchLine.getSize()) {
+				int topCycle = cycle;
 				if (instrIndex >= currentInstruction.getInfo().getSize()) {
 					if (currentInstruction.getType() >= 0) {
 						currentInstruction.toInstr(prog(outIndex++));
@@ -818,19 +821,31 @@ namespace RandomX {
 				mop.setCycle(scheduleCycle);
 
 				if (instrIndex == currentInstruction.getInfo().getSrcOp()) {
-					while (!currentInstruction.selectSource(scheduleCycle, registers, gen)) {
+					for (attempts = 0; attempts < MAX_ATTEMPTS && !currentInstruction.selectSource(scheduleCycle, registers, gen); ++attempts) {
 						std::cout << "; src STALL at cycle " << cycle << std::endl;
 						++scheduleCycle;
 						++cycle;
 					}
+					if (attempts == MAX_ATTEMPTS) { //throw instruction away
+						cycle = topCycle;
+						instrIndex = currentInstruction.getInfo().getSize();
+						std::cout << "; THROW away " << currentInstruction.getInfo().getName() << std::endl;
+						continue;
+					}
 					std::cout << "; src = r" << currentInstruction.getSource() << std::endl;
 				}
 				if (instrIndex == currentInstruction.getInfo().getDstOp()) {
-					while (!currentInstruction.selectDestination(scheduleCycle, registers, gen)) {
+					for (attempts = 0; attempts < MAX_ATTEMPTS && !currentInstruction.selectDestination(scheduleCycle, registers, gen); ++attempts) {
 						std::cout << "; dst STALL at cycle " << cycle << std::endl;
 						++scheduleCycle;
 						++cycle;
 					}
+					if (attempts == MAX_ATTEMPTS) { //throw instruction away
+						cycle = topCycle;
+						instrIndex = currentInstruction.getInfo().getSize();
+						std::cout << "; THROW away " << currentInstruction.getInfo().getName() << std::endl;
+						continue;
+					}
 					std::cout << "; dst = r" << currentInstruction.getDestination() << std::endl;
 				}
 				depCycle = scheduleCycle + mop.getLatency();
@@ -850,6 +865,7 @@ namespace RandomX {
 				if (scheduleCycle >= RANDOMX_LPROG_LATENCY) {
 					portsSaturated = true;
 				}
+				cycle = topCycle;
 			}
 			++cycle;
 		}

+ 1 - 1
src/LightProgramGenerator.hpp

@@ -21,5 +21,5 @@ along with RandomX.  If not, see<http://www.gnu.org/licenses/>.
 
 namespace RandomX {
 	void generateLightProgram(LightProgram& prog, const void* seed, int indexRegister);
-	void generateLightProg2(LightProgram& prog, const void* seed, int indexRegister);
+	void generateLightProg2(LightProgram& prog, const void* seed, int indexRegister, int nonce);
 }

+ 1 - 1
src/main.cpp

@@ -223,7 +223,7 @@ int main(int argc, char** argv) {
 
 	if (genLight) {
 		RandomX::LightProgram p;
-		RandomX::generateLightProg2(p, seed, 0);
+		RandomX::generateLightProg2(p, seed, 0, programCount);
 		RandomX::AssemblyGeneratorX86 asmX86;
 		asmX86.generateProgram(p);
 		std::cout << "-------------------------------------------------------" << std::endl;