|
|
@@ -573,14 +573,6 @@ namespace randomx {
|
|
|
constexpr int LOOK_FORWARD_CYCLES = 4;
|
|
|
constexpr int MAX_THROWAWAY_COUNT = 256;
|
|
|
|
|
|
-#ifndef _DEBUG
|
|
|
- constexpr bool TRACE = false;
|
|
|
- constexpr bool INFO = false;
|
|
|
-#else
|
|
|
- constexpr bool TRACE = true;
|
|
|
- constexpr bool INFO = true;
|
|
|
-#endif
|
|
|
-
|
|
|
template<bool commit>
|
|
|
static int scheduleUop(ExecutionPort::type uop, ExecutionPort::type(&portBusy)[CYCLE_MAP_SIZE][3], int cycle) {
|
|
|
//The scheduling here is done optimistically by checking port availability in order P5 -> P0 -> P1 to not overload
|
|
|
@@ -588,21 +580,21 @@ namespace randomx {
|
|
|
for (; cycle < CYCLE_MAP_SIZE; ++cycle) {
|
|
|
if ((uop & ExecutionPort::P5) != 0 && !portBusy[cycle][2]) {
|
|
|
if (commit) {
|
|
|
- if (TRACE) std::cout << "; P5 at cycle " << cycle << std::endl;
|
|
|
+ if (trace) std::cout << "; P5 at cycle " << cycle << std::endl;
|
|
|
portBusy[cycle][2] = uop;
|
|
|
}
|
|
|
return cycle;
|
|
|
}
|
|
|
if ((uop & ExecutionPort::P0) != 0 && !portBusy[cycle][0]) {
|
|
|
if (commit) {
|
|
|
- if (TRACE) std::cout << "; P0 at cycle " << cycle << std::endl;
|
|
|
+ if (trace) std::cout << "; P0 at cycle " << cycle << std::endl;
|
|
|
portBusy[cycle][0] = uop;
|
|
|
}
|
|
|
return cycle;
|
|
|
}
|
|
|
if ((uop & ExecutionPort::P1) != 0 && !portBusy[cycle][1]) {
|
|
|
if (commit) {
|
|
|
- if (TRACE) std::cout << "; P1 at cycle " << cycle << std::endl;
|
|
|
+ if (trace) std::cout << "; P1 at cycle " << cycle << std::endl;
|
|
|
portBusy[cycle][1] = uop;
|
|
|
}
|
|
|
return cycle;
|
|
|
@@ -621,7 +613,7 @@ namespace randomx {
|
|
|
//move instructions are eliminated and don't need an execution unit
|
|
|
if (mop.isEliminated()) {
|
|
|
if (commit)
|
|
|
- if (TRACE) std::cout << "; (eliminated)" << std::endl;
|
|
|
+ if (trace) std::cout << "; (eliminated)" << std::endl;
|
|
|
return cycle;
|
|
|
}
|
|
|
else if (mop.isSimple()) {
|
|
|
@@ -677,7 +669,7 @@ namespace randomx {
|
|
|
|
|
|
//select a decode configuration
|
|
|
decodeBuffer = decodeBuffer->fetchNext(currentInstruction.getType(), decodeCycle, mulCount, gen);
|
|
|
- if (TRACE) std::cout << "; ------------- fetch cycle " << cycle << " (" << decodeBuffer->getName() << ")" << std::endl;
|
|
|
+ if (trace) std::cout << "; ------------- fetch cycle " << cycle << " (" << decodeBuffer->getName() << ")" << std::endl;
|
|
|
|
|
|
int bufferIndex = 0;
|
|
|
|
|
|
@@ -692,15 +684,15 @@ namespace randomx {
|
|
|
//select an instruction so that the first macro-op fits into the current slot
|
|
|
currentInstruction.createForSlot(gen, decodeBuffer->getCounts()[bufferIndex], decodeBuffer->getIndex(), decodeBuffer->getSize() == bufferIndex + 1, bufferIndex == 0);
|
|
|
macroOpIndex = 0;
|
|
|
- if (TRACE) std::cout << "; " << currentInstruction.getInfo().getName() << std::endl;
|
|
|
+ if (trace) std::cout << "; " << currentInstruction.getInfo().getName() << std::endl;
|
|
|
}
|
|
|
const MacroOp& mop = currentInstruction.getInfo().getOp(macroOpIndex);
|
|
|
- if (TRACE) std::cout << mop.getName() << " ";
|
|
|
+ if (trace) std::cout << mop.getName() << " ";
|
|
|
|
|
|
//calculate the earliest cycle when this macro-op (all of its uOPs) can be scheduled for execution
|
|
|
int scheduleCycle = scheduleMop<false>(mop, portBusy, cycle, depCycle);
|
|
|
if (scheduleCycle < 0) {
|
|
|
- if (TRACE) std::cout << "Unable to map operation '" << mop.getName() << "' to execution port (cycle " << cycle << ")" << std::endl;
|
|
|
+ if (trace) std::cout << "Unable to map operation '" << mop.getName() << "' to execution port (cycle " << cycle << ")" << std::endl;
|
|
|
//__debugbreak();
|
|
|
portsSaturated = true;
|
|
|
break;
|
|
|
@@ -711,7 +703,7 @@ namespace randomx {
|
|
|
int forward;
|
|
|
//if no suitable operand is ready, look up to LOOK_FORWARD_CYCLES forward
|
|
|
for (forward = 0; forward < LOOK_FORWARD_CYCLES && !currentInstruction.selectSource(scheduleCycle, registers, gen); ++forward) {
|
|
|
- if (TRACE) std::cout << "; src STALL at cycle " << cycle << std::endl;
|
|
|
+ if (trace) std::cout << "; src STALL at cycle " << cycle << std::endl;
|
|
|
++scheduleCycle;
|
|
|
++cycle;
|
|
|
}
|
|
|
@@ -720,22 +712,22 @@ namespace randomx {
|
|
|
if (throwAwayCount < MAX_THROWAWAY_COUNT) {
|
|
|
throwAwayCount++;
|
|
|
macroOpIndex = currentInstruction.getInfo().getSize();
|
|
|
- if (TRACE) std::cout << "; THROW away " << currentInstruction.getInfo().getName() << std::endl;
|
|
|
+ if (trace) std::cout << "; THROW away " << currentInstruction.getInfo().getName() << std::endl;
|
|
|
//cycle = topCycle;
|
|
|
continue;
|
|
|
}
|
|
|
//abort this decode buffer
|
|
|
- if (TRACE) std::cout << "Aborting at cycle " << cycle << " with decode buffer " << decodeBuffer->getName() << " - source registers not available for operation " << currentInstruction.getInfo().getName() << std::endl;
|
|
|
+ if (trace) std::cout << "Aborting at cycle " << cycle << " with decode buffer " << decodeBuffer->getName() << " - source registers not available for operation " << currentInstruction.getInfo().getName() << std::endl;
|
|
|
currentInstruction = SuperscalarInstruction::Null;
|
|
|
break;
|
|
|
}
|
|
|
- if (TRACE) std::cout << "; src = r" << currentInstruction.getSource() << std::endl;
|
|
|
+ if (trace) std::cout << "; src = r" << currentInstruction.getSource() << std::endl;
|
|
|
}
|
|
|
//find a destination register that will be ready when this instruction executes
|
|
|
if (macroOpIndex == currentInstruction.getInfo().getDstOp()) {
|
|
|
int forward;
|
|
|
for (forward = 0; forward < LOOK_FORWARD_CYCLES && !currentInstruction.selectDestination(scheduleCycle, throwAwayCount > 0, registers, gen); ++forward) {
|
|
|
- if (TRACE) std::cout << "; dst STALL at cycle " << cycle << std::endl;
|
|
|
+ if (trace) std::cout << "; dst STALL at cycle " << cycle << std::endl;
|
|
|
++scheduleCycle;
|
|
|
++cycle;
|
|
|
}
|
|
|
@@ -743,16 +735,16 @@ namespace randomx {
|
|
|
if (throwAwayCount < MAX_THROWAWAY_COUNT) {
|
|
|
throwAwayCount++;
|
|
|
macroOpIndex = currentInstruction.getInfo().getSize();
|
|
|
- if (TRACE) std::cout << "; THROW away " << currentInstruction.getInfo().getName() << std::endl;
|
|
|
+ if (trace) std::cout << "; THROW away " << currentInstruction.getInfo().getName() << std::endl;
|
|
|
//cycle = topCycle;
|
|
|
continue;
|
|
|
}
|
|
|
//abort this decode buffer
|
|
|
- if (TRACE) std::cout << "Aborting at cycle " << cycle << " with decode buffer " << decodeBuffer->getName() << " - destination registers not available" << std::endl;
|
|
|
+ if (trace) std::cout << "Aborting at cycle " << cycle << " with decode buffer " << decodeBuffer->getName() << " - destination registers not available" << std::endl;
|
|
|
currentInstruction = SuperscalarInstruction::Null;
|
|
|
break;
|
|
|
}
|
|
|
- if (TRACE) std::cout << "; dst = r" << currentInstruction.getDestination() << std::endl;
|
|
|
+ if (trace) std::cout << "; dst = r" << currentInstruction.getDestination() << std::endl;
|
|
|
}
|
|
|
throwAwayCount = 0;
|
|
|
|
|
|
@@ -773,7 +765,7 @@ namespace randomx {
|
|
|
ri.latency = retireCycle;
|
|
|
ri.lastOpGroup = currentInstruction.getGroup();
|
|
|
ri.lastOpPar = currentInstruction.getGroupPar();
|
|
|
- if (TRACE) std::cout << "; RETIRED at cycle " << retireCycle << std::endl;
|
|
|
+ if (trace) std::cout << "; RETIRED at cycle " << retireCycle << std::endl;
|
|
|
}
|
|
|
codeSize += mop.getSize();
|
|
|
bufferIndex++;
|