mirror of
https://github.com/hch12907/orbum.git
synced 2024-05-20 05:00:48 -04:00
Implement VU transfer instructions
finally finished implementing those instructions! also added some basic comments
This commit is contained in:
parent
9ead3c7cba
commit
cabefebec9
|
@ -3,6 +3,14 @@
|
|||
#include "Controller/Ee/Vpu/Vu/Interpreter/CVuInterpreter.hpp"
|
||||
#include "Core.hpp"
|
||||
|
||||
// All instructions here are related to the conversion between floating-points and
|
||||
// fixed-points.
|
||||
//
|
||||
// FTOIx are the instructions for converting a float to a fixed with (32-x) bits
|
||||
// as the integer part, and (x) bits as the fractional part.
|
||||
//
|
||||
// ITOFx are the instructions for converting a fixed to a float.
|
||||
|
||||
void CVuInterpreter::FTOI0(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
SizedQwordRegister& ft = unit->vf[inst.ft()];
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
#include "Controller/Ee/Vpu/Vu/Interpreter/CVuInterpreter.hpp"
|
||||
#include "Core.hpp"
|
||||
|
||||
// All instructions here are related to the EFU (Elementary Functio Unit).
|
||||
// All results produced by those instructions are stored in the P register.
|
||||
|
||||
void CVuInterpreter::ESADD(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// P = VF[fs](x)^2 + VF[fs](y)^2 + VF[fs](z)^2
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include "Controller/Ee/Vpu/Vu/Interpreter/CVuInterpreter.hpp"
|
||||
#include "Core.hpp"
|
||||
|
||||
// All instructions here are related to the flags.
|
||||
// Mostly straightforward.
|
||||
|
||||
void CVuInterpreter::FSAND(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
const uword status = unit->status.read_uword();
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "Resources/Ee/Vpu/Vu/VuUnits.hpp"
|
||||
#include "Utilities/Utilities.hpp"
|
||||
|
||||
// All instructions here are related to float arithmetic.
|
||||
//
|
||||
// Explaination for the comments:
|
||||
// VF[x] - the x-th register of VF
|
||||
// VF[x](f) - the f field of the x-th register of VF, if not specified
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "Resources/Ee/Vpu/Vu/VuUnits.hpp"
|
||||
#include "Utilities/Utilities.hpp"
|
||||
|
||||
// All instructions here are related to integer arithmetics.
|
||||
|
||||
void CVuInterpreter::IADD(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// VI[id] = VI[is] + VI[it]
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
#include "Core.hpp"
|
||||
#include "Resources/RResources.hpp"
|
||||
|
||||
// Miscellaneous VU instructions.
|
||||
// Includes:-
|
||||
// - random (R* instructions)
|
||||
// - branching & jumps
|
||||
// - GIF/VIF interaction
|
||||
// - WAIT* instruciotns (synchronization between different VU execution units)
|
||||
|
||||
void CVuInterpreter::NOP(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
return;
|
||||
|
@ -35,7 +42,7 @@ void CVuInterpreter::RINIT(VuUnit_Base* unit, const VuInstruction inst)
|
|||
SizedQwordRegister& reg_source = unit->vf[inst.fs()];
|
||||
SizedWordRegister& reg_dest = unit->r;
|
||||
|
||||
// Writes a float consisting of 23 bits of R as mantissa and 001111111 as exp+sign.
|
||||
// Writes a float consisting 23 bits of R as mantissa and 001111111 as exp+sign.
|
||||
constexpr uword append = 0b001111111 << 23;
|
||||
const f32 fsf = (reg_source.read_uword(inst.fsf()) & 0x7FFFFF) | append;
|
||||
reg_dest.write_uword(fsf);
|
||||
|
@ -102,7 +109,7 @@ void CVuInterpreter::IBEQ(VuUnit_Base* unit, const VuInstruction inst)
|
|||
|
||||
if (reg_source_1.read_uhword() == reg_source_2.read_uhword())
|
||||
{
|
||||
unit->pc.offset(inst.imm11() * 8);
|
||||
unit->pc.offset(inst.imm11() * NUMBER_BYTES_IN_DWORD);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +119,7 @@ void CVuInterpreter::IBGEZ(VuUnit_Base* unit, const VuInstruction inst)
|
|||
|
||||
if (reg_source_1.read_uhword() >= 0)
|
||||
{
|
||||
unit->pc.offset(inst.imm11() * 8);
|
||||
unit->pc.offset(inst.imm11() * NUMBER_BYTES_IN_DWORD);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,7 +129,7 @@ void CVuInterpreter::IBGTZ(VuUnit_Base* unit, const VuInstruction inst)
|
|||
|
||||
if (reg_source_1.read_uhword() > 0)
|
||||
{
|
||||
unit->pc.offset(inst.imm11() * 8);
|
||||
unit->pc.offset(inst.imm11() * NUMBER_BYTES_IN_DWORD);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +139,7 @@ void CVuInterpreter::IBLEZ(VuUnit_Base* unit, const VuInstruction inst)
|
|||
|
||||
if (reg_source_1.read_uhword() <= 0)
|
||||
{
|
||||
unit->pc.offset(inst.imm11() * 8);
|
||||
unit->pc.offset(inst.imm11() * NUMBER_BYTES_IN_DWORD);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +149,7 @@ void CVuInterpreter::IBLTZ(VuUnit_Base* unit, const VuInstruction inst)
|
|||
|
||||
if (reg_source_1.read_uhword() < 0)
|
||||
{
|
||||
unit->pc.offset(inst.imm11() * 8);
|
||||
unit->pc.offset(inst.imm11() * NUMBER_BYTES_IN_DWORD);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,13 +160,13 @@ void CVuInterpreter::IBNE(VuUnit_Base* unit, const VuInstruction inst)
|
|||
|
||||
if (reg_source_1.read_uhword() != reg_source_2.read_uhword())
|
||||
{
|
||||
unit->pc.offset(inst.imm11() * 8);
|
||||
unit->pc.offset(inst.imm11() * NUMBER_BYTES_IN_DWORD);
|
||||
}
|
||||
}
|
||||
|
||||
void CVuInterpreter::B(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
unit->pc.offset(inst.imm11() * 8);
|
||||
unit->pc.offset(inst.imm11() * NUMBER_BYTES_IN_DWORD);
|
||||
}
|
||||
|
||||
void CVuInterpreter::BAL(VuUnit_Base* unit, const VuInstruction inst)
|
||||
|
@ -168,7 +175,7 @@ void CVuInterpreter::BAL(VuUnit_Base* unit, const VuInstruction inst)
|
|||
|
||||
constexpr uword next_addr_offset = 16;
|
||||
reg_dest.write_uhword(unit->pc.read_uword() + next_addr_offset);
|
||||
unit->pc.offset(inst.imm11() * 8);
|
||||
unit->pc.offset(inst.imm11() * NUMBER_BYTES_IN_DWORD);
|
||||
}
|
||||
|
||||
void CVuInterpreter::JR(VuUnit_Base* unit, const VuInstruction inst)
|
||||
|
|
|
@ -4,185 +4,248 @@
|
|||
#include "Core.hpp"
|
||||
#include "Resources/Ee/Vpu/Vu/VuUnits.hpp"
|
||||
|
||||
// All instructions here are related to registers.
|
||||
// Particularly load/store
|
||||
|
||||
void CVuInterpreter::MOVE(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) MOVE: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("MOVE: Not implemented.");
|
||||
#endif
|
||||
SizedQwordRegister& reg_source = unit->vf[inst.fs()];
|
||||
SizedQwordRegister& reg_dest = unit->vf[inst.ft()];
|
||||
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
reg_dest.write_uword(reg_source.read_uword(field), field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVuInterpreter::MFIR(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) MFIR: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("MFIR: Not implemented.");
|
||||
#endif
|
||||
SizedHwordRegister& reg_source = unit->vi[inst.is()];
|
||||
SizedQwordRegister& reg_dest = unit->vf[inst.ft()];
|
||||
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
reg_dest.write_uword(reg_source.read_uhword(), field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVuInterpreter::MTIR(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) MTIR: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("MTIR: Not implemented.");
|
||||
#endif
|
||||
SizedQwordRegister& reg_source = unit->vf[inst.fs()];
|
||||
SizedHwordRegister& reg_dest = unit->vi[inst.it()];
|
||||
|
||||
reg_dest.write_uhword(reg_source.read_uword(inst.fsf()) & 0xFFFF);
|
||||
}
|
||||
|
||||
void CVuInterpreter::MR32(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) MR32: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("MR32: Not implemented.");
|
||||
#endif
|
||||
SizedQwordRegister& reg_source = unit->vf[inst.fs()];
|
||||
SizedQwordRegister& reg_dest = unit->vf[inst.ft()];
|
||||
|
||||
reg_dest.write_uword(reg_source.read_uword(VuVectorField::W), VuVectorField::X);
|
||||
reg_dest.write_uword(reg_source.read_uword(VuVectorField::X), VuVectorField::Y);
|
||||
reg_dest.write_uword(reg_source.read_uword(VuVectorField::Y), VuVectorField::Z);
|
||||
reg_dest.write_uword(reg_source.read_uword(VuVectorField::Z), VuVectorField::W);
|
||||
}
|
||||
|
||||
void CVuInterpreter::LQ(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) LQ: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("LQ: Not implemented.");
|
||||
#endif
|
||||
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 uqword source = unit->bus.read_uqword(BusContext::Vu, address);
|
||||
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
// Investigate?: Endianness scares me
|
||||
reg_dest.write_float(source.uw[field], field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVuInterpreter::LQD(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) LQD: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("LQD: Not implemented.");
|
||||
#endif
|
||||
SizedHwordRegister& reg_source = unit->vi[inst.is()];
|
||||
SizedQwordRegister& reg_dest = unit->vf[inst.ft()];
|
||||
|
||||
// Pre-decrement VI first
|
||||
reg_source.write_uhword(reg_source.read_uhword() - 1);
|
||||
|
||||
const uword address = reg_source.read_uhword() * NUMBER_BYTES_IN_QWORD;
|
||||
const uqword source = unit->bus.read_uqword(BusContext::Vu, address);
|
||||
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
// Investigate?: Endianness scares me
|
||||
reg_dest.write_float(source.uw[field], field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVuInterpreter::LQI(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) LQI: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("LQI: Not implemented.");
|
||||
#endif
|
||||
SizedHwordRegister& reg_source = unit->vi[inst.is()];
|
||||
SizedQwordRegister& reg_dest = unit->vf[inst.ft()];
|
||||
|
||||
const uword address = reg_source.read_uhword() * NUMBER_BYTES_IN_QWORD;
|
||||
const uqword source = unit->bus.read_uqword(BusContext::Vu, address);
|
||||
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
// Investigate?: Endianness scares me
|
||||
reg_dest.write_float(source.uw[field], field);
|
||||
}
|
||||
}
|
||||
|
||||
// Post-increment the VI
|
||||
reg_source.write_uhword(reg_source.read_uhword() + 1);
|
||||
}
|
||||
|
||||
void CVuInterpreter::SQ(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) SQ: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("SQ: Not implemented.");
|
||||
#endif
|
||||
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;
|
||||
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
unit->bus.write_uword(BusContext::Vu, address + NUMBER_BYTES_IN_WORD * field, reg_source_1.read_uword(field));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVuInterpreter::SQD(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) SQD: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("SQD: Not implemented.");
|
||||
#endif
|
||||
SizedQwordRegister& reg_source_1 = unit->vf[inst.fs()];
|
||||
SizedHwordRegister& reg_source_2 = unit->vi[inst.it()];
|
||||
|
||||
reg_source_2.write_uhword(reg_source_2.read_uhword() - 1);
|
||||
|
||||
const uword address = reg_source_2.read_uhword() * NUMBER_BYTES_IN_QWORD;
|
||||
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
unit->bus.write_uword(BusContext::Vu, address + NUMBER_BYTES_IN_WORD * field, reg_source_1.read_uword(field));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVuInterpreter::SQI(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// MEM(Ft) = Fs
|
||||
auto& reg_source1 = unit->vf[inst.fs()];
|
||||
auto& reg_source2 = unit->vi[inst.ft()]; // Mem Addr.
|
||||
SizedQwordRegister& reg_source_1 = unit->vf[inst.fs()];
|
||||
SizedHwordRegister& reg_source_2 = unit->vi[inst.ft()]; // Mem Addr.
|
||||
|
||||
// Real address obtained by VI * 16 (qword addressing).
|
||||
uword address = reg_source2.read_uhword() * NUMBER_BYTES_IN_QWORD;
|
||||
const uword address = reg_source_2.read_uhword() * NUMBER_BYTES_IN_QWORD;
|
||||
|
||||
// 32-bit write for each dest subfield.
|
||||
if (inst.test_dest_x())
|
||||
unit->bus.write_uword(BusContext::Vu, address, reg_source1.read_uword(0));
|
||||
if (inst.test_dest_y())
|
||||
unit->bus.write_uword(BusContext::Vu, address + 4, reg_source1.read_uword(1));
|
||||
if (inst.test_dest_z())
|
||||
unit->bus.write_uword(BusContext::Vu, address + 8, reg_source1.read_uword(2));
|
||||
if (inst.test_dest_w())
|
||||
unit->bus.write_uword(BusContext::Vu, address + 12, reg_source1.read_uword(3));
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
unit->bus.write_uword(BusContext::Vu, address + NUMBER_BYTES_IN_WORD * field, reg_source_1.read_uword(field));
|
||||
}
|
||||
}
|
||||
|
||||
// Post increment.
|
||||
reg_source2.write_uhword(reg_source2.read_uhword() + 1);
|
||||
reg_source_2.write_uhword(reg_source_2.read_uhword() + 1);
|
||||
}
|
||||
|
||||
void CVuInterpreter::ILW(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) ILW: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("ILW: Not implemented.");
|
||||
#endif
|
||||
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));
|
||||
}
|
||||
|
||||
void CVuInterpreter::ISW(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) ISW: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("ISW: Not implemented.");
|
||||
#endif
|
||||
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;
|
||||
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
unit->bus.write_uword(BusContext::Vu, address + NUMBER_BYTES_IN_WORD * field, reg_source_1.read_uhword());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVuInterpreter::ILWR(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) ILWR: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("ILWR: Not implemented.");
|
||||
#endif
|
||||
SizedHwordRegister& reg_source = unit->vi[inst.is()];
|
||||
SizedHwordRegister& reg_dest = unit->vi[inst.it()];
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void CVuInterpreter::ISWR(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// MEM(Fs) = Ft.
|
||||
auto& reg_source1 = unit->vi[inst.ft()]; // Data.
|
||||
auto& reg_source2 = unit->vi[inst.fs()]; // Mem Addr.
|
||||
SizedHwordRegister& reg_source_1 = unit->vi[inst.it()]; // Data.
|
||||
SizedHwordRegister& reg_source_2 = unit->vi[inst.is()]; // Mem Addr.
|
||||
|
||||
// Real address obtained by VI * 16.
|
||||
uword address = reg_source2.read_uhword() * NUMBER_BYTES_IN_QWORD;
|
||||
const uword address = reg_source_2.read_uhword() * NUMBER_BYTES_IN_QWORD;
|
||||
|
||||
// 32-bit write for each dest subfield. Upper 16-bits of VI[Ft] value is set to 0.
|
||||
if (inst.test_dest_x())
|
||||
unit->bus.write_uword(BusContext::Vu, address, static_cast<uword>(reg_source1.read_uhword()));
|
||||
if (inst.test_dest_y())
|
||||
unit->bus.write_uword(BusContext::Vu, address + 4, static_cast<uword>(reg_source1.read_uhword()));
|
||||
if (inst.test_dest_z())
|
||||
unit->bus.write_uword(BusContext::Vu, address + 8, static_cast<uword>(reg_source1.read_uhword()));
|
||||
if (inst.test_dest_w())
|
||||
unit->bus.write_uword(BusContext::Vu, address + 12, static_cast<uword>(reg_source1.read_uhword()));
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
unit->bus.write_uword(BusContext::Vu, address + NUMBER_BYTES_IN_WORD * field, reg_source_1.read_uhword());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVuInterpreter::LOI(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) LOI: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("LOI: Not implemented.");
|
||||
#endif
|
||||
// Call this instruction when the I bit of the upper instruction is set
|
||||
// And pass the lower instruction in
|
||||
|
||||
unit->i.write_uword(inst.value);
|
||||
|
||||
|
||||
// (In case you are wondering... LOI is a pseudo-instruction, it's
|
||||
// not supposed to be referenced)
|
||||
}
|
||||
|
||||
void CVuInterpreter::MFP(VuUnit_Base* unit, const VuInstruction inst)
|
||||
{
|
||||
// TODO: Implement.
|
||||
#if defined(BUILD_DEBUG)
|
||||
BOOST_LOG(Core::get_logger()) << boost::format("(%s, %d) MFP: Not implemented.") % __FILENAME__ % __LINE__;
|
||||
#else
|
||||
throw std::runtime_error("MFP: Not implemented.");
|
||||
#endif
|
||||
SizedWordRegister& reg_source = unit->p;
|
||||
SizedQwordRegister& reg_dest = unit->vf[inst.ft()];
|
||||
|
||||
for (auto field : VuVectorField::VECTOR_FIELDS)
|
||||
{
|
||||
if (inst.test_dest_field(field))
|
||||
{
|
||||
reg_dest.write_uword(reg_source.read_uword(), field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue