VIF: Split UNPACK instruction

This commit is contained in:
hch12907 2018-11-19 22:42:31 +08:00
parent db74f7dd49
commit 7dc76e4c80
6 changed files with 78 additions and 24 deletions

View file

@ -72,9 +72,9 @@ int CVif::time_step(const int ticks_available)
if (!status)
{
unit->code.write_uword(data);
unit->inst = VifcodeInstruction(data);
unit->inst = std::make_unique<VifcodeInstruction>(data);
unit->stat.insert_field(VifUnitRegister_Stat::VPS, 0b10);
unit->packets_left = obtain_required_words(unit->inst);
unit->packets_left = obtain_required_words(*unit->inst);
continue;
}
@ -82,7 +82,7 @@ int CVif::time_step(const int ticks_available)
{
unit->packets_left--;
(this->*INSTRUCTION_TABLE[unit->inst.get_info().impl_index])(unit, unit->inst);
(this->*INSTRUCTION_TABLE[unit->inst->get_info()->impl_index])(unit, *unit->inst);
// If there are no packets left, set the VIF status to idle
if (!unit->packets_left)
@ -90,7 +90,7 @@ int CVif::time_step(const int ticks_available)
unit->stat.insert_field(VifUnitRegister_Stat::VPS, 0b00);
// If the I bit is set, raise an interrupt
if (unit->inst.i())
if ((*unit->inst).i())
{
auto _lock = r.ee.intc.stat.scope_lock();
r.ee.intc.stat.insert_field(EeIntcRegister_Stat::VIF_KEYS[unit->core_id], 1);
@ -115,9 +115,6 @@ int CVif::obtain_required_words(const VifcodeInstruction instruction) const
case SpecialVifcodePacketUsage::Immediate:
return 1 + instruction.imm() * 4;
case SpecialVifcodePacketUsage::Unpack:
return 10; // Fixme: This is COMPLETELY wrong
default:
return instruction.get_info()->cpi;
}

View file

@ -49,7 +49,6 @@ public:
void MPG(VifUnit_Base* unit, const VifcodeInstruction inst);
void DIRECT(VifUnit_Base* unit, const VifcodeInstruction inst);
void DIRECTHL(VifUnit_Base* unit, const VifcodeInstruction inst);
void UNPACK(VifUnit_Base* unit, const VifcodeInstruction inst);
void UNPACK_S_32(VifUnit_Base* unit, const VifcodeInstruction inst);
void UNPACK_S_16(VifUnit_Base* unit, const VifcodeInstruction inst);
void UNPACK_S_8(VifUnit_Base* unit, const VifcodeInstruction inst);
@ -89,7 +88,19 @@ public:
&CVif::MPG,
&CVif::DIRECT,
&CVif::DIRECTHL,
&CVif::UNPACK,
&CVif::UNPACK_S_32,
&CVif::UNPACK_S_16,
&CVif::UNPACK_S_8,
&CVif::UNPACK_V2_32,
&CVif::UNPACK_V2_16,
&CVif::UNPACK_V2_8,
&CVif::UNPACK_V3_32,
&CVif::UNPACK_V3_16,
&CVif::UNPACK_V3_8,
&CVif::UNPACK_V4_32,
&CVif::UNPACK_V4_16,
&CVif::UNPACK_V4_8,
&CVif::UNPACK_V4_5
};
private:

View file

@ -3,10 +3,6 @@
#include "Core.hpp"
#include "Controller/Ee/Vpu/Vif/CVif.hpp"
void CVif::UNPACK(VifUnit_Base* unit, const VifcodeInstruction inst)
{
}
void CVif::UNPACK_S_32(VifUnit_Base* unit, const VifcodeInstruction inst)
{
}

View file

@ -1,9 +1,12 @@
#pragma once
#include <algorithm>
#include <cereal/cereal.hpp>
#include "Common/Types/FifoQueue/DmaFifoQueue.hpp"
#include "Resources/Ee/Vpu/Vif/VifUnitRegisters.hpp"
#include "Resources/Ee/Vpu/Vif/VifcodeInstruction.hpp"
// A base class for a VIF core.
class VifUnit_Base
@ -15,7 +18,7 @@ public:
int core_id;
/// The instruction the VIF is currently processing.
VifcodeInstruction inst;
std::unique_ptr<VifcodeInstruction> inst;
/// The data being processed by the VIF.
uword processing_data;

