Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/jit_compiler_a64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,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;
Expand Down
13 changes: 10 additions & 3 deletions src/jit_compiler_rv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -789,9 +789,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);
}
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/jit_compiler_rv64_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,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
Expand Down
18 changes: 17 additions & 1 deletion src/tests/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void runTest(const char* name, bool condition, FUNC f) {
std::cout << "[";
std::cout.width(2);
std::cout << std::right << ++testNo << "] ";
std::cout.width(40);
std::cout.width(44);
std::cout << std::left << name << " ... ";
std::cout.flush();
if (condition) {
Expand Down Expand Up @@ -1002,11 +1002,26 @@ int main() {
assert(equalsHex(hash, (vm->getFlags() & RANDOMX_FLAG_V2) ? "c8e92c5f7c1946fecf06bc382b92e3111da38ee3e6a5ad90704e1a9d8aaf6e76" : "c56414121acda1713c2f2a819d8ae38aed7c80c35c2a769298d34f03833cd5f1"));
};

auto test_f = [&] {
uint8_t key_u[RANDOMX_HASH_SIZE] = {
0x77, 0x97, 0x37, 0x3e, 0xa4, 0x63, 0x31, 0x94, 0x64, 0x0b, 0xf8, 0xd8, 0xc3, 0xb6, 0x67, 0x24, 0xd6, 0xaa, 0x7b, 0xd2, 0xdc, 0x20, 0xe0, 0x09, 0xdf, 0x2f, 0x8f, 0x17, 0x10, 0xab, 0xe8, 0x24
};
char key[RANDOMX_HASH_SIZE];

// workaround for picky compilers
memcpy(key, key_u, sizeof(key_u));

char hash[RANDOMX_HASH_SIZE];
calcHexHash(key, "1010e1eaf8cf067b37b5f0ee031ab23ed1755e090a3af4415830145853e2be3e1f6821fed84dae58d00e00da5214d6c1f2d0622e0abd51f9373d04e0b0f8e6d6514d90689721c4aac5a9bb0d", &hash);
assert(equalsHex(hash, "78af2a1864c42abce36d2e8983e13df99b2af0ce1362999af09fab004d4435a8"));
};

runTest("Hash test 1a (interpreter)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_a);
runTest("Hash test 1b (interpreter)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_b);
runTest("Hash test 1c (interpreter)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_c);
runTest("Hash test 1d (interpreter)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_d);
runTest("Hash test 1e (interpreter)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_e);
runTest("Hash test 1f (ISUB_R edge case, interpreter)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_f);

randomx_destroy_vm(vm);

Expand Down Expand Up @@ -1040,6 +1055,7 @@ int main() {
runTest("Hash test 2c (compiler)", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_c);
runTest("Hash test 2d (compiler)", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_d);
runTest("Hash test 2e (compiler)", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_e);
runTest("Hash test 2f (ISUB_R edge case, compiler)", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_f);

if (RANDOMX_HAVE_COMPILER) {
randomx_destroy_vm(vm);
Expand Down
Loading