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);
|
result = Compile_sll(cbi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case InstructionFunct::sllv:
|
||||||
|
result = Compile_sllv(cbi);
|
||||||
|
break;
|
||||||
|
|
||||||
case InstructionFunct::srl:
|
case InstructionFunct::srl:
|
||||||
result = Compile_srl(cbi);
|
result = Compile_srl(cbi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case InstructionFunct::srlv:
|
||||||
|
result = Compile_srlv(cbi);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
result = Compile_Fallback(cbi);
|
result = Compile_Fallback(cbi);
|
||||||
break;
|
break;
|
||||||
|
@ -589,6 +597,22 @@ bool CodeGenerator::Compile_sll(const CodeBlockInstruction& cbi)
|
||||||
return true;
|
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)
|
bool CodeGenerator::Compile_srl(const CodeBlockInstruction& cbi)
|
||||||
{
|
{
|
||||||
InstructionPrologue(cbi, 1);
|
InstructionPrologue(cbi, 1);
|
||||||
|
@ -602,6 +626,22 @@ bool CodeGenerator::Compile_srl(const CodeBlockInstruction& cbi)
|
||||||
return true;
|
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)
|
bool CodeGenerator::Compile_addiu(const CodeBlockInstruction& cbi)
|
||||||
{
|
{
|
||||||
InstructionPrologue(cbi, 1);
|
InstructionPrologue(cbi, 1);
|
||||||
|
|
|
@ -158,7 +158,9 @@ private:
|
||||||
bool Compile_lui(const CodeBlockInstruction& cbi);
|
bool Compile_lui(const CodeBlockInstruction& cbi);
|
||||||
bool Compile_ori(const CodeBlockInstruction& cbi);
|
bool Compile_ori(const CodeBlockInstruction& cbi);
|
||||||
bool Compile_sll(const CodeBlockInstruction& cbi);
|
bool Compile_sll(const CodeBlockInstruction& cbi);
|
||||||
|
bool Compile_sllv(const CodeBlockInstruction& cbi);
|
||||||
bool Compile_srl(const CodeBlockInstruction& cbi);
|
bool Compile_srl(const CodeBlockInstruction& cbi);
|
||||||
|
bool Compile_srlv(const CodeBlockInstruction& cbi);
|
||||||
bool Compile_addiu(const CodeBlockInstruction& cbi);
|
bool Compile_addiu(const CodeBlockInstruction& cbi);
|
||||||
|
|
||||||
Core* m_cpu;
|
Core* m_cpu;
|
||||||
|
|
|
@ -37,6 +37,9 @@ constexpr RegSize HostPointerSize = RegSize_64;
|
||||||
// A reasonable "maximum" number of bytes per instruction.
|
// A reasonable "maximum" number of bytes per instruction.
|
||||||
constexpr u32 MAX_HOST_BYTES_PER_INSTRUCTION = 128;
|
constexpr u32 MAX_HOST_BYTES_PER_INSTRUCTION = 128;
|
||||||
|
|
||||||
|
// Are shifts implicitly masked to 0..31?
|
||||||
|
constexpr bool SHIFTS_ARE_IMPLICITLY_MASKED = true;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
using HostReg = void;
|
using HostReg = void;
|
||||||
using CodeEmitter = void;
|
using CodeEmitter = void;
|
||||||
|
@ -46,6 +49,7 @@ enum : u32
|
||||||
};
|
};
|
||||||
constexpr HostReg HostReg_Invalid = static_cast<HostReg>(HostReg_Count);
|
constexpr HostReg HostReg_Invalid = static_cast<HostReg>(HostReg_Count);
|
||||||
constexpr OperandSize HostPointerSize = OperandSize_64;
|
constexpr OperandSize HostPointerSize = OperandSize_64;
|
||||||
|
constexpr bool SHIFTS_ARE_IMPLICITLY_MASKED = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace Recompiler
|
} // namespace Recompiler
|
||||||
|
|
Loading…
Reference in a new issue