diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index bae695cf1..c4be5ad92 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -726,7 +726,16 @@ void JitCompilerA64::h_ISUB_R(Instruction& instr, uint32_t& codePos) } else { - emitAddImmediate(dst, dst, -instr.getImm32(), code, k); + const uint32_t imm = instr.getImm32(); + + if (imm == 0x80000000ul) { + constexpr uint32_t tmp_reg = 20; + emit32(ARMV8A::MOVZ | tmp_reg | (1u << 21) | (0x8000u << 5), code, k); + emit32(ARMV8A::ADD | dst | (dst << 5) | (tmp_reg << 16), code, k); + } + else { + emitAddImmediate(dst, dst, -instr.getImm32(), code, k); + } } reg_changed_offset[instr.dst] = k; diff --git a/src/crypto/randomx/jit_compiler_rv64.cpp b/src/crypto/randomx/jit_compiler_rv64.cpp index 230b22d1b..596deda7b 100644 --- a/src/crypto/randomx/jit_compiler_rv64.cpp +++ b/src/crypto/randomx/jit_compiler_rv64.cpp @@ -814,9 +814,16 @@ namespace randomx { state.emit(rvi(rv64::SUB, regR(isn.dst), regR(isn.dst), regR(isn.src))); } else { - int32_t imm = unsigned32ToSigned2sCompl(-isn.getImm32()); //convert to add - //x{dst} = x{dst} + {-imm} - emitImm32(state, imm, regR(isn.dst), regR(isn.dst), Tmp1Reg); + const uint32_t uimm = isn.getImm32(); + if (uimm == 0x80000000ul) { + state.emit(rv64::LUI | (0x80000 << 12) | rvrd(Tmp1Reg)); + state.emit(rvi(rv64::SUB, regR(isn.dst), regR(isn.dst), Tmp1Reg)); + } + else { + int32_t imm = unsigned32ToSigned2sCompl(-uimm); //convert to add + //x{dst} = x{dst} + {-imm} + emitImm32(state, imm, regR(isn.dst), regR(isn.dst), Tmp1Reg); + } } } diff --git a/src/crypto/randomx/jit_compiler_rv64_vector.cpp b/src/crypto/randomx/jit_compiler_rv64_vector.cpp index e177a0f2d..bc9f68f19 100644 --- a/src/crypto/randomx/jit_compiler_rv64_vector.cpp +++ b/src/crypto/randomx/jit_compiler_rv64_vector.cpp @@ -444,6 +444,12 @@ void* generateProgramVectorRV64(uint8_t* buf, Program& prog, ProgramConfiguratio // sub x20 + dst, x20 + dst, x20 + src emit32(0x414A0A33 + (dst << 7) + (dst << 15) + (src << 20)); } + else if (imm == 0x80000000U) { + // lui x5, 0x80000000U + emit32(0x800002B7); + // sub x20 + dst, x20 + dst, x5 + emit32(0x405A0A33 + (dst << 7) + (dst << 15)); + } else { imm_to_x5(-imm, p); // c.add x20 + dst, x5 diff --git a/src/crypto/randomx/randomx.h b/src/crypto/randomx/randomx.h index 51998e298..4b23b37d2 100644 --- a/src/crypto/randomx/randomx.h +++ b/src/crypto/randomx/randomx.h @@ -163,7 +163,7 @@ extern RandomX_ConfigurationGraft RandomX_GraftConfig; extern RandomX_ConfigurationSafex RandomX_SafexConfig; extern RandomX_ConfigurationYada RandomX_YadaConfig; -extern RandomX_ConfigurationBase RandomX_CurrentConfig; +alignas(64) extern RandomX_ConfigurationBase RandomX_CurrentConfig; template void randomx_apply_config(const T& config)