Merge pull request #17 from hch12907/master

VU bugfixes
This commit is contained in:
Marco Satti 2018-09-23 22:42:33 +08:00 committed by GitHub
commit 5286c1ad7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 8 deletions

View file

@ -38,6 +38,10 @@ void CVuInterpreter::ABS(VuUnit_Base* unit, const VuInstruction inst)
reg_dest.write_float(field, result);
}
else
{
unit->mac.clear_vector_field(field);
}
}
}
@ -1470,6 +1474,10 @@ void CVuInterpreter::MAX(VuUnit_Base* unit, const VuInstruction inst)
const f32 b = reg_source_2.read_float(field);
reg_dest.write_float(field, std::max(a, b));
}
else
{
unit->mac.clear_vector_field(field);
}
}
}
@ -1489,6 +1497,10 @@ void CVuInterpreter::MAXi(VuUnit_Base* unit, const VuInstruction inst)
const f32 b = reg_source_2.read_float();
reg_dest.write_float(field, std::max(a, b));
}
else
{
unit->mac.clear_vector_field(field);
}
}
}
@ -1510,6 +1522,10 @@ void CVuInterpreter::MAXbc(VuUnit_Base* unit, const VuInstruction inst, const in
const f32 b = reg_source_2.read_float(bc);
reg_dest.write_float(field, std::max(a, b));
}
else
{
unit->mac.clear_vector_field(field);
}
}
}
@ -1553,6 +1569,10 @@ void CVuInterpreter::MINI(VuUnit_Base* unit, const VuInstruction inst)
const f32 b = reg_source_2.read_float(field);
reg_dest.write_float(field, std::min(a, b));
}
else
{
unit->mac.clear_vector_field(field);
}
}
}
@ -1572,6 +1592,10 @@ void CVuInterpreter::MINIi(VuUnit_Base* unit, const VuInstruction inst)
const f32 b = reg_source_2.read_float();
reg_dest.write_float(field, std::min(a, b));
}
else
{
unit->mac.clear_vector_field(field);
}
}
}
@ -1593,6 +1617,10 @@ void CVuInterpreter::MINIbc(VuUnit_Base* unit, const VuInstruction inst, const i
const f32 b = reg_source_2.read_float(bc);
reg_dest.write_float(field, std::min(a, b));
}
else
{
unit->mac.clear_vector_field(field);
}
}
}

View file

@ -3,6 +3,7 @@
#include "Controller/Ee/Vpu/Vu/Interpreter/CVuInterpreter.hpp"
#include "Core.hpp"
#include "Resources/Ee/Vpu/Vu/VuUnits.hpp"
#include "Utilities/Utilities.hpp"
// All instructions here are related to registers.
// Particularly load/store
@ -59,7 +60,8 @@ void CVuInterpreter::LQ(VuUnit_Base* unit, const VuInstruction inst)
SizedHwordRegister& reg_source = unit->vi[inst.is()];
SizedQwordRegister& reg_dest = unit->vf[inst.ft()];
const uword address = (inst.imm11() + reg_source.read_uhword()) * NUMBER_BYTES_IN_QWORD;
const shword offset = extend_integer<uhword, shword, 11>(inst.imm11());
const uword address = (offset + reg_source.read_uhword()) * NUMBER_BYTES_IN_QWORD;
const uqword source = unit->bus.read_uqword(BusContext::Vu, address);
for (auto field : VuVectorField::VECTOR_FIELDS)
@ -119,7 +121,8 @@ void CVuInterpreter::SQ(VuUnit_Base* unit, const VuInstruction inst)
SizedQwordRegister& reg_source_1 = unit->vf[inst.fs()];
SizedHwordRegister& reg_source_2 = unit->vi[inst.it()];
const uword address = (inst.imm11() + reg_source_2.read_uhword()) * NUMBER_BYTES_IN_QWORD;
const shword offset = extend_integer<uhword, shword, 11>(inst.imm11());
const uword address = (offset + reg_source_2.read_uhword()) * NUMBER_BYTES_IN_QWORD;
for (auto field : VuVectorField::VECTOR_FIELDS)
{
@ -174,9 +177,18 @@ void CVuInterpreter::ILW(VuUnit_Base* unit, const VuInstruction inst)
SizedHwordRegister& reg_source = unit->vi[inst.is()];
SizedHwordRegister& reg_dest = unit->vi[inst.it()];
const uword address = (inst.imm15() + reg_source.read_uhword()) * NUMBER_BYTES_IN_QWORD;
const uword source = unit->bus.read_uqword(BusContext::Vu, address).uw[inst.dest()];
reg_dest.write_uhword(static_cast<uhword>(source));
const shword offset = extend_integer<uhword, shword, 11>(inst.imm11());
const uword address = (offset + reg_source.read_uhword()) * NUMBER_BYTES_IN_QWORD;
// Note: the operation is undefined when multiple fields are specified
for (auto field : VuVectorField::VECTOR_FIELDS)
{
if (inst.test_dest_field(field))
{
const uword source = unit->bus.read_uqword(BusContext::Vu, address).uw[field];
reg_dest.write_uhword(static_cast<uhword>(source));
}
}
}
void CVuInterpreter::ISW(VuUnit_Base* unit, const VuInstruction inst)
@ -184,7 +196,8 @@ void CVuInterpreter::ISW(VuUnit_Base* unit, const VuInstruction inst)
SizedHwordRegister& reg_source_1 = unit->vi[inst.it()];
SizedHwordRegister& reg_source_2 = unit->vi[inst.is()];
const uword address = (inst.imm15() + reg_source_2.read_uhword()) * NUMBER_BYTES_IN_QWORD;
const shword offset = extend_integer<uhword, shword, 11>(inst.imm11());
const uword address = (offset + reg_source_2.read_uhword()) * NUMBER_BYTES_IN_QWORD;
for (auto field : VuVectorField::VECTOR_FIELDS)
{
@ -200,9 +213,16 @@ void CVuInterpreter::ILWR(VuUnit_Base* unit, const VuInstruction inst)
SizedHwordRegister& reg_source = unit->vi[inst.is()];
SizedHwordRegister& reg_dest = unit->vi[inst.it()];
// Note: the operation is undefined when multiple fields are specified
const uword address = reg_source.read_uhword() * NUMBER_BYTES_IN_QWORD;
const uword source = unit->bus.read_uqword(BusContext::Vu, address).uw[inst.dest()];
reg_dest.write_uhword(static_cast<uhword>(source));
for (auto field : VuVectorField::VECTOR_FIELDS)
{
if (inst.test_dest_field(field))
{
const uword source = unit->bus.read_uqword(BusContext::Vu, address).uw[field];
reg_dest.write_uhword(static_cast<uhword>(source));
}
}
}
void CVuInterpreter::ISWR(VuUnit_Base* unit, const VuInstruction inst)