mirror of
https://git.wownero.com/wownero/RandomWOW.git
synced 2025-01-03 05:38:54 +00:00
Simplified division in interpreted mode
Fixed incorrect condition code in JitCompilerX86 Refactoring
This commit is contained in:
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,23 +135,21 @@ 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) {
|
|
||||||
quotient = quotient == UINT64_MAX ? UINT64_MAX : quotient + 1;
|
|
||||||
}
|
|
||||||
quotient = mulh(quotient, ibc.signedMultiplier);
|
|
||||||
quotient >>= ibc.postShift;
|
|
||||||
*ibc.idst += quotient;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*ibc.idst += *ibc.idst >> ibc.shift;
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case InstructionType::ISDIV_C: {
|
case InstructionType::ISDIV_C: {
|
||||||
|
if (ibc.simm != -1) {
|
||||||
|
int64_t dividend = unsigned64ToSigned2sCompl(*ibc.idst);
|
||||||
|
int64_t quotient = dividend / ibc.simm;
|
||||||
|
*ibc.idst += quotient;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint64_t quotient = ~(*ibc.idst) + 1;
|
||||||
|
*ibc.idst += quotient;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case InstructionType::INEG_R: {
|
case InstructionType::INEG_R: {
|
||||||
@ -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…
Reference in New Issue
Block a user