mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-18 14:25:38 +00:00
CPU/Recompiler: Implement sra/srav instructions
This commit is contained in:
parent
4f436461ff
commit
09de3819eb
|
@ -90,11 +90,13 @@ bool CodeGenerator::CompileInstruction(const CodeBlockInstruction& cbi)
|
||||||
{
|
{
|
||||||
case InstructionFunct::sll:
|
case InstructionFunct::sll:
|
||||||
case InstructionFunct::srl:
|
case InstructionFunct::srl:
|
||||||
|
case InstructionFunct::sra:
|
||||||
result = Compile_ShiftImmediate(cbi);
|
result = Compile_ShiftImmediate(cbi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InstructionFunct::sllv:
|
case InstructionFunct::sllv:
|
||||||
case InstructionFunct::srlv:
|
case InstructionFunct::srlv:
|
||||||
|
case InstructionFunct::srav:
|
||||||
result = Compile_ShiftVariable(cbi);
|
result = Compile_ShiftVariable(cbi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -268,7 +270,7 @@ Value CodeGenerator::ShlValues(const Value& lhs, const Value& rhs)
|
||||||
if (lhs.IsConstant() && rhs.IsConstant())
|
if (lhs.IsConstant() && rhs.IsConstant())
|
||||||
{
|
{
|
||||||
// compile-time
|
// compile-time
|
||||||
u64 new_cv = lhs.constant_value << rhs.constant_value;
|
u64 new_cv = lhs.constant_value << (rhs.constant_value & 0x1F);
|
||||||
switch (lhs.size)
|
switch (lhs.size)
|
||||||
{
|
{
|
||||||
case RegSize_8:
|
case RegSize_8:
|
||||||
|
@ -301,7 +303,7 @@ Value CodeGenerator::ShrValues(const Value& lhs, const Value& rhs)
|
||||||
if (lhs.IsConstant() && rhs.IsConstant())
|
if (lhs.IsConstant() && rhs.IsConstant())
|
||||||
{
|
{
|
||||||
// compile-time
|
// compile-time
|
||||||
u64 new_cv = lhs.constant_value >> rhs.constant_value;
|
u64 new_cv = lhs.constant_value >> (rhs.constant_value & 0x1F);
|
||||||
switch (lhs.size)
|
switch (lhs.size)
|
||||||
{
|
{
|
||||||
case RegSize_8:
|
case RegSize_8:
|
||||||
|
@ -328,6 +330,42 @@ Value CodeGenerator::ShrValues(const Value& lhs, const Value& rhs)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value CodeGenerator::SarValues(const Value& lhs, const Value& rhs)
|
||||||
|
{
|
||||||
|
DebugAssert(lhs.size == rhs.size);
|
||||||
|
if (lhs.IsConstant() && rhs.IsConstant())
|
||||||
|
{
|
||||||
|
// compile-time
|
||||||
|
switch (lhs.size)
|
||||||
|
{
|
||||||
|
case RegSize_8:
|
||||||
|
return Value::FromConstantU8(
|
||||||
|
static_cast<u8>(static_cast<s8>(Truncate8(lhs.constant_value)) >> (rhs.constant_value & 0x1F)));
|
||||||
|
|
||||||
|
case RegSize_16:
|
||||||
|
return Value::FromConstantU16(
|
||||||
|
static_cast<u16>(static_cast<s16>(Truncate16(lhs.constant_value)) >> (rhs.constant_value & 0x1F)));
|
||||||
|
|
||||||
|
case RegSize_32:
|
||||||
|
return Value::FromConstantU32(
|
||||||
|
static_cast<u32>(static_cast<s32>(Truncate32(lhs.constant_value)) >> (rhs.constant_value & 0x1F)));
|
||||||
|
|
||||||
|
case RegSize_64:
|
||||||
|
return Value::FromConstantU64(
|
||||||
|
static_cast<u64>(static_cast<s64>(lhs.constant_value) >> (rhs.constant_value & 0x3F)));
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value res = m_register_cache.AllocateScratch(lhs.size);
|
||||||
|
EmitCopyValue(res.host_reg, lhs);
|
||||||
|
if (!rhs.HasConstantValue(0))
|
||||||
|
EmitSar(res.host_reg, res.size, rhs);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
Value CodeGenerator::OrValues(const Value& lhs, const Value& rhs)
|
Value CodeGenerator::OrValues(const Value& lhs, const Value& rhs)
|
||||||
{
|
{
|
||||||
DebugAssert(lhs.size == rhs.size);
|
DebugAssert(lhs.size == rhs.size);
|
||||||
|
@ -688,6 +726,10 @@ bool CodeGenerator::Compile_ShiftImmediate(const CodeBlockInstruction& cbi)
|
||||||
result = ShrValues(rt, shamt);
|
result = ShrValues(rt, shamt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case InstructionFunct::sra:
|
||||||
|
result = SarValues(rt, shamt);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UnreachableCode();
|
UnreachableCode();
|
||||||
break;
|
break;
|
||||||
|
@ -720,6 +762,10 @@ bool CodeGenerator::Compile_ShiftVariable(const CodeBlockInstruction& cbi)
|
||||||
result = ShrValues(rt, shamt);
|
result = ShrValues(rt, shamt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case InstructionFunct::srav:
|
||||||
|
result = SarValues(rt, shamt);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UnreachableCode();
|
UnreachableCode();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -127,6 +127,7 @@ public:
|
||||||
Value MulValues(const Value& lhs, const Value& rhs);
|
Value MulValues(const Value& lhs, const Value& rhs);
|
||||||
Value ShlValues(const Value& lhs, const Value& rhs);
|
Value ShlValues(const Value& lhs, const Value& rhs);
|
||||||
Value ShrValues(const Value& lhs, const Value& rhs);
|
Value ShrValues(const Value& lhs, const Value& rhs);
|
||||||
|
Value SarValues(const Value& lhs, const Value& rhs);
|
||||||
Value OrValues(const Value& lhs, const Value& rhs);
|
Value OrValues(const Value& lhs, const Value& rhs);
|
||||||
Value AndValues(const Value& lhs, const Value& rhs);
|
Value AndValues(const Value& lhs, const Value& rhs);
|
||||||
Value XorValues(const Value& lhs, const Value& rhs);
|
Value XorValues(const Value& lhs, const Value& rhs);
|
||||||
|
|
Loading…
Reference in a new issue