|
|
|
@ -11,7 +11,7 @@ namespace Tegra { |
|
|
|
|
|
|
|
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(); |
|
|
|
registers[1] = parameters[0]; |
|
|
|
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.
|
|
|
|
bool keep_executing = true; |
|
|
|
while (keep_executing) { |
|
|
|
keep_executing = Step(code, false); |
|
|
|
keep_executing = Step(offset, false); |
|
|
|
} |
|
|
|
|
|
|
|
// Assert the the macro used all the input parameters
|
|
|
|
@ -37,10 +37,10 @@ void MacroInterpreter::Reset() { |
|
|
|
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; |
|
|
|
|
|
|
|
Opcode opcode = GetOpcode(code); |
|
|
|
Opcode opcode = GetOpcode(offset); |
|
|
|
pc += 4; |
|
|
|
|
|
|
|
// 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(); |
|
|
|
// Execute one more instruction due to the delay slot.
|
|
|
|
return Step(code, true); |
|
|
|
return Step(offset, true); |
|
|
|
} |
|
|
|
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
|
|
|
|
// Note: Executing an exit during a branch delay slot will cause the instruction at the
|
|
|
|
// branch target to be executed before exiting.
|
|
|
|
Step(code, true); |
|
|
|
Step(offset, true); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
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 < code.size() * sizeof(u32)); |
|
|
|
return {code[pc / sizeof(u32)]}; |
|
|
|
ASSERT((pc + offset) < macro_memory.size() * sizeof(u32)); |
|
|
|
return {macro_memory[offset + pc / sizeof(u32)]}; |
|
|
|
} |
|
|
|
|
|
|
|
u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const { |
|
|
|
|