Fixed mining and verification mode not giving the same results

Trace support in Assembly generator
This commit is contained in:
tevador 2019-02-16 23:18:45 +01:00
parent a145caa185
commit 923420f0a3
5 changed files with 170 additions and 14 deletions

View File

@ -58,6 +58,24 @@ namespace RandomX {
} }
} }
void AssemblyGeneratorX86::traceint(Instruction& instr) {
if (trace) {
asmCode << "\tpush " << regR[instr.dst] << std::endl;
}
}
void AssemblyGeneratorX86::traceflt(Instruction& instr) {
if (trace) {
asmCode << "\tpush 0" << std::endl;
}
}
void AssemblyGeneratorX86::tracenop(Instruction& instr) {
if (trace) {
asmCode << "\tpush 0" << std::endl;
}
}
void AssemblyGeneratorX86::generateCode(Instruction& instr, int i) { void AssemblyGeneratorX86::generateCode(Instruction& instr, int i) {
asmCode << "\t; " << instr; asmCode << "\t; " << instr;
auto generator = engine[instr.opcode]; auto generator = engine[instr.opcode];
@ -86,6 +104,7 @@ namespace RandomX {
else { else {
asmCode << "\tadd " << regR[instr.dst] << ", " << (int32_t)instr.imm32 << std::endl; asmCode << "\tadd " << regR[instr.dst] << ", " << (int32_t)instr.imm32 << std::endl;
} }
traceint(instr);
} }
//2.75 uOP //2.75 uOP
@ -97,11 +116,13 @@ namespace RandomX {
else { else {
asmCode << "\tadd " << regR[instr.dst] << ", qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl; asmCode << "\tadd " << regR[instr.dst] << ", qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl;
} }
traceint(instr);
} }
//1 uOP //1 uOP
void AssemblyGeneratorX86::h_IADD_RC(Instruction& instr, int i) { void AssemblyGeneratorX86::h_IADD_RC(Instruction& instr, int i) {
asmCode << "\tlea " << regR[instr.dst] << ", [" << regR[instr.dst] << "+" << regR[instr.src] << std::showpos << (int32_t)instr.imm32 << std::noshowpos << "]" << std::endl; asmCode << "\tlea " << regR[instr.dst] << ", [" << regR[instr.dst] << "+" << regR[instr.src] << std::showpos << (int32_t)instr.imm32 << std::noshowpos << "]" << std::endl;
traceint(instr);
} }
//1 uOP //1 uOP
@ -112,6 +133,7 @@ namespace RandomX {
else { else {
asmCode << "\tsub " << regR[instr.dst] << ", " << (int32_t)instr.imm32 << std::endl; asmCode << "\tsub " << regR[instr.dst] << ", " << (int32_t)instr.imm32 << std::endl;
} }
traceint(instr);
} }
//2.75 uOP //2.75 uOP
@ -123,11 +145,13 @@ namespace RandomX {
else { else {
asmCode << "\tsub " << regR[instr.dst] << ", qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl; asmCode << "\tsub " << regR[instr.dst] << ", qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl;
} }
traceint(instr);
} }
//1 uOP //1 uOP
void AssemblyGeneratorX86::h_IMUL_9C(Instruction& instr, int i) { void AssemblyGeneratorX86::h_IMUL_9C(Instruction& instr, int i) {
asmCode << "\tlea " << regR[instr.dst] << ", [" << regR[instr.dst] << "+" << regR[instr.dst] << "*8" << std::showpos << (int32_t)instr.imm32 << std::noshowpos << "]" << std::endl; asmCode << "\tlea " << regR[instr.dst] << ", [" << regR[instr.dst] << "+" << regR[instr.dst] << "*8" << std::showpos << (int32_t)instr.imm32 << std::noshowpos << "]" << std::endl;
traceint(instr);
} }
//1 uOP //1 uOP
@ -138,6 +162,7 @@ namespace RandomX {
else { else {
asmCode << "\timul " << regR[instr.dst] << ", " << (int32_t)instr.imm32 << std::endl; asmCode << "\timul " << regR[instr.dst] << ", " << (int32_t)instr.imm32 << std::endl;
} }
traceint(instr);
} }
//2.75 uOP //2.75 uOP
@ -149,6 +174,7 @@ namespace RandomX {
else { else {
asmCode << "\timul " << regR[instr.dst] << ", qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl; asmCode << "\timul " << regR[instr.dst] << ", qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl;
} }
traceint(instr);
} }
//4 uOPs //4 uOPs
@ -156,6 +182,7 @@ namespace RandomX {
asmCode << "\tmov rax, " << regR[instr.dst] << std::endl; asmCode << "\tmov rax, " << regR[instr.dst] << std::endl;
asmCode << "\tmul " << regR[instr.src] << std::endl; asmCode << "\tmul " << regR[instr.src] << std::endl;
asmCode << "\tmov " << regR[instr.dst] << ", rdx" << std::endl; asmCode << "\tmov " << regR[instr.dst] << ", rdx" << std::endl;
traceint(instr);
} }
//5.75 uOPs //5.75 uOPs
@ -170,6 +197,7 @@ namespace RandomX {
asmCode << "\tmul qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl; asmCode << "\tmul qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl;
} }
asmCode << "\tmov " << regR[instr.dst] << ", rdx" << std::endl; asmCode << "\tmov " << regR[instr.dst] << ", rdx" << std::endl;
traceint(instr);
} }
//4 uOPs //4 uOPs
@ -177,6 +205,7 @@ namespace RandomX {
asmCode << "\tmov rax, " << regR[instr.dst] << std::endl; asmCode << "\tmov rax, " << regR[instr.dst] << std::endl;
asmCode << "\timul " << regR[instr.src] << std::endl; asmCode << "\timul " << regR[instr.src] << std::endl;
asmCode << "\tmov " << regR[instr.dst] << ", rdx" << std::endl; asmCode << "\tmov " << regR[instr.dst] << ", rdx" << std::endl;
traceint(instr);
} }
//5.75 uOPs //5.75 uOPs
@ -191,11 +220,13 @@ namespace RandomX {
asmCode << "\timul qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl; asmCode << "\timul qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl;
} }
asmCode << "\tmov " << regR[instr.dst] << ", rdx" << std::endl; asmCode << "\tmov " << regR[instr.dst] << ", rdx" << std::endl;
traceint(instr);
} }
//1 uOP //1 uOP
void AssemblyGeneratorX86::h_INEG_R(Instruction& instr, int i) { void AssemblyGeneratorX86::h_INEG_R(Instruction& instr, int i) {
asmCode << "\tneg " << regR[instr.dst] << std::endl; asmCode << "\tneg " << regR[instr.dst] << std::endl;
traceint(instr);
} }
//1 uOP //1 uOP
@ -206,6 +237,7 @@ namespace RandomX {
else { else {
asmCode << "\txor " << regR[instr.dst] << ", " << (int32_t)instr.imm32 << std::endl; asmCode << "\txor " << regR[instr.dst] << ", " << (int32_t)instr.imm32 << std::endl;
} }
traceint(instr);
} }
//2.75 uOP //2.75 uOP
@ -217,6 +249,7 @@ namespace RandomX {
else { else {
asmCode << "\txor " << regR[instr.dst] << ", qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl; asmCode << "\txor " << regR[instr.dst] << ", qword ptr [rsi+" << genAddressImm(instr) << "]" << std::endl;
} }
traceint(instr);
} }
//1.75 uOPs //1.75 uOPs
@ -228,6 +261,7 @@ namespace RandomX {
else { else {
asmCode << "\tror " << regR[instr.dst] << ", " << (instr.imm32 & 63) << std::endl; asmCode << "\tror " << regR[instr.dst] << ", " << (instr.imm32 & 63) << std::endl;
} }
traceint(instr);
} }
//1.75 uOPs //1.75 uOPs
@ -239,6 +273,7 @@ namespace RandomX {
else { else {
asmCode << "\trol " << regR[instr.dst] << ", " << (instr.imm32 & 63) << std::endl; asmCode << "\trol " << regR[instr.dst] << ", " << (instr.imm32 & 63) << std::endl;
} }
traceint(instr);
} }
//~6 uOPs //~6 uOPs
@ -273,7 +308,11 @@ namespace RandomX {
if(shift > 0) if(shift > 0)
asmCode << "\tshr " << regR[instr.dst] << ", " << shift << std::endl; asmCode << "\tshr " << regR[instr.dst] << ", " << shift << std::endl;
} }
} traceint(instr);
}
else {
tracenop(instr);
}
} }
//~8.5 uOPs //~8.5 uOPs
@ -300,6 +339,7 @@ namespace RandomX {
if (negative) if (negative)
asmCode << "\tneg rax" << std::endl; asmCode << "\tneg rax" << std::endl;
asmCode << "\tadd " << regR[instr.dst] << ", rax" << std::endl; asmCode << "\tadd " << regR[instr.dst] << ", rax" << std::endl;
traceint(instr);
} }
else if (divisor != 0) { else if (divisor != 0) {
magics_info mi = compute_signed_magic_info(divisor); magics_info mi = compute_signed_magic_info(divisor);
@ -325,6 +365,10 @@ namespace RandomX {
asmCode << "\tsets al" << std::endl; asmCode << "\tsets al" << std::endl;
asmCode << "\tadd rdx, rax" << std::endl; asmCode << "\tadd rdx, rax" << std::endl;
asmCode << "\tadd " << regR[instr.dst] << ", rdx" << std::endl; asmCode << "\tadd " << regR[instr.dst] << ", rdx" << std::endl;
traceint(instr);
}
else {
tracenop(instr);
} }
} }
@ -332,12 +376,17 @@ namespace RandomX {
void AssemblyGeneratorX86::h_ISWAP_R(Instruction& instr, int i) { void AssemblyGeneratorX86::h_ISWAP_R(Instruction& instr, int i) {
if (instr.src != instr.dst) { if (instr.src != instr.dst) {
asmCode << "\txchg " << regR[instr.dst] << ", " << regR[instr.src] << std::endl; asmCode << "\txchg " << regR[instr.dst] << ", " << regR[instr.src] << std::endl;
traceint(instr);
}
else {
tracenop(instr);
} }
} }
//1 uOPs //1 uOPs
void AssemblyGeneratorX86::h_FSWAP_R(Instruction& instr, int i) { void AssemblyGeneratorX86::h_FSWAP_R(Instruction& instr, int i) {
asmCode << "\tshufpd " << regFE[instr.dst] << ", " << regFE[instr.dst] << ", 1" << std::endl; asmCode << "\tshufpd " << regFE[instr.dst] << ", " << regFE[instr.dst] << ", 1" << std::endl;
traceflt(instr);
} }
//1 uOP //1 uOP
@ -346,6 +395,7 @@ namespace RandomX {
instr.src %= 4; instr.src %= 4;
asmCode << "\taddpd " << regF[instr.dst] << ", " << regA[instr.src] << std::endl; asmCode << "\taddpd " << regF[instr.dst] << ", " << regA[instr.src] << std::endl;
//asmCode << "\t" << fsumInstr[instr.mod % 4] << " " << signMask << ", " << regF[instr.dst] << std::endl; //asmCode << "\t" << fsumInstr[instr.mod % 4] << " " << signMask << ", " << regF[instr.dst] << std::endl;
traceflt(instr);
} }
//5 uOPs //5 uOPs
@ -354,6 +404,7 @@ namespace RandomX {
genAddressReg(instr); genAddressReg(instr);
asmCode << "\tcvtdq2pd xmm12, qword ptr [rsi+rax]" << std::endl; asmCode << "\tcvtdq2pd xmm12, qword ptr [rsi+rax]" << std::endl;
asmCode << "\taddpd " << regF[instr.dst] << ", xmm12" << std::endl; asmCode << "\taddpd " << regF[instr.dst] << ", xmm12" << std::endl;
traceflt(instr);
} }
//1 uOP //1 uOP
@ -362,6 +413,7 @@ namespace RandomX {
instr.src %= 4; instr.src %= 4;
asmCode << "\tsubpd " << regF[instr.dst] << ", " << regA[instr.src] << std::endl; asmCode << "\tsubpd " << regF[instr.dst] << ", " << regA[instr.src] << std::endl;
//asmCode << "\t" << fsumInstr[instr.mod % 4] << " " << signMask << ", " << regF[instr.dst] << std::endl; //asmCode << "\t" << fsumInstr[instr.mod % 4] << " " << signMask << ", " << regF[instr.dst] << std::endl;
traceflt(instr);
} }
//5 uOPs //5 uOPs
@ -370,12 +422,14 @@ namespace RandomX {
genAddressReg(instr); genAddressReg(instr);
asmCode << "\tcvtdq2pd xmm12, qword ptr [rsi+rax]" << std::endl; asmCode << "\tcvtdq2pd xmm12, qword ptr [rsi+rax]" << std::endl;
asmCode << "\tsubpd " << regF[instr.dst] << ", xmm12" << std::endl; asmCode << "\tsubpd " << regF[instr.dst] << ", xmm12" << std::endl;
traceflt(instr);
} }
//1 uOP //1 uOP
void AssemblyGeneratorX86::h_FSCAL_R(Instruction& instr, int i) { void AssemblyGeneratorX86::h_FSCAL_R(Instruction& instr, int i) {
instr.dst %= 4; instr.dst %= 4;
asmCode << "\txorps " << regF[instr.dst] << ", " << signMask << std::endl; asmCode << "\txorps " << regF[instr.dst] << ", " << signMask << std::endl;
traceflt(instr);
} }
//1 uOPs //1 uOPs
@ -383,6 +437,7 @@ namespace RandomX {
instr.dst %= 4; instr.dst %= 4;
instr.src %= 4; instr.src %= 4;
asmCode << "\tmulpd " << regE[instr.dst] << ", " << regA[instr.src] << std::endl; asmCode << "\tmulpd " << regE[instr.dst] << ", " << regA[instr.src] << std::endl;
traceflt(instr);
} }
//7 uOPs //7 uOPs
@ -393,6 +448,7 @@ namespace RandomX {
asmCode << "\tandps xmm12, xmm14" << std::endl; asmCode << "\tandps xmm12, xmm14" << std::endl;
asmCode << "\tmulpd " << regE[instr.dst] << ", xmm12" << std::endl; asmCode << "\tmulpd " << regE[instr.dst] << ", xmm12" << std::endl;
asmCode << "\tmaxpd " << regE[instr.dst] << ", " << dblMin << std::endl; asmCode << "\tmaxpd " << regE[instr.dst] << ", " << dblMin << std::endl;
traceflt(instr);
} }
//2 uOPs //2 uOPs
@ -401,6 +457,7 @@ namespace RandomX {
instr.src %= 4; instr.src %= 4;
asmCode << "\tdivpd " << regE[instr.dst] << ", " << regA[instr.src] << std::endl; asmCode << "\tdivpd " << regE[instr.dst] << ", " << regA[instr.src] << std::endl;
asmCode << "\tmaxpd " << regE[instr.dst] << ", " << dblMin << std::endl; asmCode << "\tmaxpd " << regE[instr.dst] << ", " << dblMin << std::endl;
traceflt(instr);
} }
//7 uOPs //7 uOPs
@ -411,12 +468,14 @@ namespace RandomX {
asmCode << "\tandps xmm12, xmm14" << std::endl; asmCode << "\tandps xmm12, xmm14" << std::endl;
asmCode << "\tdivpd " << regE[instr.dst] << ", xmm12" << std::endl; asmCode << "\tdivpd " << regE[instr.dst] << ", xmm12" << std::endl;
asmCode << "\tmaxpd " << regE[instr.dst] << ", " << dblMin << std::endl; asmCode << "\tmaxpd " << regE[instr.dst] << ", " << dblMin << std::endl;
traceflt(instr);
} }
//1 uOP //1 uOP
void AssemblyGeneratorX86::h_FSQRT_R(Instruction& instr, int i) { void AssemblyGeneratorX86::h_FSQRT_R(Instruction& instr, int i) {
instr.dst %= 4; instr.dst %= 4;
asmCode << "\tsqrtpd " << regE[instr.dst] << ", " << regE[instr.dst] << std::endl; asmCode << "\tsqrtpd " << regE[instr.dst] << ", " << regE[instr.dst] << std::endl;
traceflt(instr);
} }
//6 uOPs //6 uOPs
@ -429,6 +488,7 @@ namespace RandomX {
asmCode << "\tor eax, 40896" << std::endl; asmCode << "\tor eax, 40896" << std::endl;
asmCode << "\tmov dword ptr [rsp-8], eax" << std::endl; asmCode << "\tmov dword ptr [rsp-8], eax" << std::endl;
asmCode << "\tldmxcsr dword ptr [rsp-8]" << std::endl; asmCode << "\tldmxcsr dword ptr [rsp-8]" << std::endl;
tracenop(instr);
} }
static inline const char* condition(Instruction& instr) { static inline const char* condition(Instruction& instr) {
@ -461,6 +521,7 @@ namespace RandomX {
asmCode << "\tcmp " << regR32[instr.src] << ", " << (int32_t)instr.imm32 << std::endl; asmCode << "\tcmp " << regR32[instr.src] << ", " << (int32_t)instr.imm32 << std::endl;
asmCode << "\tset" << condition(instr) << " cl" << std::endl; asmCode << "\tset" << condition(instr) << " cl" << std::endl;
asmCode << "\tadd " << regR[instr.dst] << ", rcx" << std::endl; asmCode << "\tadd " << regR[instr.dst] << ", rcx" << std::endl;
traceint(instr);
} }
//6 uOPs //6 uOPs
@ -470,22 +531,26 @@ namespace RandomX {
asmCode << "\tcmp dword ptr [rsi+rax], " << (int32_t)instr.imm32 << std::endl; asmCode << "\tcmp dword ptr [rsi+rax], " << (int32_t)instr.imm32 << std::endl;
asmCode << "\tset" << condition(instr) << " cl" << std::endl; asmCode << "\tset" << condition(instr) << " cl" << std::endl;
asmCode << "\tadd " << regR[instr.dst] << ", rcx" << std::endl; asmCode << "\tadd " << regR[instr.dst] << ", rcx" << std::endl;
traceint(instr);
} }
//3 uOPs //3 uOPs
void AssemblyGeneratorX86::h_ISTORE(Instruction& instr, int i) { void AssemblyGeneratorX86::h_ISTORE(Instruction& instr, int i) {
genAddressRegDst(instr); genAddressRegDst(instr);
asmCode << "\tmov qword ptr [rsi+rax], " << regR[instr.src] << std::endl; asmCode << "\tmov qword ptr [rsi+rax], " << regR[instr.src] << std::endl;
tracenop(instr);
} }
//3 uOPs //3 uOPs
void AssemblyGeneratorX86::h_FSTORE(Instruction& instr, int i) { void AssemblyGeneratorX86::h_FSTORE(Instruction& instr, int i) {
genAddressRegDst(instr, 16); genAddressRegDst(instr, 16);
asmCode << "\tmovapd xmmword ptr [rsi+rax], " << regFE[instr.src] << std::endl; asmCode << "\tmovapd xmmword ptr [rsi+rax], " << regFE[instr.src] << std::endl;
tracenop(instr);
} }
void AssemblyGeneratorX86::h_NOP(Instruction& instr, int i) { void AssemblyGeneratorX86::h_NOP(Instruction& instr, int i) {
asmCode << "\tnop" << std::endl; asmCode << "\tnop" << std::endl;
tracenop(instr);
} }
#include "instructionWeights.hpp" #include "instructionWeights.hpp"

