Skip to content

Commit ffebc37

Browse files
committed
COND_R instruction reworked as CBRANCH
instruction mod field bits reallocated
1 parent ebddaf6 commit ffebc37

12 files changed

+166
-313
lines changed

doc/program.asm

+107-139
Large diffs are not rendered by default.

src/assembly_generator_x86.cpp

+10-49
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,12 @@ namespace randomx {
4444
static const char* regScratchpadAddr = "rsi";
4545

4646
void AssemblyGeneratorX86::generateProgram(Program& prog) {
47-
for (unsigned i = 0; i < 8; ++i) {
47+
for (unsigned i = 0; i < RegistersCount; ++i) {
4848
registerUsage[i] = -1;
4949
}
5050
asmCode.str(std::string()); //clear
5151
for (unsigned i = 0; i < prog.getSize(); ++i) {
52-
#if RANDOMX_JUMP
5352
asmCode << "randomx_isn_" << i << ":" << std::endl;
54-
#endif
5553
Instruction& instr = prog(i);
5654
instr.src %= RegistersCount;
5755
instr.dst %= RegistersCount;
@@ -261,7 +259,7 @@ namespace randomx {
261259
void AssemblyGeneratorX86::genAddressRegDst(Instruction& instr, int maskAlign = 8) {
262260
asmCode << "\tlea eax, [" << regR32[instr.dst] << std::showpos << (int32_t)instr.getImm32() << std::noshowpos << "]" << std::endl;
263261
int mask;
264-
if (instr.getModCond()) {
262+
if (instr.getModCond() < StoreL3Condition) {
265263
mask = instr.getModMem() ? ScratchpadL1Mask : ScratchpadL2Mask;
266264
}
267265
else {
@@ -277,9 +275,9 @@ namespace randomx {
277275
void AssemblyGeneratorX86::h_IADD_RS(Instruction& instr, int i) {
278276
registerUsage[instr.dst] = i;
279277
if(instr.dst == RegisterNeedsDisplacement)
280-
asmCode << "\tlea " << regR[instr.dst] << ", [" << regR[instr.dst] << "+" << regR[instr.src] << "*" << (1 << (instr.getModMem())) << std::showpos << (int32_t)instr.getImm32() << std::noshowpos << "]" << std::endl;
278+
asmCode << "\tlea " << regR[instr.dst] << ", [" << regR[instr.dst] << "+" << regR[instr.src] << "*" << (1 << (instr.getModShift())) << std::showpos << (int32_t)instr.getImm32() << std::noshowpos << "]" << std::endl;
281279
else
282-
asmCode << "\tlea " << regR[instr.dst] << ", [" << regR[instr.dst] << "+" << regR[instr.src] << "*" << (1 << (instr.getModMem())) << "]" << std::endl;
280+
asmCode << "\tlea " << regR[instr.dst] << ", [" << regR[instr.dst] << "+" << regR[instr.src] << "*" << (1 << (instr.getModShift())) << "]" << std::endl;
283281
traceint(instr);
284282
}
285283

@@ -542,55 +540,18 @@ namespace randomx {
542540
tracenop(instr);
543541
}
544542

545-
static inline const char* condition(Instruction& instr) {
546-
switch (instr.getModCond())
547-
{
548-
case 0:
549-
return "be";
550-
case 1:
551-
return "a";
552-
case 2:
553-
return "s";
554-
case 3:
555-
return "ns";
556-
case 4:
557-
return "o";
558-
case 5:
559-
return "no";
560-
case 6:
561-
return "l";
562-
case 7:
563-
return "ge";
564-
default:
565-
UNREACHABLE;
566-
}
567-
}
568-
569-
void AssemblyGeneratorX86::handleCondition(Instruction& instr, int i) {
570-
const int shift = instr.getModShift();
571-
const int conditionMask = ((1 << RANDOMX_JUMP_BITS) - 1) << shift;
543+
void AssemblyGeneratorX86::h_CBRANCH(Instruction& instr, int i) {
572544
int reg = getConditionRegister();
573545
int target = registerUsage[reg] + 1;
574-
registerUsage[reg] = i;
575-
asmCode << "\tadd " << regR[reg] << ", " << (1 << shift) << std::endl;
576-
asmCode << "\ttest " << regR[reg] << ", " << conditionMask << std::endl;
546+
int shift = instr.getModCond();
547+
asmCode << "\tadd " << regR[reg] << ", " << (int32_t)(instr.getImm32() | (1 << shift)) << std::endl;
548+
asmCode << "\ttest " << regR[reg] << ", " << (ConditionMask << shift) << std::endl;
577549
asmCode << "\tjz randomx_isn_" << target << std::endl;
578-
for (unsigned j = 0; j < 8; ++j) { //mark all registers as used
550+
for (unsigned j = 0; j < RegistersCount; ++j) { //mark all registers as used
579551
registerUsage[j] = i;
580552
}
581553
}
582554

583-
void AssemblyGeneratorX86::h_COND_R(Instruction& instr, int i) {
584-
#if RANDOMX_JUMP
585-
handleCondition(instr, i);
586-
#endif
587-
asmCode << "\txor ecx, ecx" << std::endl;
588-
asmCode << "\tcmp " << regR32[instr.src] << ", " << (int32_t)instr.getImm32() << std::endl;
589-
asmCode << "\tset" << condition(instr) << " cl" << std::endl;
590-
asmCode << "\tadd " << regR[instr.dst] << ", rcx" << std::endl;
591-
traceint(instr);
592-
}
593-
594555
void AssemblyGeneratorX86::h_ISTORE(Instruction& instr, int i) {
595556
genAddressRegDst(instr);
596557
asmCode << "\tmov qword ptr [" << regScratchpadAddr << "+rax], " << regR[instr.src] << std::endl;
@@ -632,7 +593,7 @@ namespace randomx {
632593
INST_HANDLE(FMUL_R)
633594
INST_HANDLE(FDIV_M)
634595
INST_HANDLE(FSQRT_R)
635-
INST_HANDLE(COND_R)
596+
INST_HANDLE(CBRANCH)
636597
INST_HANDLE(CFROUND)
637598
INST_HANDLE(ISTORE)
638599
INST_HANDLE(NOP)

src/assembly_generator_x86.hpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ namespace randomx {
4444
void genAddressRegDst(Instruction&, int);
4545
int32_t genAddressImm(Instruction&);
4646
int getConditionRegister();
47-
void handleCondition(Instruction&, int);
4847
void generateCode(Instruction&, int);
4948
void traceint(Instruction&);
5049
void traceflt(Instruction&);
@@ -76,7 +75,7 @@ namespace randomx {
7675
void h_FMUL_R(Instruction&, int);
7776
void h_FDIV_M(Instruction&, int);
7877
void h_FSQRT_R(Instruction&, int);
79-
void h_COND_R(Instruction&, int);
78+
void h_CBRANCH(Instruction&, int);
8079
void h_CFROUND(Instruction&, int);
8180
void h_ISTORE(Instruction&, int);
8281
void h_NOP(Instruction&, int);

src/common.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,14 @@ namespace randomx {
4040
static_assert(RANDOMX_SCRATCHPAD_L2 >= RANDOMX_SCRATCHPAD_L1, "RANDOMX_SCRATCHPAD_L2 must be greater than or equal to RANDOMX_SCRATCHPAD_L1.");
4141
static_assert((RANDOMX_SCRATCHPAD_L1 & (RANDOMX_SCRATCHPAD_L1 - 1)) == 0, "RANDOMX_SCRATCHPAD_L1 must be a power of 2.");
4242
static_assert(RANDOMX_CACHE_ACCESSES > 1, "RANDOMX_CACHE_ACCESSES must be greater than 1");
43+
static_assert(RANDOMX_JUMP_BITS >= 1 && RANDOMX_JUMP_BITS <= 16, "RANDOMX_JUMP_BITS must be an integer in the range 1-16.");
4344

4445
constexpr int wtSum = RANDOMX_FREQ_IADD_RS + RANDOMX_FREQ_IADD_M + RANDOMX_FREQ_ISUB_R + \
4546
RANDOMX_FREQ_ISUB_M + RANDOMX_FREQ_IMUL_R + RANDOMX_FREQ_IMUL_M + RANDOMX_FREQ_IMULH_R + \
4647
RANDOMX_FREQ_IMULH_M + RANDOMX_FREQ_ISMULH_R + RANDOMX_FREQ_ISMULH_M + RANDOMX_FREQ_IMUL_RCP + \
4748
RANDOMX_FREQ_INEG_R + RANDOMX_FREQ_IXOR_R + RANDOMX_FREQ_IXOR_M + RANDOMX_FREQ_IROR_R + RANDOMX_FREQ_ISWAP_R + \
4849
RANDOMX_FREQ_FSWAP_R + RANDOMX_FREQ_FADD_R + RANDOMX_FREQ_FADD_M + RANDOMX_FREQ_FSUB_R + RANDOMX_FREQ_FSUB_M + \
49-
RANDOMX_FREQ_FSCAL_R + RANDOMX_FREQ_FMUL_R + RANDOMX_FREQ_FDIV_M + RANDOMX_FREQ_FSQRT_R + RANDOMX_FREQ_COND_R + \
50+
RANDOMX_FREQ_FSCAL_R + RANDOMX_FREQ_FMUL_R + RANDOMX_FREQ_FDIV_M + RANDOMX_FREQ_FSQRT_R + RANDOMX_FREQ_CBRANCH + \
5051
RANDOMX_FREQ_CFROUND + RANDOMX_FREQ_ISTORE + RANDOMX_FREQ_NOP;
5152

5253
static_assert(wtSum == 256, "Sum of instruction frequencies must be 256.");
@@ -59,6 +60,8 @@ namespace randomx {
5960
constexpr uint32_t CacheSize = RANDOMX_ARGON_MEMORY * ArgonBlockSize;
6061
constexpr uint64_t DatasetSize = RANDOMX_DATASET_BASE_SIZE + RANDOMX_DATASET_EXTRA_SIZE;
6162
constexpr uint32_t DatasetExtraItems = RANDOMX_DATASET_EXTRA_SIZE / RANDOMX_DATASET_ITEM_SIZE;
63+
constexpr uint32_t ConditionMask = ((1 << RANDOMX_JUMP_BITS) - 1);
64+
constexpr int StoreL3Condition = 14;
6265

6366
#ifdef TRACE
6467
constexpr bool trace = true;
@@ -76,8 +79,6 @@ namespace randomx {
7679
#endif
7780
#endif
7881

79-
#define RANDOMX_JUMP (RANDOMX_JUMP_BITS > 0)
80-
8182
using addr_t = uint32_t;
8283

8384
using int_reg_t = uint64_t;

src/configuration.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
6464
//Scratchpad L1 size in bytes. Must be a power of two and less than or equal to RANDOMX_SCRATCHPAD_L2.
6565
#define RANDOMX_SCRATCHPAD_L1 (16 * 1024)
6666

67-
//How many register bits must be zero for a jump condition to be triggered. If set to 0, jumps are disabled.
67+
//How many register bits must be zero for CBRANCH instruction to jump. Must be an integer in the range 1-16.
6868
#define RANDOMX_JUMP_BITS 7
6969

7070
/*
@@ -100,8 +100,9 @@ Total sum of frequencies must be 256
100100
#define RANDOMX_FREQ_FDIV_M 4
101101
#define RANDOMX_FREQ_FSQRT_R 6
102102

103-
#define RANDOMX_FREQ_COND_R 8
103+
#define RANDOMX_FREQ_CBRANCH 8
104104
#define RANDOMX_FREQ_CFROUND 1
105+
105106
#define RANDOMX_FREQ_ISTORE 16
106107

107108
#define RANDOMX_FREQ_NOP 0

src/instruction.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ namespace randomx {
3333
}
3434

3535
void Instruction::genAddressRegDst(std::ostream& os) const {
36-
if (getModCond())
36+
if (getModCond() < StoreL3Condition)
3737
os << (getModMem() ? "L1" : "L2");
3838
else
3939
os << "L3";
@@ -49,7 +49,7 @@ namespace randomx {
4949
if(dst == RegisterNeedsDisplacement) {
5050
os << ", " << (int32_t)getImm32();
5151
}
52-
os << ", LSH " << (int)getModMem() << std::endl;
52+
os << ", SHFT " << (int)getModShift() << std::endl;
5353
}
5454

5555
void Instruction::h_IADD_M(std::ostream& os) const {
@@ -278,8 +278,8 @@ namespace randomx {
278278
}
279279
}
280280

281-
void Instruction::h_COND_R(std::ostream& os) const {
282-
os << "r" << (int)dst << ", " << condition(getModCond()) << "(r" << (int)src << ", " << (int32_t)getImm32() << "), LSH " << (int)(getModShift()) << std::endl;
281+
void Instruction::h_CBRANCH(std::ostream& os) const {
282+
os << (int32_t)getImm32() << ", COND " << (int)(getModCond()) << std::endl;
283283
}
284284

285285
void Instruction::h_ISTORE(std::ostream& os) const {
@@ -321,7 +321,7 @@ namespace randomx {
321321
INST_NAME(FMUL_R)
322322
INST_NAME(FDIV_M)
323323
INST_NAME(FSQRT_R)
324-
INST_NAME(COND_R)
324+
INST_NAME(CBRANCH)
325325
INST_NAME(CFROUND)
326326
INST_NAME(ISTORE)
327327
INST_NAME(NOP)
@@ -354,7 +354,7 @@ namespace randomx {
354354
INST_HANDLE(FMUL_R)
355355
INST_HANDLE(FDIV_M)
356356
INST_HANDLE(FSQRT_R)
357-
INST_HANDLE(COND_R)
357+
INST_HANDLE(CBRANCH)
358358
INST_HANDLE(CFROUND)
359359
INST_HANDLE(ISTORE)
360360
INST_HANDLE(NOP)

src/instruction.hpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ namespace randomx {
5757
constexpr int FMUL_R = 23;
5858
constexpr int FDIV_M = 24;
5959
constexpr int FSQRT_R = 25;
60-
constexpr int COND_R = 26;
60+
constexpr int CBRANCH = 26;
6161
constexpr int CFROUND = 27;
6262
constexpr int ISTORE = 28;
6363
constexpr int NOP = 29;
@@ -81,11 +81,11 @@ namespace randomx {
8181
int getModMem() const {
8282
return mod % 4; //bits 0-1
8383
}
84-
int getModCond() const {
85-
return (mod >> 2) % 8; //bits 2-4
86-
}
8784
int getModShift() const {
88-
return mod >> 5; //bits 5-7
85+
return (mod >> 2) % 4; //bits 2-3
86+
}
87+
int getModCond() const {
88+
return mod >> 4; //bits 4-7
8989
}
9090
void setMod(uint8_t val) {
9191
mod = val;
@@ -129,7 +129,7 @@ namespace randomx {
129129
void h_FMUL_R(std::ostream&) const;
130130
void h_FDIV_M(std::ostream&) const;
131131
void h_FSQRT_R(std::ostream&) const;
132-
void h_COND_R(std::ostream&) const;
132+
void h_CBRANCH(std::ostream&) const;
133133
void h_CFROUND(std::ostream&) const;
134134
void h_ISTORE(std::ostream&) const;
135135
void h_NOP(std::ostream&) const;

0 commit comments

Comments
 (0)