From 428b845a3d62bd722e3ec18622c28f6f876c78ac Mon Sep 17 00:00:00 2001 From: tevador Date: Mon, 1 Apr 2019 19:04:08 +0200 Subject: [PATCH] Fixed an infinite loop bug --- src/AssemblyGeneratorX86.cpp | 4 ++-- src/LightProgramGenerator.cpp | 30 +++++++++++++++++++++++------- src/LightProgramGenerator.hpp | 2 +- src/main.cpp | 2 +- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/AssemblyGeneratorX86.cpp b/src/AssemblyGeneratorX86.cpp index 8a4012a..8b5dbcf 100644 --- a/src/AssemblyGeneratorX86.cpp +++ b/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; diff --git a/src/LightProgramGenerator.cpp b/src/LightProgramGenerator.cpp index d4aa79d..96207c0 100644 --- a/src/LightProgramGenerator.cpp +++ b/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 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; } diff --git a/src/LightProgramGenerator.hpp b/src/LightProgramGenerator.hpp index a7762b1..34688db 100644 --- a/src/LightProgramGenerator.hpp +++ b/src/LightProgramGenerator.hpp @@ -21,5 +21,5 @@ along with RandomX. If not, see. 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); } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index fdc198c..e4f9407 100644 --- a/src/main.cpp +++ b/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;