View file

@ -1,6 +1,6 @@
#include "Resources/Ee/Vpu/Vif/VifcodeInstruction.hpp"
MipsInstructionInfo VIFCODE_INSTRUCTION_TABLE[21] =
MipsInstructionInfo VIFCODE_INSTRUCTION_TABLE[34] =
{
{"NOP", 1, 1},
{"STCYCL", 2, 1},
@ -22,7 +22,20 @@ MipsInstructionInfo VIFCODE_INSTRUCTION_TABLE[21] =
{"MPG", 18, SpecialVifcodePacketUsage::Num},
{"DIRECT", 19, SpecialVifcodePacketUsage::Immediate},
{"DIRECTHL", 20, SpecialVifcodePacketUsage::Immediate},
{"UNPACK", 21, SpecialVifcodePacketUsage::Unpack}};
{"UNPACK_S_32", 21, 4},
{"UNPACK_S_16", 22, 3},
{"UNPACK_S_8", 23, 2},
{"UNPACK_V2_32", 24, 7},
{"UNPACK_V2_16", 25, 4},
{"UNPACK_V2_8", 26, 3},
{"UNPACK_V3_32", 27, 10},
{"UNPACK_V3_16", 28, 6},
{"UNPACK_V3_8", 29, 4},
{"UNPACK_V4_32", 30, 13},
{"UNPACK_V4_16", 31, 7},
{"UNPACK_V4_8", 32, 4},
{"UNPACK_V4_5", 33, 3},
{"UNKNOWN", 0, 1}};
VifcodeInstruction::VifcodeInstruction(const uword value) :
MipsInstruction(value),
@ -66,8 +79,6 @@ MipsInstructionInfo* VifcodeInstruction::lookup() const
return &VIFCODE_INSTRUCTION_TABLE[12];
case 23:
return &VIFCODE_INSTRUCTION_TABLE[13];
default:
throw std::runtime_error("Could not determine instruction");
}
}
case 1:
@ -80,8 +91,6 @@ MipsInstructionInfo* VifcodeInstruction::lookup() const
return &VIFCODE_INSTRUCTION_TABLE[15];
case 17:
return &VIFCODE_INSTRUCTION_TABLE[16];
default:
throw std::runtime_error("Could not determine instruction");
}
}
case 2:
@ -94,13 +103,41 @@ MipsInstructionInfo* VifcodeInstruction::lookup() const
return &VIFCODE_INSTRUCTION_TABLE[18];
case 17:
return &VIFCODE_INSTRUCTION_TABLE[19];
default:
throw std::runtime_error("Could not determine instruction");
}
}
case 3:
return &VIFCODE_INSTRUCTION_TABLE[20];
{
switch (cmdlo() & 0xF) // ignore M bit
{
case 0:
return &VIFCODE_INSTRUCTION_TABLE[20];
case 1:
return &VIFCODE_INSTRUCTION_TABLE[21];
case 2:
return &VIFCODE_INSTRUCTION_TABLE[22];
case 4:
return &VIFCODE_INSTRUCTION_TABLE[23];
case 5:
return &VIFCODE_INSTRUCTION_TABLE[24];
case 6:
return &VIFCODE_INSTRUCTION_TABLE[25];
case 8:
return &VIFCODE_INSTRUCTION_TABLE[26];
case 9:
return &VIFCODE_INSTRUCTION_TABLE[27];
case 10:
return &VIFCODE_INSTRUCTION_TABLE[28];
case 12:
return &VIFCODE_INSTRUCTION_TABLE[29];
case 13:
return &VIFCODE_INSTRUCTION_TABLE[30];
case 14:
return &VIFCODE_INSTRUCTION_TABLE[31];
case 15:
return &VIFCODE_INSTRUCTION_TABLE[32];
}
}
default:
throw std::runtime_error("Could not determine instruction");
return &VIFCODE_INSTRUCTION_TABLE[33];
}
}

View file

@ -71,6 +71,16 @@ struct VifcodeInstruction : public MipsInstruction
return static_cast<ubyte>(M.extract_from(value));
}
ubyte vl() const
{
return static_cast<ubyte>(VL.extract_from(value));
}
ubyte vn() const
{
return static_cast<ubyte>(VN.extract_from(value));
}
/// Performs a lookup if required and returns the instruction details.
const MipsInstructionInfo* get_info() const
{