mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 15:45:42 +00:00
CPU/Recompiler: Implement srlv/srrv instructions
This commit is contained in:
parent
82cbb6e1b8
commit
6157aa9d21
|
@ -90,10 +90,18 @@ bool CodeGenerator::CompileInstruction(const CodeBlockInstruction& cbi)
|
|||
result = Compile_sll(cbi);
|
||||
break;
|
||||
|
||||
case InstructionFunct::sllv:
|
||||
result = Compile_sllv(cbi);
|
||||
break;
|
||||
|
||||
case InstructionFunct::srl:
|
||||
result = Compile_srl(cbi);
|
||||
break;
|
||||
|
||||
case InstructionFunct::srlv:
|
||||
result = Compile_srlv(cbi);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = Compile_Fallback(cbi);
|
||||
break;
|
||||
|
@ -589,6 +597,22 @@ bool CodeGenerator::Compile_sll(const CodeBlockInstruction& cbi)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CodeGenerator::Compile_sllv(const CodeBlockInstruction& cbi)
|
||||
{
|
||||
InstructionPrologue(cbi, 1);
|
||||
|
||||
// rd <- rt << rs
|
||||
Value shift_amount = m_register_cache.ReadGuestRegister(cbi.instruction.r.rs);
|
||||
if constexpr (!SHIFTS_ARE_IMPLICITLY_MASKED)
|
||||
EmitAnd(shift_amount.host_reg, Value::FromConstantU32(0x1F));
|
||||
|
||||
m_register_cache.WriteGuestRegister(
|
||||
cbi.instruction.r.rd, ShlValues(m_register_cache.ReadGuestRegister(cbi.instruction.r.rt), shift_amount));
|
||||
|
||||
InstructionEpilogue(cbi);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CodeGenerator::Compile_srl(const CodeBlockInstruction& cbi)
|
||||
{
|
||||
InstructionPrologue(cbi, 1);
|
||||
|
@ -602,6 +626,22 @@ bool CodeGenerator::Compile_srl(const CodeBlockInstruction& cbi)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CodeGenerator::Compile_srlv(const CodeBlockInstruction& cbi)
|
||||
{
|
||||
InstructionPrologue(cbi, 1);
|
||||
|
||||
// rd <- rt << rs
|
||||
Value shift_amount = m_register_cache.ReadGuestRegister(cbi.instruction.r.rs);
|
||||
if constexpr (!SHIFTS_ARE_IMPLICITLY_MASKED)
|
||||
EmitAnd(shift_amount.host_reg, Value::FromConstantU32(0x1F));
|
||||
|
||||
m_register_cache.WriteGuestRegister(
|
||||
cbi.instruction.r.rd, ShrValues(m_register_cache.ReadGuestRegister(cbi.instruction.r.rt), shift_amount));
|
||||
|
||||
InstructionEpilogue(cbi);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CodeGenerator::Compile_addiu(const CodeBlockInstruction& cbi)
|
||||
{
|
||||
InstructionPrologue(cbi, 1);
|
||||
|
|
|
@ -158,7 +158,9 @@ private:
|
|||
bool Compile_lui(const CodeBlockInstruction& cbi);
|
||||
bool Compile_ori(const CodeBlockInstruction& cbi);
|
||||
bool Compile_sll(const CodeBlockInstruction& cbi);
|
||||
bool Compile_sllv(const CodeBlockInstruction& cbi);
|
||||
bool Compile_srl(const CodeBlockInstruction& cbi);
|
||||
bool Compile_srlv(const CodeBlockInstruction& cbi);
|
||||
bool Compile_addiu(const CodeBlockInstruction& cbi);
|
||||
|
||||
Core* m_cpu;
|
||||
|
|
|
@ -37,6 +37,9 @@ constexpr RegSize HostPointerSize = RegSize_64;
|
|||
// A reasonable "maximum" number of bytes per instruction.
|
||||
constexpr u32 MAX_HOST_BYTES_PER_INSTRUCTION = 128;
|
||||
|
||||
// Are shifts implicitly masked to 0..31?
|
||||
constexpr bool SHIFTS_ARE_IMPLICITLY_MASKED = true;
|
||||
|
||||
#else
|
||||
using HostReg = void;
|
||||
using CodeEmitter = void;
|
||||
|
@ -46,6 +49,7 @@ enum : u32
|
|||
};
|
||||
constexpr HostReg HostReg_Invalid = static_cast<HostReg>(HostReg_Count);
|
||||
constexpr OperandSize HostPointerSize = OperandSize_64;
|
||||
constexpr bool SHIFTS_ARE_IMPLICITLY_MASKED = false;
|
||||
#endif
|
||||
|
||||
} // namespace Recompiler
|
||||
|
|
Loading…
Reference in a new issue