Simplified division in interpreted mode

Fixed incorrect condition code in JitCompilerX86
Refactoring
debug
tevador 5 years ago
parent 1df975e583
commit 447e8a1d4f

@ -431,8 +431,8 @@ namespace RandomX {
asmCode << "\tldmxcsr dword ptr [rsp-8]" << std::endl; asmCode << "\tldmxcsr dword ptr [rsp-8]" << std::endl;
} }
static inline const char* condition(Instruction& instr, bool invert = false) { static inline const char* condition(Instruction& instr) {
switch (((instr.mod >> 2) & 7) ^ invert) switch ((instr.mod >> 2) & 7)
{ {
case 0: case 0:
return "be"; return "be";

@ -33,7 +33,6 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
#ifdef STATS #ifdef STATS
#include <algorithm> #include <algorithm>
#endif #endif
#include "divideByConstantCodegen.h"
#ifdef FPUCHECK #ifdef FPUCHECK
constexpr bool fpuCheck = true; constexpr bool fpuCheck = true;
@ -136,25 +135,23 @@ namespace RandomX {
} break; } break;
case InstructionType::IDIV_C: { case InstructionType::IDIV_C: {
if (ibc.signedMultiplier != 0) { uint64_t dividend = *ibc.idst;
int_reg_t dividend = *ibc.idst; uint64_t quotient = dividend / ibc.imm;
int_reg_t quotient = dividend >> ibc.preShift; *ibc.idst += quotient;
if (ibc.increment) { } break;
quotient = quotient == UINT64_MAX ? UINT64_MAX : quotient + 1;
} case InstructionType::ISDIV_C: {
quotient = mulh(quotient, ibc.signedMultiplier); if (ibc.simm != -1) {
quotient >>= ibc.postShift; int64_t dividend = unsigned64ToSigned2sCompl(*ibc.idst);
int64_t quotient = dividend / ibc.simm;
*ibc.idst += quotient; *ibc.idst += quotient;
} }
else { else {
*ibc.idst += *ibc.idst >> ibc.shift; uint64_t quotient = ~(*ibc.idst) + 1;
*ibc.idst += quotient;
} }
} break; } break;
case InstructionType::ISDIV_C: {
} break;
case InstructionType::INEG_R: { case InstructionType::INEG_R: {
*ibc.idst = ~(*ibc.idst) + 1; //two's complement negative *ibc.idst = ~(*ibc.idst) + 1; //two's complement negative
} break; } break;
@ -204,8 +201,8 @@ namespace RandomX {
} break; } break;
case InstructionType::FSCAL_R: { case InstructionType::FSCAL_R: {
const __m128d signMask = _mm_castsi128_pd(_mm_set1_epi64x(0x81F0000000000000)); const __m128d mask = _mm_castsi128_pd(_mm_set1_epi64x(0x81F0000000000000));
*ibc.fdst = _mm_xor_pd(*ibc.fdst, signMask); *ibc.fdst = _mm_xor_pd(*ibc.fdst, mask);
} break; } break;
case InstructionType::FMUL_R: { case InstructionType::FMUL_R: {
@ -516,20 +513,7 @@ namespace RandomX {
auto dst = instr.dst % RegistersCount; auto dst = instr.dst % RegistersCount;
ibc.type = InstructionType::IDIV_C; ibc.type = InstructionType::IDIV_C;
ibc.idst = &r[dst]; ibc.idst = &r[dst];
if (divisor & (divisor - 1)) { ibc.imm = divisor;
magicu_info mi = compute_unsigned_magic_info(divisor, sizeof(uint64_t) * 8);
ibc.signedMultiplier = mi.multiplier;
ibc.preShift = mi.pre_shift;
ibc.postShift = mi.post_shift;
ibc.increment = mi.increment;
}
else {
ibc.signedMultiplier = 0;
int shift = 0;
while (divisor >>= 1)
++shift;
ibc.shift = shift;
}
} }
else { else {
ibc.type = InstructionType::NOP; ibc.type = InstructionType::NOP;
@ -537,7 +521,16 @@ namespace RandomX {
} break; } break;
CASE_REP(ISDIV_C) { CASE_REP(ISDIV_C) {
ibc.type = InstructionType::NOP; int32_t divisor = unsigned32ToSigned2sCompl(instr.imm32);
if (divisor != 0) {
auto dst = instr.dst % RegistersCount;
ibc.type = InstructionType::ISDIV_C;
ibc.idst = &r[dst];
ibc.simm = divisor;
}
else {
ibc.type = InstructionType::NOP;
}
} break; } break;
CASE_REP(INEG_R) { CASE_REP(INEG_R) {

@ -38,23 +38,18 @@ namespace RandomX {
typedef void(InterpretedVirtualMachine::*InstructionHandler)(Instruction&); typedef void(InterpretedVirtualMachine::*InstructionHandler)(Instruction&);
struct alignas(16) InstructionByteCode { struct alignas(8) InstructionByteCode {
int_reg_t* idst; int_reg_t* idst;
int_reg_t* isrc; int_reg_t* isrc;
int_reg_t imm; union {
uint64_t imm;
int64_t simm;
};
__m128d* fdst; __m128d* fdst;
__m128d* fsrc; __m128d* fsrc;
uint32_t condition; uint32_t condition;
uint32_t memMask; uint32_t memMask;
uint32_t type; uint32_t type;
union {
uint64_t unsignedMultiplier;
int64_t signedMultiplier;
};
unsigned shift;
unsigned preShift;
unsigned postShift;
bool increment;
}; };
constexpr int asedwfagdewsa = sizeof(InstructionByteCode); constexpr int asedwfagdewsa = sizeof(InstructionByteCode);

@ -666,8 +666,8 @@ namespace RandomX {
emit(AND_OR_MOV_LDMXCSR); emit(AND_OR_MOV_LDMXCSR);
} }
static inline uint8_t condition(Instruction& instr, bool invert = false) { static inline uint8_t condition(Instruction& instr) {
switch ((instr.mod & 7) ^ invert) switch ((instr.mod >> 2) & 7)
{ {
case 0: case 0:
return 0x96; //setbe return 0x96; //setbe

@ -102,7 +102,7 @@ public:
os << std::endl; os << std::endl;
} }
private: private:
void print(std::atomic<uint64_t>& hash, std::ostream& os) { static void print(std::atomic<uint64_t>& hash, std::ostream& os) {
auto h = hash.load(); auto h = hash.load();
outputHex(std::cout, (char*)&h, sizeof(h)); outputHex(std::cout, (char*)&h, sizeof(h));
} }

Loading…
Cancel
Save