mirror of
https://github.com/hch12907/orbum.git
synced 2024-05-20 05:00:48 -04:00
VU: Instruction decoder rework
This commit is contained in:
parent
c9713cb365
commit
620110cfa6
|
@ -35,17 +35,37 @@ int CVuInterpreter::time_step(const int ticks_available)
|
|||
const uword upper_raw_inst = (raw_inst >> 32) & 0xFFFFFFFF;
|
||||
const VuInstruction upper_inst = VuInstruction(upper_raw_inst);
|
||||
const MipsInstructionInfo upper_info = upper_inst.lower_lookup();
|
||||
const VuInstructionDecoder upper_decoder = VuInstructionDecoder(upper_inst, upper_info);
|
||||
|
||||
const uword lower_raw_inst = raw_inst & 0xFFFFFFFF;
|
||||
const VuInstruction lower_inst = VuInstruction(lower_raw_inst);
|
||||
const MipsInstructionInfo lower_info = lower_inst.lower_lookup();
|
||||
const VuInstructionDecoder lower_decoder = VuInstructionDecoder(lower_inst, lower_info);
|
||||
|
||||
const VuInstructionDecoder decoder = VuInstructionDecoder(lower_inst, upper_inst);
|
||||
|
||||
// Flush the pipelines
|
||||
unit->efu.consume_cycle(1);
|
||||
unit->fdiv.consume_cycle(1);
|
||||
unit->ialu.consume_cycle(1);
|
||||
unit->lsu.consume_cycle(1);
|
||||
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
fmac.consume_cycle(1);
|
||||
}
|
||||
|
||||
// If the units have finished execution, replace the original regs with new ones
|
||||
if (!unit->efu.is_running())
|
||||
unit->p = unit->efu.new_p;
|
||||
if (!unit->fdiv.is_running())
|
||||
unit->q = unit->fdiv.new_q;
|
||||
|
||||
bool data_hazard_occured = check_data_hazard(unit, upper_decoder, lower_decoder);
|
||||
|
||||
// If I (bit 63) is set, execute UpperInst and LOI (using LowerInst as an immediate)
|
||||
if ((raw_inst >> 63) & 1)
|
||||
{
|
||||
execute_upper_instruction(unit, upper_inst, upper_info, decoder);
|
||||
execute_upper_instruction(unit, upper_decoder, data_hazard_occured);
|
||||
this->LOI(unit, lower_inst);
|
||||
|
||||
// Advance PC and onto the next unit
|
||||
|
@ -109,39 +129,39 @@ int CVuInterpreter::time_step(const int ticks_available)
|
|||
try
|
||||
{
|
||||
// Try obtaining the destination (will throw if the instruction writes to non-VF/VI regs)
|
||||
const uword upper_dest = *decoder.upper_dest();
|
||||
const uword lower_dest = *decoder.lower_dest();
|
||||
const uword upper_dest = *upper_decoder.try_get_dest();
|
||||
const uword lower_dest = *lower_decoder.try_get_dest();
|
||||
|
||||
// Check if the lower instruction write to VI or VF
|
||||
// If it writes to VF, check if it writes to the same reg
|
||||
if (decoder.decode_lower().field != VuDecodedInst::Int)
|
||||
if (!lower_decoder.is_integer_instruction())
|
||||
{
|
||||
if (upper_dest == lower_dest)
|
||||
{
|
||||
SizedQwordRegister original_vf = unit->vf[upper_dest];
|
||||
execute_lower_instruction(unit, upper_inst, upper_info, decoder);
|
||||
execute_lower_instruction(unit, lower_decoder, data_hazard_occured);
|
||||
|
||||
// The result produced by lower instruction is discarded
|
||||
unit->vf[upper_dest] = original_vf;
|
||||
execute_upper_instruction(unit, lower_inst, lower_info, decoder);
|
||||
execute_upper_instruction(unit, upper_decoder, data_hazard_occured);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise just run it usually
|
||||
execute_upper_instruction(unit, upper_inst, upper_info, decoder);
|
||||
execute_lower_instruction(unit, lower_inst, lower_info, decoder);
|
||||
// Otherwise just run it as usual
|
||||
execute_upper_instruction(unit, upper_decoder, data_hazard_occured);
|
||||
execute_lower_instruction(unit, lower_decoder, data_hazard_occured);
|
||||
}
|
||||
}
|
||||
catch (std::exception)
|
||||
{
|
||||
// If one of them write to special regs (P, Q, etc), execute like usual
|
||||
execute_upper_instruction(unit, upper_inst, upper_info, decoder);
|
||||
execute_lower_instruction(unit, lower_inst, lower_info, decoder);
|
||||
execute_upper_instruction(unit, upper_decoder, data_hazard_occured);
|
||||
execute_lower_instruction(unit, lower_decoder, data_hazard_occured);
|
||||
}
|
||||
|
||||
// Advance the PC
|
||||
if (!check_data_hazard(unit, decoder))
|
||||
if (!check_data_hazard(unit, upper_decoder, lower_decoder))
|
||||
unit->bdelay.advance_pc(unit->pc);
|
||||
}
|
||||
|
||||
|
@ -149,21 +169,13 @@ int CVuInterpreter::time_step(const int ticks_available)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CVuInterpreter::execute_lower_instruction(VuUnit_Base* unit, const VuInstruction inst, MipsInstructionInfo info, const VuInstructionDecoder& decoder)
|
||||
int CVuInterpreter::execute_lower_instruction(VuUnit_Base* unit, const VuInstructionDecoder& decoder, bool data_hazard)
|
||||
{
|
||||
unit->efu.consume_cycle(1);
|
||||
unit->fdiv.consume_cycle(1);
|
||||
unit->ialu.consume_cycle(1);
|
||||
unit->lsu.consume_cycle(1);
|
||||
|
||||
// If the units have finished execution, replace the original regs with new ones
|
||||
if (!unit->efu.is_running())
|
||||
unit->p = unit->efu.new_p;
|
||||
if (!unit->fdiv.is_running())
|
||||
unit->q = unit->fdiv.new_q;
|
||||
const VuInstruction& inst = decoder.instruction;
|
||||
const MipsInstructionInfo& info = decoder.instruction_info;
|
||||
|
||||
// If there's a data hazard, stall
|
||||
if (check_data_hazard(unit, decoder))
|
||||
if (data_hazard)
|
||||
return 1;
|
||||
|
||||
switch (info.pipeline)
|
||||
|
@ -208,7 +220,7 @@ int CVuInterpreter::execute_lower_instruction(VuUnit_Base* unit, const VuInstruc
|
|||
if (!unit->ialu.is_running())
|
||||
{
|
||||
// Try to get the destination
|
||||
int dest = decoder.lower_dest().value_or(0);
|
||||
int dest = decoder.try_get_dest().value_or(0);
|
||||
|
||||
// See FDIV
|
||||
unit->ialu = IaluPipeline(info.cpi - 2, dest);
|
||||
|
@ -225,7 +237,7 @@ int CVuInterpreter::execute_lower_instruction(VuUnit_Base* unit, const VuInstruc
|
|||
{
|
||||
if (!unit->lsu.is_running())
|
||||
{
|
||||
int dest = decoder.lower_dest().value_or(0);
|
||||
int dest = decoder.try_get_dest().value_or(0);
|
||||
|
||||
unit->lsu = LsuPipeline(info.cpi - 2, dest);
|
||||
}
|
||||
|
@ -242,22 +254,20 @@ int CVuInterpreter::execute_lower_instruction(VuUnit_Base* unit, const VuInstruc
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CVuInterpreter::execute_upper_instruction(VuUnit_Base* unit, VuInstruction inst, MipsInstructionInfo info, const VuInstructionDecoder& decoder)
|
||||
int CVuInterpreter::execute_upper_instruction(VuUnit_Base* unit, const VuInstructionDecoder& decoder, bool data_hazard)
|
||||
{
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
fmac.consume_cycle(1);
|
||||
}
|
||||
const VuInstruction& inst = decoder.instruction;
|
||||
const MipsInstructionInfo& info = decoder.instruction_info;
|
||||
|
||||
// If there's a data hazard, stall
|
||||
if (check_data_hazard(unit, decoder))
|
||||
// Stall if there's a data hazard
|
||||
if (data_hazard)
|
||||
return 1;
|
||||
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
if (!fmac.is_running())
|
||||
{
|
||||
fmac = FmacPipeline(info.cpi - 2, decoder.upper_dest().value_or(0), inst.dest());
|
||||
fmac = FmacPipeline(info.cpi - 2, decoder.try_get_dest().value_or(0), inst.dest());
|
||||
(this->*VU_INSTRUCTION_TABLE[info.impl_index])(unit, inst);
|
||||
break;
|
||||
}
|
||||
|
@ -266,122 +276,75 @@ int CVuInterpreter::execute_upper_instruction(VuUnit_Base* unit, VuInstruction i
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool CVuInterpreter::check_data_hazard(VuUnit_Base* unit, const VuInstructionDecoder& decoder) const
|
||||
bool CVuInterpreter::check_data_hazard(VuUnit_Base* unit, const VuInstructionDecoder& ud, const VuInstructionDecoder& ld) const
|
||||
{
|
||||
// Obtain the registers to be read by the instruction
|
||||
// If the instruction does not specify the field(s), use 0 as placeholder,
|
||||
// as VF0/VI0 is hardwired to 0 (and the manual did this too)
|
||||
const int upper_read[3] = {
|
||||
decoder.upper_src(0).value_or(0),
|
||||
decoder.upper_src(1).value_or(0),
|
||||
decoder.upper_src(2).value_or(-1) // this one's special because only MADD/MSUB uses this
|
||||
ud.try_get_src(0).value_or(0),
|
||||
ud.try_get_src(1).value_or(0),
|
||||
ud.try_get_src(2).value_or(-1) // this one's special because only MADD/MSUB uses this
|
||||
};
|
||||
|
||||
const int lower_read[2] = {
|
||||
decoder.lower_src(0).value_or(-1),
|
||||
decoder.lower_src(1).value_or(-1)};
|
||||
ld.try_get_src(0).value_or(0),
|
||||
ld.try_get_src(1).value_or(0)
|
||||
};
|
||||
|
||||
// If the instruction is WAITP, return true if EFU is running
|
||||
if (((decoder.get_lower_inst().value) & 0x7FF) == 0x7BF)
|
||||
if (((ld.instruction.value) & 0x7FF) == 0x7BF)
|
||||
{
|
||||
if (unit->efu.is_running())
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the instruction is WAITQ, return true if FDIV is running
|
||||
if (((decoder.get_lower_inst().value) & 0x7FF) == 0x3BF)
|
||||
if (((ld.instruction.value) & 0x7FF) == 0x3BF)
|
||||
{
|
||||
if (unit->fdiv.is_running())
|
||||
return true;
|
||||
}
|
||||
|
||||
// Upper Instructions data hazard check
|
||||
// Special case: if the instruction is MADD/MSUB/OPMSUB, then BC relates to 3rd field instead of 2nd
|
||||
// note: (1 << (3 - inst.bc())) converts BC to DEST
|
||||
{
|
||||
VuInstruction inst = decoder.get_upper_inst();
|
||||
const VuInstruction inst = ud.instruction;
|
||||
|
||||
if (upper_read[2] == -1)
|
||||
{
|
||||
if (decoder.decode_upper().field == VuDecodedInst::Bc)
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
if (fmac.is_using_register(upper_read[0], inst.dest()))
|
||||
return true;
|
||||
if (fmac.is_using_register(upper_read[1], 1U << (3 - inst.bc())))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (decoder.decode_upper().field == VuDecodedInst::Dest)
|
||||
{
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
if (fmac.is_using_register(upper_read[0], inst.dest()))
|
||||
return true;
|
||||
if (fmac.is_using_register(upper_read[1], inst.dest()))
|
||||
return true;
|
||||
}
|
||||
if (fmac.is_using_register(upper_read[0], *ud.try_get_src_field(0)))
|
||||
return true;
|
||||
if (fmac.is_using_register(upper_read[1], *ud.try_get_src_field(1)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (decoder.decode_upper().field == VuDecodedInst::Bc)
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
if (fmac.is_using_register(upper_read[0], inst.dest()))
|
||||
return true;
|
||||
if (fmac.is_using_register(upper_read[1], inst.dest()))
|
||||
return true;
|
||||
if (fmac.is_using_register(upper_read[2], 1U << (3 - inst.bc())))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (decoder.decode_upper().field == VuDecodedInst::Dest)
|
||||
{
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
if (fmac.is_using_register(upper_read[0], inst.dest()))
|
||||
return true;
|
||||
if (fmac.is_using_register(upper_read[1], inst.dest()))
|
||||
return true;
|
||||
if (fmac.is_using_register(upper_read[2], inst.dest()))
|
||||
return true;
|
||||
}
|
||||
if (fmac.is_using_register(upper_read[0], *ud.try_get_src_field(0)))
|
||||
return true;
|
||||
if (fmac.is_using_register(upper_read[1], *ud.try_get_src_field(1)))
|
||||
return true;
|
||||
if (fmac.is_using_register(upper_read[2], *ud.try_get_src_field(2)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lower Instructions data hazard check
|
||||
{
|
||||
VuInstruction inst = decoder.get_upper_inst();
|
||||
const VuInstruction inst = ld.instruction;
|
||||
|
||||
if (decoder.decode_lower().field == VuDecodedInst::FsfFtf)
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
if (fmac.is_using_register(lower_read[0], inst.fsf()))
|
||||
return true;
|
||||
if (fmac.is_using_register(lower_read[1], inst.ftf()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (decoder.decode_lower().field == VuDecodedInst::Dest)
|
||||
{
|
||||
for (FmacPipeline& fmac : unit->fmac)
|
||||
{
|
||||
if (fmac.is_using_register(lower_read[0], inst.dest()))
|
||||
return true;
|
||||
if (fmac.is_using_register(lower_read[1], inst.dest()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (decoder.decode_lower().field == VuDecodedInst::Int)
|
||||
{
|
||||
if (unit->lsu.is_using_register(lower_read[0]))
|
||||
if (fmac.is_using_register(lower_read[0], *ld.try_get_src_field(0)))
|
||||
return true;
|
||||
}
|
||||
if (fmac.is_using_register(lower_read[1], *ld.try_get_src_field(1)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -383,8 +383,8 @@ public:
|
|||
&CVuInterpreter::XITOP};
|
||||
|
||||
private:
|
||||
bool check_data_hazard(VuUnit_Base* unit, const VuInstructionDecoder& decoder) const;
|
||||
bool check_data_hazard(VuUnit_Base* unit, const VuInstructionDecoder& upper_decoder, const VuInstructionDecoder& lower_decoder) const;
|
||||
|
||||
int execute_upper_instruction(VuUnit_Base* unit, VuInstruction inst, MipsInstructionInfo info, const VuInstructionDecoder& decoder);
|
||||
int execute_lower_instruction(VuUnit_Base* unit, VuInstruction inst, MipsInstructionInfo info, const VuInstructionDecoder& decoder);
|
||||
int execute_upper_instruction(VuUnit_Base* unit, const VuInstructionDecoder& decoder, bool handle_data_hazard);
|
||||
int execute_lower_instruction(VuUnit_Base* unit, const VuInstructionDecoder& decoder, bool handle_data_hazard);
|
||||
};
|
||||
|
|
|
@ -1,271 +1,349 @@
|
|||
#include "Resources/Ee/Vpu/Vu/VuInstructionDecoder.hpp"
|
||||
|
||||
/// Each VuInstruction specifies 3 registers (one for the destination reg
|
||||
/// and others for source) and uses 4 at most (eg MADD/MSUB). In this table index 0
|
||||
/// stores the destination reg, while index 1, 2 & 3 stores the source reg(s).
|
||||
/// If the destination bitfield is set to nullopt, then it is assumed that the
|
||||
/// instruction uses special registers such as P, Q or ACC.
|
||||
VuDecodedInst VU_DECODE_TABLE[Constants::EE::VPU::VU::NUMBER_VU_INSTRUCTIONS]{
|
||||
// DESTINATION SOURCE (1) SOURCE (2) SOURCE (3) FIELDS
|
||||
VuInstructionType VU_INSTRUCTION_DECODE_TABLE[Constants::EE::VPU::VU::NUMBER_VU_INSTRUCTIONS] {
|
||||
// Upper Instructions
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // ABS
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Dest), // ADD
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuSpecialRegs::I, std::nullopt, VuDecodedInst::Dest), // ADDi
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuSpecialRegs::Q, std::nullopt, VuDecodedInst::Dest), // ADDq
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // ADDbc_0
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // ADDbc_1
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // ADDbc_2
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // ADDbc_3
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Dest), // ADDA
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::I, std::nullopt, VuDecodedInst::Dest), // ADDAi
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::Q, std::nullopt, VuDecodedInst::Dest), // ADDAq
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // ADDAbc_0
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // ADDAbc_1
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // ADDAbc_2
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // ADDAbc_3
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Dest), // SUB
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuSpecialRegs::I, std::nullopt, VuDecodedInst::Dest), // SUBi
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuSpecialRegs::Q, std::nullopt, VuDecodedInst::Dest), // SUBq
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // SUBbc_0
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // SUBbc_1
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // SUBbc_2
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // SUBbc_3
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Dest), // SUBA
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::I, std::nullopt, VuDecodedInst::Dest), // SUBAi
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::Q, std::nullopt, VuDecodedInst::Dest), // SUBAq
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // SUBAbc_0
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // SUBAbc_1
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // SUBAbc_2
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // SUBAbc_3
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Dest), // MUL
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuSpecialRegs::I, std::nullopt, VuDecodedInst::Dest), // MULi
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuSpecialRegs::Q, std::nullopt, VuDecodedInst::Dest), // MULq
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MULbc_0
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MULbc_1
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MULbc_2
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MULbc_3
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Dest), // MULA
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::I, std::nullopt, VuDecodedInst::Dest), // MULAi
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::Q, std::nullopt, VuDecodedInst::Dest), // MULAq
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MULAbc_0
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MULAbc_1
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MULAbc_2
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MULAbc_3
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Dest), // MADD
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::I, VuDecodedInst::Dest), // MADDi
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::Q, VuDecodedInst::Dest), // MADDq
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MADDbc_0
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MADDbc_1
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MADDbc_2
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MADDbc_3
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Dest), // MADDA
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::I, VuDecodedInst::Dest), // MADDAi
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::Q, VuDecodedInst::Dest), // MADDAq
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MADDAbc_0
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MADDAbc_1
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MADDAbc_2
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MADDAbc_3
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Dest), // MSUB
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::I, VuDecodedInst::Dest), // MSUBi
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::Q, VuDecodedInst::Dest), // MSUBq
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MSUBbc_0
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MSUBbc_1
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MSUBbc_2
|
||||
VuDecodedInst(VuInstruction::FD, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MSUBbc_3
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Dest), // MSUBA
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::I, VuDecodedInst::Dest), // MSUBAi
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuSpecialRegs::Q, VuDecodedInst::Dest), // MSUBAq
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MSUBAbc_0
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MSUBAbc_1
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MSUBAbc_2
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Bc), // MSUBAbc_3
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Dest), // MAX
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuSpecialRegs::I, std::nullopt, VuDecodedInst::Dest), // MAXi
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MAXbc_0
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MAXbc_1
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MAXbc_2
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MAXbc_3
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Dest), // MINI
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuSpecialRegs::I, std::nullopt, VuDecodedInst::Dest), // MINIi
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MINIbc_0
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MINIbc_1
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MINIbc_2
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Bc), // MINIbc_3
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Dest), // OPMULA
|
||||
VuDecodedInst(VuSpecialRegs::ACC, VuSpecialRegs::ACC, VuInstruction::FS, VuInstruction::FT, VuDecodedInst::Dest), // OPMSUB
|
||||
VuDecodedInst(std::nullopt, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Dest), // NOP
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // FTOI0
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // FTOI4
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // FTOI12
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // FTOI15
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // ITOF0
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // ITOF4
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // ITOF12
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // ITOF15
|
||||
VuDecodedInst(VuSpecialRegs::CLIP, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Dest), // CLIP
|
||||
|
||||
// Lower Instructions
|
||||
VuDecodedInst(VuSpecialRegs::Q, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::FsfFtf), // DIV
|
||||
VuDecodedInst(VuSpecialRegs::Q, VuInstruction::FT, std::nullopt, std::nullopt, VuDecodedInst::FsfFtf), // SQRT
|
||||
VuDecodedInst(VuSpecialRegs::Q, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::FsfFtf), // RSQRT
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Int), // IADD
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // IADDI
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // IADDIU
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Int), // IAND
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Int), // IOR
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, VuInstruction::FT, std::nullopt, VuDecodedInst::Int), // ISUB
|
||||
VuDecodedInst(VuInstruction::FD, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // ISUBI
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // MOVE
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // MFIR
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::FsfFtf), // MTIR
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // MR32
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // LQ
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // LQD
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // LQI
|
||||
VuDecodedInst(VuInstruction::FS, VuInstruction::FT, std::nullopt, std::nullopt, VuDecodedInst::Dest), // SQ
|
||||
VuDecodedInst(VuInstruction::FS, VuInstruction::FT, std::nullopt, std::nullopt, VuDecodedInst::Dest), // SQD
|
||||
VuDecodedInst(VuInstruction::FS, VuInstruction::FT, std::nullopt, std::nullopt, VuDecodedInst::Dest), // SQI
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // ILW
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // ISW
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // ILWR
|
||||
VuDecodedInst(VuInstruction::FT, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // ISWR
|
||||
VuDecodedInst(VuSpecialRegs::R, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::FsfFtf), // RINIT
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::R, std::nullopt, std::nullopt, VuDecodedInst::Dest), // RGET
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::R, std::nullopt, std::nullopt, VuDecodedInst::Dest), // RNEXT
|
||||
VuDecodedInst(VuSpecialRegs::R, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::FsfFtf), // RXOR
|
||||
VuDecodedInst(std::nullopt, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Dest), // WAITQ
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::SF, std::nullopt, std::nullopt, VuDecodedInst::Int), // FSAND
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::SF, std::nullopt, std::nullopt, VuDecodedInst::Int), // FSEQ
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::SF, std::nullopt, std::nullopt, VuDecodedInst::Int), // FSOR
|
||||
VuDecodedInst(VuSpecialRegs::SF, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Int), // FSSET
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::MAC, VuInstruction::FS, std::nullopt, VuDecodedInst::Int), // FMAND
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::MAC, VuInstruction::FS, std::nullopt, VuDecodedInst::Int), // FMEQ
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::MAC, VuInstruction::FS, std::nullopt, VuDecodedInst::Int), // FMOR
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::CLIP, std::nullopt, std::nullopt, VuDecodedInst::Int), // FCAND
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::CLIP, std::nullopt, std::nullopt, VuDecodedInst::Int), // FCEQ
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::CLIP, std::nullopt, std::nullopt, VuDecodedInst::Int), // FCOR
|
||||
VuDecodedInst(VuSpecialRegs::CLIP, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Int), // FCSET
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::CLIP, std::nullopt, std::nullopt, VuDecodedInst::Int), // FCGET
|
||||
VuDecodedInst(VuSpecialRegs::PC, VuInstruction::FT, VuInstruction::FS, std::nullopt, VuDecodedInst::Int), // IBEQ
|
||||
VuDecodedInst(VuSpecialRegs::PC, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // IBGEZ
|
||||
VuDecodedInst(VuSpecialRegs::PC, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // IBGTZ
|
||||
VuDecodedInst(VuSpecialRegs::PC, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // IBLEZ
|
||||
VuDecodedInst(VuSpecialRegs::PC, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // IBLTZ
|
||||
VuDecodedInst(VuSpecialRegs::PC, VuInstruction::FT, VuInstruction::FS, std::nullopt, VuDecodedInst::Int), // IBNE
|
||||
VuDecodedInst(VuSpecialRegs::PC, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Int), // B
|
||||
VuDecodedInst(VuInstruction::FT, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Int), // BAL
|
||||
VuDecodedInst(VuSpecialRegs::PC, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Int), // J
|
||||
VuDecodedInst(VuInstruction::FT, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Int), // JALR
|
||||
VuDecodedInst(VuInstruction::FT, VuSpecialRegs::P, std::nullopt, std::nullopt, VuDecodedInst::Dest), // MFP
|
||||
VuDecodedInst(std::nullopt, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Dest), // WAITP
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // ESADD
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // ERSADD
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // ELENG
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // ERLENG
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // EATANxy
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // EATANxz
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Dest), // ESUM
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::FsfFtf), // ERCPR
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::FsfFtf), // ESQRT
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::FsfFtf), // ERSQRT
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::FsfFtf), // ESIN
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::FsfFtf), // EATAN
|
||||
VuDecodedInst(VuSpecialRegs::P, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::FsfFtf), // EEXP
|
||||
VuDecodedInst(std::nullopt, VuInstruction::FS, std::nullopt, std::nullopt, VuDecodedInst::Int), // XGKICK
|
||||
VuDecodedInst(VuInstruction::FT, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Int), // XTOP
|
||||
VuDecodedInst(VuInstruction::FT, std::nullopt, std::nullopt, std::nullopt, VuDecodedInst::Int), // XITOP
|
||||
VuInstructionType::UpperType3, // ABS
|
||||
VuInstructionType::UpperType1, // ADD
|
||||
VuInstructionType::UpperType1, // ADDi
|
||||
VuInstructionType::UpperType1, // ADDq
|
||||
VuInstructionType::UpperType0, // ADDbc_0
|
||||
VuInstructionType::UpperType0, // ADDbc_1
|
||||
VuInstructionType::UpperType0, // ADDbc_2
|
||||
VuInstructionType::UpperType0, // ADDbc_3
|
||||
VuInstructionType::UpperType3_ACC, // ADDA
|
||||
VuInstructionType::UpperType3_ACC, // ADDAi
|
||||
VuInstructionType::UpperType3_ACC, // ADDAq
|
||||
VuInstructionType::UpperType2_ACC, // ADDAbc_0
|
||||
VuInstructionType::UpperType2_ACC, // ADDAbc_1
|
||||
VuInstructionType::UpperType2_ACC, // ADDAbc_2
|
||||
VuInstructionType::UpperType2_ACC, // ADDAbc_3
|
||||
VuInstructionType::UpperType1, // SUB
|
||||
VuInstructionType::UpperType1, // SUBi
|
||||
VuInstructionType::UpperType1, // SUBq
|
||||
VuInstructionType::UpperType0, // SUBbc_0
|
||||
VuInstructionType::UpperType0, // SUBbc_1
|
||||
VuInstructionType::UpperType0, // SUBbc_2
|
||||
VuInstructionType::UpperType0, // SUBbc_3
|
||||
VuInstructionType::UpperType3_ACC, // SUBA
|
||||
VuInstructionType::UpperType3_ACC, // SUBAi
|
||||
VuInstructionType::UpperType3_ACC, // SUBAq
|
||||
VuInstructionType::UpperType2_ACC, // SUBAbc_0
|
||||
VuInstructionType::UpperType2_ACC, // SUBAbc_1
|
||||
VuInstructionType::UpperType2_ACC, // SUBAbc_2
|
||||
VuInstructionType::UpperType2_ACC, // SUBAbc_3
|
||||
VuInstructionType::UpperType1, // MUL
|
||||
VuInstructionType::UpperType1, // MULi
|
||||
VuInstructionType::UpperType1, // MULq
|
||||
VuInstructionType::UpperType0, // MULbc_0
|
||||
VuInstructionType::UpperType0, // MULbc_1
|
||||
VuInstructionType::UpperType0, // MULbc_2
|
||||
VuInstructionType::UpperType0, // MULbc_3
|
||||
VuInstructionType::UpperType3_ACC, // MULA
|
||||
VuInstructionType::UpperType3_ACC, // MULAi
|
||||
VuInstructionType::UpperType3_ACC, // MULAq
|
||||
VuInstructionType::UpperType2_ACC, // MULAbc_0
|
||||
VuInstructionType::UpperType2_ACC, // MULAbc_1
|
||||
VuInstructionType::UpperType2_ACC, // MULAbc_2
|
||||
VuInstructionType::UpperType2_ACC, // MULAbc_3
|
||||
VuInstructionType::UpperType1, // MADD
|
||||
VuInstructionType::UpperType1, // MADDi
|
||||
VuInstructionType::UpperType1, // MADDq
|
||||
VuInstructionType::UpperType0, // MADDbc_0
|
||||
VuInstructionType::UpperType0, // MADDbc_1
|
||||
VuInstructionType::UpperType0, // MADDbc_2
|
||||
VuInstructionType::UpperType0, // MADDbc_3
|
||||
VuInstructionType::UpperType3_ACC, // MADDA
|
||||
VuInstructionType::UpperType3_ACC, // MADDAi
|
||||
VuInstructionType::UpperType3_ACC, // MADDAq
|
||||
VuInstructionType::UpperType2_ACC, // MADDAbc_0
|
||||
VuInstructionType::UpperType2_ACC, // MADDAbc_1
|
||||
VuInstructionType::UpperType2_ACC, // MADDAbc_2
|
||||
VuInstructionType::UpperType2_ACC, // MADDAbc_3
|
||||
VuInstructionType::UpperType1, // MSUB
|
||||
VuInstructionType::UpperType1, // MSUBi
|
||||
VuInstructionType::UpperType1, // MSUBq
|
||||
VuInstructionType::UpperType0, // MSUBbc_0
|
||||
VuInstructionType::UpperType0, // MSUBbc_1
|
||||
VuInstructionType::UpperType0, // MSUBbc_2
|
||||
VuInstructionType::UpperType0, // MSUBbc_3
|
||||
VuInstructionType::UpperType3_ACC, // MSUBA
|
||||
VuInstructionType::UpperType3_ACC, // MSUBAi
|
||||
VuInstructionType::UpperType3_ACC, // MSUBAq
|
||||
VuInstructionType::UpperType2_ACC, // MSUBAbc_0
|
||||
VuInstructionType::UpperType2_ACC, // MSUBAbc_1
|
||||
VuInstructionType::UpperType2_ACC, // MSUBAbc_2
|
||||
VuInstructionType::UpperType2_ACC, // MSUBAbc_3
|
||||
VuInstructionType::UpperType1, // MAX
|
||||
VuInstructionType::UpperType1, // MAXi
|
||||
VuInstructionType::UpperType0, // MAXbc_0
|
||||
VuInstructionType::UpperType0, // MAXbc_1
|
||||
VuInstructionType::UpperType0, // MAXbc_2
|
||||
VuInstructionType::UpperType0, // MAXbc_3
|
||||
VuInstructionType::UpperType1, // MINI
|
||||
VuInstructionType::UpperType1, // MINIi
|
||||
VuInstructionType::UpperType0, // MINIbc_0
|
||||
VuInstructionType::UpperType0, // MINIbc_1
|
||||
VuInstructionType::UpperType0, // MINIbc_2
|
||||
VuInstructionType::UpperType0, // MINIbc_3
|
||||
VuInstructionType::UpperType3_ACC, // OPMULA
|
||||
VuInstructionType::UpperType3_ACC, // OPMSUB
|
||||
VuInstructionType::UpperType3, // NOP
|
||||
VuInstructionType::UpperType3, // FTOI0
|
||||
VuInstructionType::UpperType3, // FTOI4
|
||||
VuInstructionType::UpperType3, // FTOI12
|
||||
VuInstructionType::UpperType3, // FTOI15
|
||||
VuInstructionType::UpperType3, // ITOF0
|
||||
VuInstructionType::UpperType3, // ITOF4
|
||||
VuInstructionType::UpperType3, // ITOF12
|
||||
VuInstructionType::UpperType3, // ITOF15
|
||||
VuInstructionType::UpperType3, // CLIP
|
||||
|
||||
// Lower Instructions
|
||||
VuInstructionType::LowerType4, // DIV
|
||||
VuInstructionType::LowerType4, // SQRT
|
||||
VuInstructionType::LowerType4, // RSQRT
|
||||
VuInstructionType::LowerType1_I, // IADD
|
||||
VuInstructionType::LowerType5, // IADDI
|
||||
VuInstructionType::LowerType8, // IADDIU
|
||||
VuInstructionType::LowerType1_I, // IAND
|
||||
VuInstructionType::LowerType1_I, // IOR
|
||||
VuInstructionType::LowerType1_I, // ISUB
|
||||
VuInstructionType::LowerType8, // ISUBI
|
||||
VuInstructionType::LowerType3, // MOVE
|
||||
VuInstructionType::LowerType3_FT_IS, // MFIR
|
||||
VuInstructionType::LowerType4_IT_FS, // MTIR
|
||||
VuInstructionType::LowerType3, // MR32
|
||||
VuInstructionType::LowerType7_FT_IS, // LQ
|
||||
VuInstructionType::LowerType3_FT_IS, // LQD
|
||||
VuInstructionType::LowerType3_FT_IS, // LQI
|
||||
VuInstructionType::LowerType7, // SQ
|
||||
VuInstructionType::LowerType3_IT_FS, // SQD
|
||||
VuInstructionType::LowerType3_IT_FS, // SQI
|
||||
VuInstructionType::LowerType7_I, // ILW
|
||||
VuInstructionType::LowerType7_I, // ISW
|
||||
VuInstructionType::LowerType3_I, // ILWR
|
||||
VuInstructionType::LowerType3_I, // ISWR
|
||||
VuInstructionType::LowerType4, // RINIT
|
||||
VuInstructionType::LowerType3, // RGET
|
||||
VuInstructionType::LowerType3, // RNEXT
|
||||
VuInstructionType::LowerType4, // RXOR
|
||||
VuInstructionType::LowerType3, // WAITQ
|
||||
VuInstructionType::LowerType8, // FSAND
|
||||
VuInstructionType::LowerType8, // FSEQ
|
||||
VuInstructionType::LowerType8, // FSOR
|
||||
VuInstructionType::LowerType8, // FSSET
|
||||
VuInstructionType::LowerType8, // FMAND
|
||||
VuInstructionType::LowerType8, // FMEQ
|
||||
VuInstructionType::LowerType8, // FMOR
|
||||
VuInstructionType::LowerType9, // FCAND
|
||||
VuInstructionType::LowerType9, // FCEQ
|
||||
VuInstructionType::LowerType9, // FCOR
|
||||
VuInstructionType::LowerType9, // FCSET
|
||||
VuInstructionType::LowerType8, // FCGET
|
||||
VuInstructionType::LowerType7_I, // IBEQ
|
||||
VuInstructionType::LowerType7_I, // IBGEZ
|
||||
VuInstructionType::LowerType7_I, // IBGTZ
|
||||
VuInstructionType::LowerType7_I, // IBLEZ
|
||||
VuInstructionType::LowerType7_I, // IBLTZ
|
||||
VuInstructionType::LowerType7_I, // IBNE
|
||||
VuInstructionType::LowerType7_I, // B
|
||||
VuInstructionType::LowerType7_I, // BAL
|
||||
VuInstructionType::LowerType7_I, // JR
|
||||
VuInstructionType::LowerType7_I, // JALR
|
||||
VuInstructionType::LowerType3, // MFP
|
||||
VuInstructionType::LowerType3, // WAITP
|
||||
VuInstructionType::LowerType3, // ESADD
|
||||
VuInstructionType::LowerType3, // ERSADD
|
||||
VuInstructionType::LowerType3, // ELENG
|
||||
VuInstructionType::LowerType3, // ERLENG
|
||||
VuInstructionType::LowerType3, // EATANxy
|
||||
VuInstructionType::LowerType3, // EATANxz
|
||||
VuInstructionType::LowerType3, // ESUM
|
||||
VuInstructionType::LowerType4, // ERCPR
|
||||
VuInstructionType::LowerType4, // ESQRT
|
||||
VuInstructionType::LowerType4, // ERSQRT
|
||||
VuInstructionType::LowerType4, // ESIN
|
||||
VuInstructionType::LowerType4, // EATAN
|
||||
VuInstructionType::LowerType4, // EEXP
|
||||
VuInstructionType::LowerType3, // XGKICK
|
||||
VuInstructionType::LowerType3_I, // XTOP
|
||||
VuInstructionType::LowerType3_I // XITOP
|
||||
};
|
||||
|
||||
VuInstructionDecoder::VuInstructionDecoder(VuInstruction lower, VuInstruction upper) :
|
||||
lower_inst(lower),
|
||||
upper_inst(upper),
|
||||
decoded_inst_lower(VU_DECODE_TABLE[lower.lower_lookup().impl_index]),
|
||||
decoded_inst_upper(VU_DECODE_TABLE[lower.upper_lookup().impl_index])
|
||||
VuInstructionType VuInstructionDecoder::decode_instruction() const
|
||||
{
|
||||
return VU_INSTRUCTION_DECODE_TABLE[instruction_info.impl_index];
|
||||
}
|
||||
|
||||
const VuDecodedInst& VuInstructionDecoder::decode_lower() const
|
||||
std::optional<int> VuInstructionDecoder::try_get_dest() const
|
||||
{
|
||||
return decoded_inst_lower;
|
||||
}
|
||||
VuInstructionType decoded = decode_instruction();
|
||||
|
||||
const VuDecodedInst& VuInstructionDecoder::decode_upper() const
|
||||
{
|
||||
return decoded_inst_upper;
|
||||
}
|
||||
|
||||
const VuInstruction& VuInstructionDecoder::get_upper_inst() const
|
||||
{
|
||||
return upper_inst;
|
||||
}
|
||||
|
||||
const VuInstruction& VuInstructionDecoder::get_lower_inst() const
|
||||
{
|
||||
return lower_inst;
|
||||
}
|
||||
|
||||
std::optional<int> VuInstructionDecoder::upper_dest() const
|
||||
{
|
||||
if (decoded_inst_upper.dest_reg.has_value())
|
||||
switch (decoded)
|
||||
{
|
||||
VuDecodeInfo value = decoded_inst_upper.dest_reg.value();
|
||||
if (Bitfield* ptr = std::get_if<Bitfield>(&value))
|
||||
{
|
||||
return ptr->extract_from(upper_inst.value);
|
||||
}
|
||||
}
|
||||
case VuInstructionType::UpperType0:
|
||||
case VuInstructionType::UpperType1:
|
||||
case VuInstructionType::LowerType1:
|
||||
return instruction.fd();
|
||||
|
||||
case VuInstructionType::UpperType2:
|
||||
case VuInstructionType::UpperType3:
|
||||
case VuInstructionType::LowerType3:
|
||||
case VuInstructionType::LowerType7_FT_IS:
|
||||
return instruction.ft();
|
||||
|
||||
return std::nullopt;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<int> VuInstructionDecoder::upper_src(int index) const
|
||||
std::optional<int> VuInstructionDecoder::try_get_dest_field() const
|
||||
{
|
||||
const std::optional<VuDecodeInfo>* src_regs[3] = {
|
||||
&decoded_inst_upper.source_reg_1,
|
||||
&decoded_inst_upper.source_reg_2,
|
||||
&decoded_inst_upper.source_reg_3};
|
||||
VuInstructionType decoded = decode_instruction();
|
||||
|
||||
if (src_regs[index]->has_value())
|
||||
switch (decoded)
|
||||
{
|
||||
VuDecodeInfo value = src_regs[index]->value();
|
||||
if (Bitfield* ptr = std::get_if<Bitfield>(&value))
|
||||
{
|
||||
return ptr->extract_from(upper_inst.value);
|
||||
}
|
||||
}
|
||||
case VuInstructionType::UpperType0:
|
||||
case VuInstructionType::UpperType1:
|
||||
case VuInstructionType::UpperType2:
|
||||
case VuInstructionType::UpperType3:
|
||||
case VuInstructionType::LowerType1:
|
||||
case VuInstructionType::LowerType3:
|
||||
case VuInstructionType::LowerType7_FT_IS:
|
||||
return instruction.dest();
|
||||
|
||||
return std::nullopt;
|
||||
case VuInstructionType::LowerType4:
|
||||
return 1 << (3 - instruction.ftf());
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<int> VuInstructionDecoder::lower_dest() const
|
||||
std::optional<int> VuInstructionDecoder::try_get_src(int idx) const
|
||||
{
|
||||
if (decoded_inst_lower.dest_reg.has_value())
|
||||
{
|
||||
VuDecodeInfo value = decoded_inst_lower.dest_reg.value();
|
||||
if (Bitfield* ptr = std::get_if<Bitfield>(&value))
|
||||
{
|
||||
return ptr->extract_from(lower_inst.value);
|
||||
}
|
||||
}
|
||||
VuInstructionType decoded = decode_instruction();
|
||||
|
||||
return std::nullopt;
|
||||
switch (idx)
|
||||
{
|
||||
case 0: switch (decoded)
|
||||
{
|
||||
case VuInstructionType::UpperType0:
|
||||
case VuInstructionType::UpperType1:
|
||||
case VuInstructionType::UpperType2:
|
||||
case VuInstructionType::UpperType3:
|
||||
case VuInstructionType::UpperType1_ACC:
|
||||
case VuInstructionType::UpperType2_ACC:
|
||||
case VuInstructionType::UpperType3_ACC:
|
||||
case VuInstructionType::LowerType1:
|
||||
case VuInstructionType::LowerType3:
|
||||
case VuInstructionType::LowerType3_IT_FS:
|
||||
case VuInstructionType::LowerType4:
|
||||
case VuInstructionType::LowerType4_IT_FS:
|
||||
case VuInstructionType::LowerType7:
|
||||
case VuInstructionType::LowerType8:
|
||||
return instruction.fs();
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
case 1: switch (decoded)
|
||||
{
|
||||
case VuInstructionType::UpperType0:
|
||||
case VuInstructionType::UpperType1:
|
||||
case VuInstructionType::UpperType1_ACC:
|
||||
case VuInstructionType::UpperType2:
|
||||
case VuInstructionType::UpperType2_ACC:
|
||||
case VuInstructionType::UpperType3:
|
||||
case VuInstructionType::UpperType3_ACC:
|
||||
case VuInstructionType::LowerType1:
|
||||
case VuInstructionType::LowerType4:
|
||||
return instruction.ft();
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<int> VuInstructionDecoder::lower_src(int index) const
|
||||
std::optional<int> VuInstructionDecoder::try_get_src_field(int idx) const
|
||||
{
|
||||
const std::optional<VuDecodeInfo>* src_regs[3] = {
|
||||
&decoded_inst_lower.source_reg_1,
|
||||
&decoded_inst_lower.source_reg_2,
|
||||
&decoded_inst_lower.source_reg_3};
|
||||
VuInstructionType decoded = decode_instruction();
|
||||
|
||||
if (src_regs[index]->has_value())
|
||||
switch (idx)
|
||||
{
|
||||
VuDecodeInfo value = src_regs[index]->value();
|
||||
if (auto ptr = std::get_if<Bitfield>(&value))
|
||||
case 0: switch (decoded)
|
||||
{
|
||||
return ptr->extract_from(lower_inst.value);
|
||||
}
|
||||
}
|
||||
case VuInstructionType::UpperType0:
|
||||
case VuInstructionType::UpperType1:
|
||||
case VuInstructionType::UpperType2:
|
||||
case VuInstructionType::UpperType3:
|
||||
case VuInstructionType::UpperType1_ACC:
|
||||
case VuInstructionType::UpperType2_ACC:
|
||||
case VuInstructionType::UpperType3_ACC:
|
||||
case VuInstructionType::LowerType1:
|
||||
case VuInstructionType::LowerType3:
|
||||
case VuInstructionType::LowerType3_IT_FS:
|
||||
case VuInstructionType::LowerType7:
|
||||
case VuInstructionType::LowerType8:
|
||||
return instruction.dest();
|
||||
|
||||
return std::nullopt;
|
||||
case VuInstructionType::LowerType4:
|
||||
case VuInstructionType::LowerType4_IT_FS:
|
||||
return 1 << (3 - instruction.fsf());
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
case 1: switch (decoded)
|
||||
{
|
||||
case VuInstructionType::UpperType0:
|
||||
case VuInstructionType::UpperType2:
|
||||
case VuInstructionType::UpperType2_ACC:
|
||||
return 1 << (3 - instruction.bc());
|
||||
|
||||
case VuInstructionType::UpperType1:
|
||||
case VuInstructionType::UpperType1_ACC:
|
||||
case VuInstructionType::UpperType3:
|
||||
case VuInstructionType::UpperType3_ACC:
|
||||
case VuInstructionType::LowerType1:
|
||||
return instruction.dest();
|
||||
|
||||
case VuInstructionType::LowerType4:
|
||||
return 1 << (3 - instruction.ftf());
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool VuInstructionDecoder::is_integer_instruction() const
|
||||
{
|
||||
VuInstructionType decoded = decode_instruction();
|
||||
|
||||
switch (decoded)
|
||||
{
|
||||
case VuInstructionType::LowerType1:
|
||||
case VuInstructionType::LowerType3_I:
|
||||
case VuInstructionType::LowerType3_IT_FS:
|
||||
case VuInstructionType::LowerType4_IT_FS:
|
||||
case VuInstructionType::LowerType5:
|
||||
case VuInstructionType::LowerType7:
|
||||
case VuInstructionType::LowerType7_I:
|
||||
case VuInstructionType::LowerType8:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,86 +6,75 @@
|
|||
#include "Common/Types/Bitfield.hpp"
|
||||
#include "Resources/Ee/Vpu/Vu/VuInstruction.hpp"
|
||||
|
||||
enum class VuSpecialRegs
|
||||
/// Used to store the type of the instruction. The type determines the fields in
|
||||
/// which the instruction is going to have. This is required for VU data hazards
|
||||
/// checking.
|
||||
/// Note: Some instructions use the register fields differently, although the
|
||||
/// formats are considered the same.
|
||||
/// Note: OPCODE and OPCODE+BC are both 6 bits, OPCODE+0b1111+[*] is 11 bits.
|
||||
enum class VuInstructionType
|
||||
{
|
||||
ACC,
|
||||
CLIP,
|
||||
I,
|
||||
P,
|
||||
PC, // program counter
|
||||
Q,
|
||||
R,
|
||||
SF, // sticky flag
|
||||
MAC // mac flag
|
||||
};
|
||||
|
||||
typedef std::variant<Bitfield, VuSpecialRegs> VuDecodeInfo;
|
||||
|
||||
struct VuDecodedInst
|
||||
{
|
||||
// Used for storing the field specifier (dest, fsf/ftf, bc, etc..)
|
||||
// Note: Integer GPRs do not have a field.
|
||||
enum FieldSpecifier
|
||||
{
|
||||
FsfFtf = 0,
|
||||
Dest = 1,
|
||||
Bc = 2,
|
||||
Int = 3,
|
||||
};
|
||||
|
||||
// Default constructor
|
||||
VuDecodedInst() :
|
||||
dest_reg(std::nullopt),
|
||||
source_reg_1(std::nullopt),
|
||||
source_reg_2(std::nullopt),
|
||||
source_reg_3(std::nullopt),
|
||||
field(FieldSpecifier::Dest)
|
||||
{
|
||||
}
|
||||
|
||||
VuDecodedInst(
|
||||
std::optional<VuDecodeInfo> dest,
|
||||
std::optional<VuDecodeInfo> src_1,
|
||||
std::optional<VuDecodeInfo> src_2,
|
||||
std::optional<VuDecodeInfo> src_3,
|
||||
int dest_field) :
|
||||
dest_reg(dest),
|
||||
source_reg_1(src_1),
|
||||
source_reg_2(src_2),
|
||||
source_reg_3(src_3),
|
||||
field(dest_field)
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<VuDecodeInfo> dest_reg;
|
||||
std::optional<VuDecodeInfo> source_reg_1;
|
||||
std::optional<VuDecodeInfo> source_reg_2;
|
||||
std::optional<VuDecodeInfo> source_reg_3;
|
||||
|
||||
int field;
|
||||
UpperType0, // DEST, FT, FS, FD, OPCODE+BC
|
||||
UpperType1, // DEST, FT, FS, FD, OPCODE
|
||||
UpperType2, // DEST, FT, FS, OPCODE+0b1111+BC
|
||||
UpperType3, // DEST, FT, FS, OPCODE+0b1111+OPCODE
|
||||
UpperType1_ACC, // DEST, FT, FS, FD, OPCODE; uses ACC
|
||||
UpperType2_ACC, // DEST, FT, FS, OPCODE+0b1111+BC; uses ACC
|
||||
UpperType3_ACC, // DEST, FT, FS, OPCODE+0b1111+OPCODE; uses ACC
|
||||
|
||||
LowerType1, // DEST, FT, FS, FD, OPCODE
|
||||
LowerType1_I, // DEST, IT, IS, ID, OPCODE
|
||||
LowerType2, // (unspecified)
|
||||
LowerType3, // DEST, FT, FS, OPCODE+0b1111+OPCODE
|
||||
LowerType3_I, // DEST, IT, IS, OPCODE+0b1111+OPCODE
|
||||
LowerType3_IT_FS, // DEST, IT, FS, OPCODE+0b1111+OPCODE
|
||||
LowerType3_FT_IS, // DEST, FT, IS, OPCODE+0b1111+OPCODE
|
||||
LowerType4, // FTF+FSF, FT, FS, OPCODE+0b1111+OPCODE
|
||||
LowerType4_IT_FS, // FTF+FSF, IT, FS, OPCODE+0b1111+OPCODE
|
||||
LowerType5, // DEST, IT, IS, IMM5, OPCODE
|
||||
LowerType6, // (unspecified)
|
||||
LowerType7, // DEST, IT, FS, IMM11
|
||||
LowerType7_I, // DEST, IT, IS, IMM11
|
||||
LowerType7_FT_IS, // DEST, FT, IS, IMM11
|
||||
LowerType8, // LOWER OP, IMM15, IT, IS, IMM15
|
||||
LowerType9, // LOWER OP, 0b0, IMM24
|
||||
};
|
||||
|
||||
/// The name says all. Contains some helper functions to ease instruction
|
||||
/// decoding.
|
||||
class VuInstructionDecoder
|
||||
{
|
||||
public:
|
||||
VuInstructionDecoder(const VuInstruction lower, const VuInstruction upper);
|
||||
VuInstructionDecoder(const VuInstruction inst, const MipsInstructionInfo info) :
|
||||
instruction(inst),
|
||||
instruction_info(info)
|
||||
{
|
||||
}
|
||||
|
||||
const VuDecodedInst& decode_lower() const;
|
||||
const VuDecodedInst& decode_upper() const;
|
||||
/// Decodes the instruction, returning the type of the instruction.
|
||||
/// See VuInstructionType for more details.
|
||||
VuInstructionType decode_instruction() const;
|
||||
|
||||
const VuInstruction& get_lower_inst() const;
|
||||
const VuInstruction& get_upper_inst() const;
|
||||
/// Obtains the location of destination register, if it is specified by
|
||||
/// the instruction.
|
||||
/// Note: This function returns nullopt for non-VF/non-VI destinations.
|
||||
std::optional<int> try_get_dest() const;
|
||||
|
||||
std::optional<int> lower_dest() const;
|
||||
std::optional<int> upper_dest() const;
|
||||
/// Obtains the field specified by the instruction.
|
||||
std::optional<int> try_get_dest_field() const;
|
||||
|
||||
std::optional<int> lower_src(int index) const;
|
||||
std::optional<int> upper_src(int index) const;
|
||||
/// Obtains the location of source register, if specified by the instruction.
|
||||
/// Some instructions specify 2 or more registers, therefore idx is required
|
||||
/// to specify which source register to obtain.
|
||||
/// Note: This function returns nullopt for special sources.
|
||||
std::optional<int> try_get_src(int idx) const;
|
||||
|
||||
private:
|
||||
VuInstruction lower_inst;
|
||||
VuInstruction upper_inst;
|
||||
/// Obtains the field specified by the instruction.
|
||||
std::optional<int> try_get_src_field(int idx) const;
|
||||
|
||||
VuDecodedInst decoded_inst_lower;
|
||||
VuDecodedInst decoded_inst_upper;
|
||||
/// Returns true if the instruction uses VI registers as its destination.
|
||||
bool is_integer_instruction() const;
|
||||
|
||||
VuInstruction instruction;
|
||||
MipsInstructionInfo instruction_info;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue