Unique scratchpad addresses - interpreter

Additional writes to L3
This commit is contained in:
tevador
2019-04-16 18:58:44 +02:00
parent 33a2fd021d
commit 682000b1a9
11 changed files with 161 additions and 112 deletions
+57 -42
View File
@@ -45,6 +45,8 @@ constexpr bool fpuCheck = false;
namespace RandomX {
static int_reg_t Zero = 0;
template<bool superscalar>
void InterpretedVirtualMachine<superscalar>::setDataset(dataset_t ds, uint64_t size, SuperscalarProgram(&programs)[RANDOMX_CACHE_ACCESSES]) {
mem.ds = ds;
@@ -108,6 +110,12 @@ namespace RandomX {
return std::fpclassify(x) == FP_SUBNORMAL;
}
template<bool superscalar>
FORCE_INLINE void* InterpretedVirtualMachine<superscalar>::getScratchpadAddress(InstructionByteCode& ibc) {
uint32_t addr = (*ibc.isrc + ibc.imm) & ibc.memMask;
return scratchpad + addr;
}
template<bool superscalar>
FORCE_INLINE void InterpretedVirtualMachine<superscalar>::executeBytecode(int& ic, int_reg_t(&r)[8], __m128d (&f)[4], __m128d (&e)[4], __m128d (&a)[4]) {
auto& ibc = byteCode[ic];
@@ -120,7 +128,7 @@ namespace RandomX {
} break;
case InstructionType::IADD_M: {
*ibc.idst += load64(scratchpad + (*ibc.isrc & ibc.memMask));
*ibc.idst += load64(getScratchpadAddress(ibc));
} break;
case InstructionType::IADD_RC: {
@@ -132,7 +140,7 @@ namespace RandomX {
} break;
case InstructionType::ISUB_M: {
*ibc.idst -= load64(scratchpad + (*ibc.isrc & ibc.memMask));
*ibc.idst -= load64(getScratchpadAddress(ibc));
} break;
case InstructionType::IMUL_9C: {
@@ -144,7 +152,7 @@ namespace RandomX {
} break;
case InstructionType::IMUL_M: {
*ibc.idst *= load64(scratchpad + (*ibc.isrc & ibc.memMask));
*ibc.idst *= load64(getScratchpadAddress(ibc));
} break;
case InstructionType::IMULH_R: {
@@ -152,7 +160,7 @@ namespace RandomX {
} break;
case InstructionType::IMULH_M: {
*ibc.idst = mulh(*ibc.idst, load64(scratchpad + (*ibc.isrc & ibc.memMask)));
*ibc.idst = mulh(*ibc.idst, load64(getScratchpadAddress(ibc)));
} break;
case InstructionType::ISMULH_R: {
@@ -160,7 +168,7 @@ namespace RandomX {
} break;
case InstructionType::ISMULH_M: {
*ibc.idst = smulh(unsigned64ToSigned2sCompl(*ibc.idst), unsigned64ToSigned2sCompl(load64(scratchpad + (*ibc.isrc & ibc.memMask))));
*ibc.idst = smulh(unsigned64ToSigned2sCompl(*ibc.idst), unsigned64ToSigned2sCompl(load64(getScratchpadAddress(ibc))));
} break;
case InstructionType::INEG_R: {
@@ -172,7 +180,7 @@ namespace RandomX {
} break;
case InstructionType::IXOR_M: {
*ibc.idst ^= load64(scratchpad + (*ibc.isrc & ibc.memMask));
*ibc.idst ^= load64(getScratchpadAddress(ibc));
} break;
case InstructionType::IROR_R: {
@@ -198,7 +206,7 @@ namespace RandomX {
} break;
case InstructionType::FADD_M: {
__m128d fsrc = load_cvt_i32x2(scratchpad + (*ibc.isrc & ibc.memMask));
__m128d fsrc = load_cvt_i32x2(getScratchpadAddress(ibc));
*ibc.fdst = _mm_add_pd(*ibc.fdst, fsrc);
} break;
@@ -207,7 +215,7 @@ namespace RandomX {
} break;
case InstructionType::FSUB_M: {
__m128d fsrc = load_cvt_i32x2(scratchpad + (*ibc.isrc & ibc.memMask));
__m128d fsrc = load_cvt_i32x2(getScratchpadAddress(ibc));
*ibc.fdst = _mm_sub_pd(*ibc.fdst, fsrc);
} break;
@@ -221,7 +229,7 @@ namespace RandomX {
} break;
case InstructionType::FDIV_M: {
__m128d fsrc = ieee_set_exponent<-240>(load_cvt_i32x2(scratchpad + (*ibc.isrc & ibc.memMask)));
__m128d fsrc = ieee_set_exponent<-240>(load_cvt_i32x2(getScratchpadAddress(ibc)));
*ibc.fdst = _mm_div_pd(*ibc.fdst, fsrc);
} break;
@@ -262,7 +270,7 @@ namespace RandomX {
count_JUMP_not_taken++;
#endif
#endif
*ibc.idst += condition(ibc.condition, load64(scratchpad + (*ibc.isrc & ibc.memMask)), ibc.imm) ? 1 : 0;
*ibc.idst += condition(ibc.condition, load64(getScratchpadAddress(ibc)), ibc.imm) ? 1 : 0;
} break;
case InstructionType::CFROUND: {
@@ -270,7 +278,7 @@ namespace RandomX {
} break;
case InstructionType::ISTORE: {
store64(scratchpad + (*ibc.idst & ibc.memMask), *ibc.isrc);
store64(scratchpad + ((*ibc.idst + ibc.imm) & ibc.memMask), *ibc.isrc);
} break;
case InstructionType::NOP: {
@@ -486,7 +494,7 @@ namespace RandomX {
r[instr.dst] ^= r[instr.src];
break;
case RandomX::SuperscalarInstructionType::IADD_RS:
r[instr.dst] += r[instr.src] << (instr.mod % 4);
r[instr.dst] += r[instr.src] << instr.getModShift2();
break;
case RandomX::SuperscalarInstructionType::IMUL_R:
r[instr.dst] *= r[instr.src];
@@ -585,14 +593,14 @@ namespace RandomX {
auto src = instr.src % RegistersCount;
ibc.type = InstructionType::IADD_RS;
ibc.idst = &r[dst];
if (dst != 5) {
if (dst != RegisterNeedsDisplacement) {
ibc.isrc = &r[src];
ibc.shift = instr.mod % 4;
ibc.shift = instr.getModShift2();
ibc.imm = 0;
}
else {
ibc.isrc = &r[src];
ibc.shift = instr.mod % 4;
ibc.shift = instr.getModShift2();
ibc.imm = signExtend2sCompl(instr.getImm32());
}
registerUsage[instr.dst] = i;
@@ -603,13 +611,13 @@ namespace RandomX {
auto src = instr.src % RegistersCount;
ibc.type = InstructionType::IADD_M;
ibc.idst = &r[dst];
ibc.imm = signExtend2sCompl(instr.getImm32());
if (instr.src != instr.dst) {
ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
}
else {
ibc.imm = instr.getImm32();
ibc.isrc = &ibc.imm;
ibc.isrc = &Zero;
ibc.memMask = ScratchpadL3Mask;
}
registerUsage[instr.dst] = i;
@@ -645,13 +653,13 @@ namespace RandomX {
auto src = instr.src % RegistersCount;
ibc.type = InstructionType::ISUB_M;
ibc.idst = &r[dst];
ibc.imm = signExtend2sCompl(instr.getImm32());
if (instr.src != instr.dst) {
ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
}
else {
ibc.imm = instr.getImm32();
ibc.isrc = &ibc.imm;
ibc.isrc = &Zero;
ibc.memMask = ScratchpadL3Mask;
}
registerUsage[instr.dst] = i;
@@ -685,13 +693,13 @@ namespace RandomX {
auto src = instr.src % RegistersCount;
ibc.type = InstructionType::IMUL_M;
ibc.idst = &r[dst];
ibc.imm = signExtend2sCompl(instr.getImm32());
if (instr.src != instr.dst) {
ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
}
else {
ibc.imm = instr.getImm32();
ibc.isrc = &ibc.imm;
ibc.isrc = &Zero;
ibc.memMask = ScratchpadL3Mask;
}
registerUsage[instr.dst] = i;
@@ -711,13 +719,13 @@ namespace RandomX {
auto src = instr.src % RegistersCount;
ibc.type = InstructionType::IMULH_M;
ibc.idst = &r[dst];
ibc.imm = signExtend2sCompl(instr.getImm32());
if (instr.src != instr.dst) {
ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
}
else {
ibc.imm = instr.getImm32();
ibc.isrc = &ibc.imm;
ibc.isrc = &Zero;
ibc.memMask = ScratchpadL3Mask;
}
registerUsage[instr.dst] = i;
@@ -737,13 +745,13 @@ namespace RandomX {
auto src = instr.src % RegistersCount;
ibc.type = InstructionType::ISMULH_M;
ibc.idst = &r[dst];
ibc.imm = signExtend2sCompl(instr.getImm32());
if (instr.src != instr.dst) {
ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
}
else {
ibc.imm = instr.getImm32();
ibc.isrc = &ibc.imm;
ibc.isrc = &Zero;
ibc.memMask = ScratchpadL3Mask;
}
registerUsage[instr.dst] = i;
@@ -791,13 +799,13 @@ namespace RandomX {
auto src = instr.src % RegistersCount;
ibc.type = InstructionType::IXOR_M;
ibc.idst = &r[dst];
ibc.imm = signExtend2sCompl(instr.getImm32());
if (instr.src != instr.dst) {
ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
}
else {
ibc.imm = instr.getImm32();
ibc.isrc = &ibc.imm;
ibc.isrc = &Zero;
ibc.memMask = ScratchpadL3Mask;
}
registerUsage[instr.dst] = i;
@@ -871,7 +879,8 @@ namespace RandomX {
ibc.type = InstructionType::FADD_M;
ibc.fdst = &f[dst];
ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.imm = signExtend2sCompl(instr.getImm32());
} break;
CASE_REP(FSUB_R) {
@@ -888,7 +897,8 @@ namespace RandomX {
ibc.type = InstructionType::FSUB_M;
ibc.fdst = &f[dst];
ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.imm = signExtend2sCompl(instr.getImm32());
} break;
CASE_REP(FSCAL_R) {
@@ -911,7 +921,8 @@ namespace RandomX {
ibc.type = InstructionType::FDIV_M;
ibc.fdst = &e[dst];
ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.imm = signExtend2sCompl(instr.getImm32());
} break;
CASE_REP(FSQRT_R) {
@@ -926,12 +937,12 @@ namespace RandomX {
ibc.type = InstructionType::COND_R;
ibc.idst = &r[dst];
ibc.isrc = &r[src];
ibc.condition = (instr.mod >> 2) & 7;
ibc.condition = instr.getModCond();
ibc.imm = instr.getImm32();
//jump condition
int reg = getConditionRegister(registerUsage);
ibc.target = registerUsage[reg];
ibc.shift = (instr.mod >> 5);
ibc.shift = instr.getModShift3();
ibc.creg = &r[reg];
for (unsigned j = 0; j < 8; ++j) { //mark all registers as used
registerUsage[j] = i;
@@ -944,13 +955,13 @@ namespace RandomX {
ibc.type = InstructionType::COND_M;
ibc.idst = &r[dst];
ibc.isrc = &r[src];
ibc.condition = (instr.mod >> 2) & 7;
ibc.condition = instr.getModCond();
ibc.imm = instr.getImm32();
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
//jump condition
int reg = getConditionRegister(registerUsage);
ibc.target = registerUsage[reg];
ibc.shift = (instr.mod >> 5);
ibc.shift = instr.getModShift3();
ibc.creg = &r[reg];
for (unsigned j = 0; j < 8; ++j) { //mark all registers as used
registerUsage[j] = i;
@@ -970,7 +981,11 @@ namespace RandomX {
ibc.type = InstructionType::ISTORE;
ibc.idst = &r[dst];
ibc.isrc = &r[src];
ibc.memMask = ((instr.mod % 4) ? ScratchpadL1Mask : ScratchpadL2Mask);
ibc.imm = signExtend2sCompl(instr.getImm32());
if (instr.getModCond())
ibc.memMask = (instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask);
else
ibc.memMask = ScratchpadL3Mask;
} break;
CASE_REP(NOP) {