|
|
@ -11,7 +11,7 @@ namespace Tegra {
|
|
|
|
|
|
|
|
|
|
|
|
MacroInterpreter::MacroInterpreter(Engines::Maxwell3D& maxwell3d) : maxwell3d(maxwell3d) {}
|
|
|
|
MacroInterpreter::MacroInterpreter(Engines::Maxwell3D& maxwell3d) : maxwell3d(maxwell3d) {}
|
|
|
|
|
|
|
|
|
|
|
|
void MacroInterpreter::Execute(const std::vector<u32>& code, std::vector<u32> parameters) {
|
|
|
|
void MacroInterpreter::Execute(u32 offset, std::vector<u32> parameters) {
|
|
|
|
Reset();
|
|
|
|
Reset();
|
|
|
|
registers[1] = parameters[0];
|
|
|
|
registers[1] = parameters[0];
|
|
|
|
this->parameters = std::move(parameters);
|
|
|
|
this->parameters = std::move(parameters);
|
|
|
@ -19,7 +19,7 @@ void MacroInterpreter::Execute(const std::vector<u32>& code, std::vector<u32> pa
|
|
|
|
// Execute the code until we hit an exit condition.
|
|
|
|
// Execute the code until we hit an exit condition.
|
|
|
|
bool keep_executing = true;
|
|
|
|
bool keep_executing = true;
|
|
|
|
while (keep_executing) {
|
|
|
|
while (keep_executing) {
|
|
|
|
keep_executing = Step(code, false);
|
|
|
|
keep_executing = Step(offset, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Assert the the macro used all the input parameters
|
|
|
|
// Assert the the macro used all the input parameters
|
|
|
@ -37,10 +37,10 @@ void MacroInterpreter::Reset() {
|
|
|
|
next_parameter_index = 1;
|
|
|
|
next_parameter_index = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) {
|
|
|
|
bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) {
|
|
|
|
u32 base_address = pc;
|
|
|
|
u32 base_address = pc;
|
|
|
|
|
|
|
|
|
|
|
|
Opcode opcode = GetOpcode(code);
|
|
|
|
Opcode opcode = GetOpcode(offset);
|
|
|
|
pc += 4;
|
|
|
|
pc += 4;
|
|
|
|
|
|
|
|
|
|
|
|
// Update the program counter if we were delayed
|
|
|
|
// Update the program counter if we were delayed
|
|
|
@ -108,7 +108,7 @@ bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) {
|
|
|
|
|
|
|
|
|
|
|
|
delayed_pc = base_address + opcode.GetBranchTarget();
|
|
|
|
delayed_pc = base_address + opcode.GetBranchTarget();
|
|
|
|
// Execute one more instruction due to the delay slot.
|
|
|
|
// Execute one more instruction due to the delay slot.
|
|
|
|
return Step(code, true);
|
|
|
|
return Step(offset, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -121,17 +121,18 @@ bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) {
|
|
|
|
// Exit has a delay slot, execute the next instruction
|
|
|
|
// Exit has a delay slot, execute the next instruction
|
|
|
|
// Note: Executing an exit during a branch delay slot will cause the instruction at the
|
|
|
|
// Note: Executing an exit during a branch delay slot will cause the instruction at the
|
|
|
|
// branch target to be executed before exiting.
|
|
|
|
// branch target to be executed before exiting.
|
|
|
|
Step(code, true);
|
|
|
|
Step(offset, true);
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MacroInterpreter::Opcode MacroInterpreter::GetOpcode(const std::vector<u32>& code) const {
|
|
|
|
MacroInterpreter::Opcode MacroInterpreter::GetOpcode(u32 offset) const {
|
|
|
|
|
|
|
|
const auto& macro_memory{maxwell3d.GetMacroMemory()};
|
|
|
|
ASSERT((pc % sizeof(u32)) == 0);
|
|
|
|
ASSERT((pc % sizeof(u32)) == 0);
|
|
|
|
ASSERT(pc < code.size() * sizeof(u32));
|
|
|
|
ASSERT((pc + offset) < macro_memory.size() * sizeof(u32));
|
|
|
|
return {code[pc / sizeof(u32)]};
|
|
|
|
return {macro_memory[offset + pc / sizeof(u32)]};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const {
|
|
|
|
u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const {
|
|
|
|