View File

@ -45,6 +45,10 @@ namespace RandomX {
void generateCode(Instruction&, int); void generateCode(Instruction&, int);
void traceint(Instruction&);
void traceflt(Instruction&);
void tracenop(Instruction&);
void h_IADD_R(Instruction&, int); void h_IADD_R(Instruction&, int);
void h_IADD_M(Instruction&, int); void h_IADD_M(Instruction&, int);
void h_IADD_RC(Instruction&, int); void h_IADD_RC(Instruction&, int);

View File

@ -82,6 +82,31 @@ namespace RandomX {
void InterpretedVirtualMachine::executeBytecode<ProgramLength>(int_reg_t(&r)[8], __m128d (&f)[4], __m128d (&e)[4], __m128d (&a)[4]) { void InterpretedVirtualMachine::executeBytecode<ProgramLength>(int_reg_t(&r)[8], __m128d (&f)[4], __m128d (&e)[4], __m128d (&a)[4]) {
} }
static void print(int_reg_t r) {
std::cout << std::hex << std::setw(16) << std::setfill('0') << r << std::endl;
}
static void print(__m128d f) {
uint64_t lo = *(((uint64_t*)&f) + 0);
uint64_t hi = *(((uint64_t*)&f) + 1);
std::cout << std::hex << std::setw(16) << std::setfill('0') << hi << '-' << std::hex << std::setw(16) << std::setfill('0') << lo << std::endl;
}
static void printState(int_reg_t(&r)[8], __m128d (&f)[4], __m128d (&e)[4], __m128d (&a)[4]) {
for (int i = 0; i < 8; ++i) {
std::cout << "r" << i << " = "; print(r[i]);
}
for (int i = 0; i < 4; ++i) {
std::cout << "f" << i << " = "; print(f[i]);
}
for (int i = 0; i < 4; ++i) {
std::cout << "e" << i << " = "; print(e[i]);
}
for (int i = 0; i < 4; ++i) {
std::cout << "a" << i << " = "; print(a[i]);
}
}
FORCE_INLINE void InterpretedVirtualMachine::executeBytecode(int i, int_reg_t(&r)[8], __m128d (&f)[4], __m128d (&e)[4], __m128d (&a)[4]) { FORCE_INLINE void InterpretedVirtualMachine::executeBytecode(int i, int_reg_t(&r)[8], __m128d (&f)[4], __m128d (&e)[4], __m128d (&a)[4]) {
auto& ibc = byteCode[i]; auto& ibc = byteCode[i];
switch (ibc.type) switch (ibc.type)
@ -107,7 +132,7 @@ namespace RandomX {
} break; } break;
case InstructionType::IMUL_9C: { case InstructionType::IMUL_9C: {
*ibc.idst += 9 * *ibc.idst + ibc.imm; *ibc.idst += 8 * *ibc.idst + ibc.imm;
} break; } break;
case InstructionType::IMUL_R: { case InstructionType::IMUL_R: {
@ -210,7 +235,7 @@ namespace RandomX {
} break; } break;
case InstructionType::FDIV_M: { case InstructionType::FDIV_M: {
__m128d fsrc = load_cvt_i32x2(scratchpad + (*ibc.isrc & ibc.memMask)); __m128d fsrc = _mm_abs(load_cvt_i32x2(scratchpad + (*ibc.isrc & ibc.memMask)));
__m128d fdst = _mm_div_pd(*ibc.fdst, fsrc); __m128d fdst = _mm_div_pd(*ibc.fdst, fsrc);
*ibc.fdst = _mm_max_pd(fdst, _mm_set_pd(DBL_MIN, DBL_MIN)); *ibc.fdst = _mm_max_pd(fdst, _mm_set_pd(DBL_MIN, DBL_MIN));
} break; } break;
@ -220,11 +245,11 @@ namespace RandomX {
} break; } break;
case InstructionType::COND_R: { case InstructionType::COND_R: {
*ibc.idst += condition(*ibc.isrc, ibc.imm, ibc.condition) ? 1 : 0; *ibc.idst += condition(ibc.condition, *ibc.isrc, ibc.imm) ? 1 : 0;
} break; } break;
case InstructionType::COND_M: { case InstructionType::COND_M: {
*ibc.idst += condition(load64(scratchpad + (*ibc.isrc & ibc.memMask)), ibc.imm, ibc.condition) ? 1 : 0; *ibc.idst += condition(ibc.condition, load64(scratchpad + (*ibc.isrc & ibc.memMask)), ibc.imm) ? 1 : 0;
} break; } break;
case InstructionType::CFROUND: { case InstructionType::CFROUND: {
@ -242,6 +267,13 @@ namespace RandomX {
default: default:
UNREACHABLE; UNREACHABLE;
} }
if (trace) {
//std::cout << program(i);
if(ibc.type < 20 || ibc.type == 31 || ibc.type == 32)
print(*ibc.idst);
else //if(ibc.type >= 20 && ibc.type <= 30)
print(0);
}
} }
void InterpretedVirtualMachine::execute() { void InterpretedVirtualMachine::execute() {
@ -260,10 +292,20 @@ namespace RandomX {
uint32_t spAddr0 = mem.mx; uint32_t spAddr0 = mem.mx;
uint32_t spAddr1 = mem.ma; uint32_t spAddr1 = mem.ma;
if (trace) {
std::cout << "execute (reg: r" << readReg0 << ", r" << readReg1 << ", r" << readReg2 << ", r" << readReg3 << ")" << std::endl;
std::cout << "spAddr " << std::hex << std::setw(8) << std::setfill('0') << spAddr1 << " / " << std::setw(8) << std::setfill('0') << spAddr0 << std::endl;
std::cout << "ma/mx " << std::hex << std::setw(8) << std::setfill('0') << mem.ma << std::setw(8) << std::setfill('0') << mem.mx << std::endl;
printState(r, f, e, a);
}
for(unsigned iter = 0; iter < InstructionCount; ++iter) { for(unsigned iter = 0; iter < InstructionCount; ++iter) {
//std::cout << "Iteration " << iter << std::endl; //std::cout << "Iteration " << iter << std::endl;
spAddr0 ^= r[readReg0]; uint64_t spMix = r[readReg0] ^ r[readReg1];
spAddr0 ^= spMix;
spAddr0 &= ScratchpadL3Mask64; spAddr0 &= ScratchpadL3Mask64;
spAddr1 ^= spMix >> 32;
spAddr1 &= ScratchpadL3Mask64;
r[0] ^= load64(scratchpad + spAddr0 + 0); r[0] ^= load64(scratchpad + spAddr0 + 0);
r[1] ^= load64(scratchpad + spAddr0 + 8); r[1] ^= load64(scratchpad + spAddr0 + 8);
@ -274,9 +316,6 @@ namespace RandomX {
r[6] ^= load64(scratchpad + spAddr0 + 48); r[6] ^= load64(scratchpad + spAddr0 + 48);
r[7] ^= load64(scratchpad + spAddr0 + 56); r[7] ^= load64(scratchpad + spAddr0 + 56);
spAddr1 ^= r[readReg1];
spAddr1 &= ScratchpadL3Mask64;
f[0] = load_cvt_i32x2(scratchpad + spAddr1 + 0); f[0] = load_cvt_i32x2(scratchpad + spAddr1 + 0);
f[1] = load_cvt_i32x2(scratchpad + spAddr1 + 8); f[1] = load_cvt_i32x2(scratchpad + spAddr1 + 8);
f[2] = load_cvt_i32x2(scratchpad + spAddr1 + 16); f[2] = load_cvt_i32x2(scratchpad + spAddr1 + 16);
@ -286,6 +325,14 @@ namespace RandomX {
e[2] = _mm_abs(load_cvt_i32x2(scratchpad + spAddr1 + 48)); e[2] = _mm_abs(load_cvt_i32x2(scratchpad + spAddr1 + 48));
e[3] = _mm_abs(load_cvt_i32x2(scratchpad + spAddr1 + 56)); e[3] = _mm_abs(load_cvt_i32x2(scratchpad + spAddr1 + 56));
if (trace) {
std::cout << "iteration " << std::dec << iter << std::endl;
std::cout << "spAddr " << std::hex << std::setw(8) << std::setfill('0') << spAddr1 << " / " << std::setw(8) << std::setfill('0') << spAddr0 << std::endl;
std::cout << "ma/mx " << std::hex << std::setw(8) << std::setfill('0') << mem.ma << std::setw(8) << std::setfill('0') << mem.mx << std::endl;
printState(r, f, e, a);
std::cout << "-----------------------------------" << std::endl;
}
executeBytecode<0>(r, f, e, a); executeBytecode<0>(r, f, e, a);
if (asyncWorker) { if (asyncWorker) {
@ -309,6 +356,14 @@ namespace RandomX {
std::swap(mem.mx, mem.ma); std::swap(mem.mx, mem.ma);
} }
if (trace) {
std::cout << "iteration " << std::dec << iter << std::endl;
std::cout << "spAddr " << std::hex << std::setw(8) << std::setfill('0') << spAddr1 << " / " << std::setw(8) << std::setfill('0') << spAddr0 << std::endl;
std::cout << "ma/mx " << std::hex << std::setw(8) << std::setfill('0') << mem.ma << std::setw(8) << std::setfill('0') << mem.mx << std::endl;
printState(r, f, e, a);
std::cout << "===================================" << std::endl;
}
store64(scratchpad + spAddr1 + 0, r[0]); store64(scratchpad + spAddr1 + 0, r[0]);
store64(scratchpad + spAddr1 + 8, r[1]); store64(scratchpad + spAddr1 + 8, r[1]);
store64(scratchpad + spAddr1 + 16, r[2]); store64(scratchpad + spAddr1 + 16, r[2]);
@ -318,10 +373,15 @@ namespace RandomX {
store64(scratchpad + spAddr1 + 48, r[6]); store64(scratchpad + spAddr1 + 48, r[6]);
store64(scratchpad + spAddr1 + 56, r[7]); store64(scratchpad + spAddr1 + 56, r[7]);
_mm_store_pd((double*)(scratchpad + spAddr0 + 0), _mm_mul_pd(f[0], e[0])); f[0] = _mm_mul_pd(f[0], e[0]);
_mm_store_pd((double*)(scratchpad + spAddr0 + 16), _mm_mul_pd(f[1], e[1])); f[1] = _mm_mul_pd(f[1], e[1]);
_mm_store_pd((double*)(scratchpad + spAddr0 + 32), _mm_mul_pd(f[2], e[2])); f[2] = _mm_mul_pd(f[2], e[2]);
_mm_store_pd((double*)(scratchpad + spAddr0 + 48), _mm_mul_pd(f[3], e[3])); f[3] = _mm_mul_pd(f[3], e[3]);
_mm_store_pd((double*)(scratchpad + spAddr0 + 0), f[0]);
_mm_store_pd((double*)(scratchpad + spAddr0 + 16), f[1]);
_mm_store_pd((double*)(scratchpad + spAddr0 + 32), f[2]);
_mm_store_pd((double*)(scratchpad + spAddr0 + 48), f[3]);
spAddr0 = 0; spAddr0 = 0;
spAddr1 = 0; spAddr1 = 0;
@ -719,6 +779,7 @@ namespace RandomX {
ibc.type = InstructionType::ISTORE; ibc.type = InstructionType::ISTORE;
ibc.idst = &r[dst]; ibc.idst = &r[dst];
ibc.isrc = &r[src]; ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
} break; } break;
CASE_REP(FSTORE) { CASE_REP(FSTORE) {

View File

@ -152,7 +152,7 @@ program_begin:
;# 256 instructions ;# 256 instructions
include program.inc include program.inc
IF 1
mov eax, r12d ;# read address register 1 mov eax, r12d ;# read address register 1
xor eax, r15d ;# read address register 2 xor eax, r15d ;# read address register 2
xor rbp, rax ;# modify "mx" xor rbp, rax ;# modify "mx"
@ -189,6 +189,26 @@ program_begin:
movapd xmmword ptr [rcx+16], xmm1 movapd xmmword ptr [rcx+16], xmm1
movapd xmmword ptr [rcx+32], xmm2 movapd xmmword ptr [rcx+32], xmm2
movapd xmmword ptr [rcx+48], xmm3 movapd xmmword ptr [rcx+48], xmm3
else
; memcpy trace from stack to scratchpad
mov rax, rsi
mov rdx, rdi
cld
mov rsi, rsp
mov rdi, rax
mov rcx, 1024
rep movsq
add rsp, 8192
pop rcx
pop rcx
mov rsi, rax
mov rdi, rdx
endif
sub ebx, 1 sub ebx, 1
jnz program_begin jnz program_begin

View File

@ -183,6 +183,12 @@ void mine(RandomX::VirtualMachine* vm, std::atomic<int>& atomicNonce, AtomicHash
fillAes1Rx4<softAes>((void*)hash, sizeof(RandomX::Program), vm->getProgramBuffer()); fillAes1Rx4<softAes>((void*)hash, sizeof(RandomX::Program), vm->getProgramBuffer());
vm->initialize(); vm->initialize();
vm->execute(); vm->execute();
/*if (RandomX::trace) {
for (int j = 0; j < RandomX::ProgramLength; ++j) {
uint64_t res = *(uint64_t*)(scratchpad + 8 * (RandomX::ProgramLength - 1 - j));
std::cout << std::hex << std::setw(16) << std::setfill('0') << res << std::endl;
}
}*/
vm->getResult<softAes>(scratchpad, RandomX::ScratchpadSize, hash); vm->getResult<softAes>(scratchpad, RandomX::ScratchpadSize, hash);
result.xorWith(hash); result.xorWith(hash);
if (RandomX::trace) { if (RandomX::trace) {