mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-23 14:25:37 +00:00
PGXP: Compute PSX values on demand for CPU instructions
Generates shorter code for the recompiler.
This commit is contained in:
parent
54f5c737ce
commit
209827b67c
|
@ -585,7 +585,7 @@ restart_instruction:
|
||||||
{
|
{
|
||||||
const u32 new_value = ReadReg(inst.r.rt) << inst.r.shamt;
|
const u32 new_value = ReadReg(inst.r.rt) << inst.r.shamt;
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SLL(inst.bits, new_value, ReadReg(inst.r.rt));
|
PGXP::CPU_SLL(inst.bits, ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -595,7 +595,7 @@ restart_instruction:
|
||||||
{
|
{
|
||||||
const u32 new_value = ReadReg(inst.r.rt) >> inst.r.shamt;
|
const u32 new_value = ReadReg(inst.r.rt) >> inst.r.shamt;
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SRL(inst.bits, new_value, ReadReg(inst.r.rt));
|
PGXP::CPU_SRL(inst.bits, ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -605,7 +605,7 @@ restart_instruction:
|
||||||
{
|
{
|
||||||
const u32 new_value = static_cast<u32>(static_cast<s32>(ReadReg(inst.r.rt)) >> inst.r.shamt);
|
const u32 new_value = static_cast<u32>(static_cast<s32>(ReadReg(inst.r.rt)) >> inst.r.shamt);
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SRA(inst.bits, new_value, ReadReg(inst.r.rt));
|
PGXP::CPU_SRA(inst.bits, ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -616,7 +616,7 @@ restart_instruction:
|
||||||
const u32 shift_amount = ReadReg(inst.r.rs) & UINT32_C(0x1F);
|
const u32 shift_amount = ReadReg(inst.r.rs) & UINT32_C(0x1F);
|
||||||
const u32 new_value = ReadReg(inst.r.rt) << shift_amount;
|
const u32 new_value = ReadReg(inst.r.rt) << shift_amount;
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SLLV(inst.bits, new_value, ReadReg(inst.r.rt), shift_amount);
|
PGXP::CPU_SLLV(inst.bits, ReadReg(inst.r.rt), shift_amount);
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -627,7 +627,7 @@ restart_instruction:
|
||||||
const u32 shift_amount = ReadReg(inst.r.rs) & UINT32_C(0x1F);
|
const u32 shift_amount = ReadReg(inst.r.rs) & UINT32_C(0x1F);
|
||||||
const u32 new_value = ReadReg(inst.r.rt) >> shift_amount;
|
const u32 new_value = ReadReg(inst.r.rt) >> shift_amount;
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SRLV(inst.bits, new_value, ReadReg(inst.r.rt), shift_amount);
|
PGXP::CPU_SRLV(inst.bits, ReadReg(inst.r.rt), shift_amount);
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -638,7 +638,7 @@ restart_instruction:
|
||||||
const u32 shift_amount = ReadReg(inst.r.rs) & UINT32_C(0x1F);
|
const u32 shift_amount = ReadReg(inst.r.rs) & UINT32_C(0x1F);
|
||||||
const u32 new_value = static_cast<u32>(static_cast<s32>(ReadReg(inst.r.rt)) >> shift_amount);
|
const u32 new_value = static_cast<u32>(static_cast<s32>(ReadReg(inst.r.rt)) >> shift_amount);
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SRAV(inst.bits, new_value, ReadReg(inst.r.rt), shift_amount);
|
PGXP::CPU_SRAV(inst.bits, ReadReg(inst.r.rt), shift_amount);
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -648,7 +648,7 @@ restart_instruction:
|
||||||
{
|
{
|
||||||
const u32 new_value = ReadReg(inst.r.rs) & ReadReg(inst.r.rt);
|
const u32 new_value = ReadReg(inst.r.rs) & ReadReg(inst.r.rt);
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_AND_(inst.bits, new_value, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
PGXP::CPU_AND_(inst.bits, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -658,7 +658,7 @@ restart_instruction:
|
||||||
{
|
{
|
||||||
const u32 new_value = ReadReg(inst.r.rs) | ReadReg(inst.r.rt);
|
const u32 new_value = ReadReg(inst.r.rs) | ReadReg(inst.r.rt);
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_OR_(inst.bits, new_value, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
PGXP::CPU_OR_(inst.bits, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -668,7 +668,7 @@ restart_instruction:
|
||||||
{
|
{
|
||||||
const u32 new_value = ReadReg(inst.r.rs) ^ ReadReg(inst.r.rt);
|
const u32 new_value = ReadReg(inst.r.rs) ^ ReadReg(inst.r.rt);
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_XOR_(inst.bits, new_value, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
PGXP::CPU_XOR_(inst.bits, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -678,7 +678,7 @@ restart_instruction:
|
||||||
{
|
{
|
||||||
const u32 new_value = ~(ReadReg(inst.r.rs) | ReadReg(inst.r.rt));
|
const u32 new_value = ~(ReadReg(inst.r.rs) | ReadReg(inst.r.rt));
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_NOR(inst.bits, new_value, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
PGXP::CPU_NOR(inst.bits, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -696,7 +696,7 @@ restart_instruction:
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (pgxp_mode == PGXPMode::CPU)
|
if constexpr (pgxp_mode == PGXPMode::CPU)
|
||||||
PGXP::CPU_ADD(inst.bits, new_value, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
PGXP::CPU_ADD(inst.bits, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
||||||
else if constexpr (pgxp_mode >= PGXPMode::Memory)
|
else if constexpr (pgxp_mode >= PGXPMode::Memory)
|
||||||
{
|
{
|
||||||
if (add_value == 0)
|
if (add_value == 0)
|
||||||
|
@ -716,7 +716,7 @@ restart_instruction:
|
||||||
const u32 add_value = ReadReg(inst.r.rt);
|
const u32 add_value = ReadReg(inst.r.rt);
|
||||||
const u32 new_value = old_value + add_value;
|
const u32 new_value = old_value + add_value;
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_ADD(inst.bits, new_value, old_value, add_value);
|
PGXP::CPU_ADD(inst.bits, old_value, add_value);
|
||||||
else if constexpr (pgxp_mode >= PGXPMode::Memory)
|
else if constexpr (pgxp_mode >= PGXPMode::Memory)
|
||||||
{
|
{
|
||||||
if (add_value == 0)
|
if (add_value == 0)
|
||||||
|
@ -742,7 +742,7 @@ restart_instruction:
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SUB(inst.bits, new_value, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
PGXP::CPU_SUB(inst.bits, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -752,7 +752,7 @@ restart_instruction:
|
||||||
{
|
{
|
||||||
const u32 new_value = ReadReg(inst.r.rs) - ReadReg(inst.r.rt);
|
const u32 new_value = ReadReg(inst.r.rs) - ReadReg(inst.r.rt);
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SUB(inst.bits, new_value, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
PGXP::CPU_SUB(inst.bits, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, new_value);
|
WriteReg(inst.r.rd, new_value);
|
||||||
}
|
}
|
||||||
|
@ -762,7 +762,7 @@ restart_instruction:
|
||||||
{
|
{
|
||||||
const u32 result = BoolToUInt32(static_cast<s32>(ReadReg(inst.r.rs)) < static_cast<s32>(ReadReg(inst.r.rt)));
|
const u32 result = BoolToUInt32(static_cast<s32>(ReadReg(inst.r.rs)) < static_cast<s32>(ReadReg(inst.r.rt)));
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SLT(inst.bits, result, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
PGXP::CPU_SLT(inst.bits, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, result);
|
WriteReg(inst.r.rd, result);
|
||||||
}
|
}
|
||||||
|
@ -772,7 +772,7 @@ restart_instruction:
|
||||||
{
|
{
|
||||||
const u32 result = BoolToUInt32(ReadReg(inst.r.rs) < ReadReg(inst.r.rt));
|
const u32 result = BoolToUInt32(ReadReg(inst.r.rs) < ReadReg(inst.r.rt));
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SLTU(inst.bits, result, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
PGXP::CPU_SLTU(inst.bits, ReadReg(inst.r.rs), ReadReg(inst.r.rt));
|
||||||
|
|
||||||
WriteReg(inst.r.rd, result);
|
WriteReg(inst.r.rd, result);
|
||||||
}
|
}
|
||||||
|
@ -948,7 +948,7 @@ restart_instruction:
|
||||||
const u32 new_value = ReadReg(inst.i.rs) & inst.i.imm_zext32();
|
const u32 new_value = ReadReg(inst.i.rs) & inst.i.imm_zext32();
|
||||||
|
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_ANDI(inst.bits, new_value, ReadReg(inst.i.rs));
|
PGXP::CPU_ANDI(inst.bits, ReadReg(inst.i.rs));
|
||||||
|
|
||||||
WriteReg(inst.i.rt, new_value);
|
WriteReg(inst.i.rt, new_value);
|
||||||
}
|
}
|
||||||
|
@ -959,7 +959,7 @@ restart_instruction:
|
||||||
const u32 new_value = ReadReg(inst.i.rs) | inst.i.imm_zext32();
|
const u32 new_value = ReadReg(inst.i.rs) | inst.i.imm_zext32();
|
||||||
|
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_ORI(inst.bits, new_value, ReadReg(inst.i.rs));
|
PGXP::CPU_ORI(inst.bits, ReadReg(inst.i.rs));
|
||||||
|
|
||||||
WriteReg(inst.i.rt, new_value);
|
WriteReg(inst.i.rt, new_value);
|
||||||
}
|
}
|
||||||
|
@ -970,7 +970,7 @@ restart_instruction:
|
||||||
const u32 new_value = ReadReg(inst.i.rs) ^ inst.i.imm_zext32();
|
const u32 new_value = ReadReg(inst.i.rs) ^ inst.i.imm_zext32();
|
||||||
|
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_XORI(inst.bits, new_value, ReadReg(inst.i.rs));
|
PGXP::CPU_XORI(inst.bits, ReadReg(inst.i.rs));
|
||||||
|
|
||||||
WriteReg(inst.i.rt, new_value);
|
WriteReg(inst.i.rt, new_value);
|
||||||
}
|
}
|
||||||
|
@ -988,7 +988,7 @@ restart_instruction:
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_ADDI(inst.bits, new_value, ReadReg(inst.i.rs));
|
PGXP::CPU_ADDI(inst.bits, ReadReg(inst.i.rs));
|
||||||
else if constexpr (pgxp_mode >= PGXPMode::Memory)
|
else if constexpr (pgxp_mode >= PGXPMode::Memory)
|
||||||
{
|
{
|
||||||
if (add_value == 0)
|
if (add_value == 0)
|
||||||
|
@ -1009,7 +1009,7 @@ restart_instruction:
|
||||||
const u32 new_value = old_value + add_value;
|
const u32 new_value = old_value + add_value;
|
||||||
|
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_ADDI(inst.bits, new_value, ReadReg(inst.i.rs));
|
PGXP::CPU_ADDI(inst.bits, ReadReg(inst.i.rs));
|
||||||
else if constexpr (pgxp_mode >= PGXPMode::Memory)
|
else if constexpr (pgxp_mode >= PGXPMode::Memory)
|
||||||
{
|
{
|
||||||
if (add_value == 0)
|
if (add_value == 0)
|
||||||
|
@ -1028,7 +1028,7 @@ restart_instruction:
|
||||||
const u32 result = BoolToUInt32(static_cast<s32>(ReadReg(inst.i.rs)) < static_cast<s32>(inst.i.imm_sext32()));
|
const u32 result = BoolToUInt32(static_cast<s32>(ReadReg(inst.i.rs)) < static_cast<s32>(inst.i.imm_sext32()));
|
||||||
|
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SLTI(inst.bits, result, ReadReg(inst.i.rs));
|
PGXP::CPU_SLTI(inst.bits, ReadReg(inst.i.rs));
|
||||||
|
|
||||||
WriteReg(inst.i.rt, result);
|
WriteReg(inst.i.rt, result);
|
||||||
}
|
}
|
||||||
|
@ -1039,7 +1039,7 @@ restart_instruction:
|
||||||
const u32 result = BoolToUInt32(ReadReg(inst.i.rs) < inst.i.imm_sext32());
|
const u32 result = BoolToUInt32(ReadReg(inst.i.rs) < inst.i.imm_sext32());
|
||||||
|
|
||||||
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
if constexpr (pgxp_mode >= PGXPMode::CPU)
|
||||||
PGXP::CPU_SLTIU(inst.bits, result, ReadReg(inst.i.rs));
|
PGXP::CPU_SLTIU(inst.bits, ReadReg(inst.i.rs));
|
||||||
|
|
||||||
WriteReg(inst.i.rt, result);
|
WriteReg(inst.i.rt, result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1137,34 +1137,34 @@ bool CodeGenerator::Compile_Bitwise(const CodeBlockInstruction& cbi)
|
||||||
{
|
{
|
||||||
case InstructionOp::ori:
|
case InstructionOp::ori:
|
||||||
{
|
{
|
||||||
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
|
EmitFunctionCall(nullptr, &PGXP::CPU_ORI, Value::FromConstantU32(cbi.instruction.bits), lhs);
|
||||||
|
|
||||||
result = OrValues(lhs, rhs);
|
result = OrValues(lhs, rhs);
|
||||||
if (spec_lhs && spec_rhs)
|
if (spec_lhs && spec_rhs)
|
||||||
spec_value = *spec_lhs | *spec_rhs;
|
spec_value = *spec_lhs | *spec_rhs;
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_ORI, Value::FromConstantU32(cbi.instruction.bits), result, lhs);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InstructionOp::andi:
|
case InstructionOp::andi:
|
||||||
{
|
{
|
||||||
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
|
EmitFunctionCall(nullptr, &PGXP::CPU_ANDI, Value::FromConstantU32(cbi.instruction.bits), lhs);
|
||||||
|
|
||||||
result = AndValues(lhs, rhs);
|
result = AndValues(lhs, rhs);
|
||||||
if (spec_lhs && spec_rhs)
|
if (spec_lhs && spec_rhs)
|
||||||
spec_value = *spec_lhs & *spec_rhs;
|
spec_value = *spec_lhs & *spec_rhs;
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_ANDI, Value::FromConstantU32(cbi.instruction.bits), result, lhs);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InstructionOp::xori:
|
case InstructionOp::xori:
|
||||||
{
|
{
|
||||||
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
|
EmitFunctionCall(nullptr, &PGXP::CPU_XORI, Value::FromConstantU32(cbi.instruction.bits), lhs);
|
||||||
|
|
||||||
result = XorValues(lhs, rhs);
|
result = XorValues(lhs, rhs);
|
||||||
if (spec_lhs && spec_rhs)
|
if (spec_lhs && spec_rhs)
|
||||||
spec_value = *spec_lhs ^ *spec_rhs;
|
spec_value = *spec_lhs ^ *spec_rhs;
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_XORI, Value::FromConstantU32(cbi.instruction.bits), result, lhs);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1174,45 +1174,45 @@ bool CodeGenerator::Compile_Bitwise(const CodeBlockInstruction& cbi)
|
||||||
{
|
{
|
||||||
case InstructionFunct::or_:
|
case InstructionFunct::or_:
|
||||||
{
|
{
|
||||||
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
|
EmitFunctionCall(nullptr, &PGXP::CPU_OR_, Value::FromConstantU32(cbi.instruction.bits), lhs, rhs);
|
||||||
|
|
||||||
result = OrValues(lhs, rhs);
|
result = OrValues(lhs, rhs);
|
||||||
if (spec_lhs && spec_rhs)
|
if (spec_lhs && spec_rhs)
|
||||||
spec_value = *spec_lhs | *spec_rhs;
|
spec_value = *spec_lhs | *spec_rhs;
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_OR_, Value::FromConstantU32(cbi.instruction.bits), result, lhs, rhs);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InstructionFunct::and_:
|
case InstructionFunct::and_:
|
||||||
{
|
{
|
||||||
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
|
EmitFunctionCall(nullptr, &PGXP::CPU_AND_, Value::FromConstantU32(cbi.instruction.bits), lhs, rhs);
|
||||||
|
|
||||||
result = AndValues(lhs, rhs);
|
result = AndValues(lhs, rhs);
|
||||||
if (spec_lhs && spec_rhs)
|
if (spec_lhs && spec_rhs)
|
||||||
spec_value = *spec_lhs & *spec_rhs;
|
spec_value = *spec_lhs & *spec_rhs;
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_AND_, Value::FromConstantU32(cbi.instruction.bits), result, lhs, rhs);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InstructionFunct::xor_:
|
case InstructionFunct::xor_:
|
||||||
{
|
{
|
||||||
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
|
EmitFunctionCall(nullptr, &PGXP::CPU_XOR_, Value::FromConstantU32(cbi.instruction.bits), lhs, rhs);
|
||||||
|
|
||||||
result = XorValues(lhs, rhs);
|
result = XorValues(lhs, rhs);
|
||||||
if (spec_lhs && spec_rhs)
|
if (spec_lhs && spec_rhs)
|
||||||
spec_value = *spec_lhs ^ *spec_rhs;
|
spec_value = *spec_lhs ^ *spec_rhs;
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_XOR_, Value::FromConstantU32(cbi.instruction.bits), result, lhs, rhs);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InstructionFunct::nor:
|
case InstructionFunct::nor:
|
||||||
{
|
{
|
||||||
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
|
EmitFunctionCall(nullptr, &PGXP::CPU_NOR, Value::FromConstantU32(cbi.instruction.bits), lhs, rhs);
|
||||||
|
|
||||||
result = NotValue(OrValues(lhs, rhs));
|
result = NotValue(OrValues(lhs, rhs));
|
||||||
if (spec_lhs && spec_rhs)
|
if (spec_lhs && spec_rhs)
|
||||||
spec_value = ~(*spec_lhs | *spec_rhs);
|
spec_value = ~(*spec_lhs | *spec_rhs);
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_NOR, Value::FromConstantU32(cbi.instruction.bits), result, lhs, rhs);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1264,51 +1264,51 @@ bool CodeGenerator::Compile_Shift(const CodeBlockInstruction& cbi)
|
||||||
case InstructionFunct::sll:
|
case InstructionFunct::sll:
|
||||||
case InstructionFunct::sllv:
|
case InstructionFunct::sllv:
|
||||||
{
|
{
|
||||||
result = ShlValues(rt, shamt, false);
|
|
||||||
if (rt_spec && shamt_spec)
|
|
||||||
result_spec = *rt_spec << *shamt_spec;
|
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
{
|
{
|
||||||
if (cbi.instruction.r.funct == InstructionFunct::sll)
|
if (cbi.instruction.r.funct == InstructionFunct::sll)
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SLL, Value::FromConstantU32(cbi.instruction.bits), result, rt);
|
EmitFunctionCall(nullptr, &PGXP::CPU_SLL, Value::FromConstantU32(cbi.instruction.bits), rt);
|
||||||
else // if (cbi.instruction.r.funct == InstructionFunct::sllv)
|
else // if (cbi.instruction.r.funct == InstructionFunct::sllv)
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SLLV, Value::FromConstantU32(cbi.instruction.bits), result, rt, shamt);
|
EmitFunctionCall(nullptr, &PGXP::CPU_SLLV, Value::FromConstantU32(cbi.instruction.bits), rt, shamt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = ShlValues(rt, shamt, false);
|
||||||
|
if (rt_spec && shamt_spec)
|
||||||
|
result_spec = *rt_spec << *shamt_spec;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InstructionFunct::srl:
|
case InstructionFunct::srl:
|
||||||
case InstructionFunct::srlv:
|
case InstructionFunct::srlv:
|
||||||
{
|
{
|
||||||
result = ShrValues(rt, shamt, false);
|
|
||||||
if (rt_spec && shamt_spec)
|
|
||||||
result_spec = *rt_spec >> *shamt_spec;
|
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
{
|
{
|
||||||
if (cbi.instruction.r.funct == InstructionFunct::srl)
|
if (cbi.instruction.r.funct == InstructionFunct::srl)
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SRL, Value::FromConstantU32(cbi.instruction.bits), result, rt);
|
EmitFunctionCall(nullptr, &PGXP::CPU_SRL, Value::FromConstantU32(cbi.instruction.bits), rt);
|
||||||
else // if (cbi.instruction.r.funct == InstructionFunct::srlv)
|
else // if (cbi.instruction.r.funct == InstructionFunct::srlv)
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SRLV, Value::FromConstantU32(cbi.instruction.bits), result, rt, shamt);
|
EmitFunctionCall(nullptr, &PGXP::CPU_SRLV, Value::FromConstantU32(cbi.instruction.bits), rt, shamt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = ShrValues(rt, shamt, false);
|
||||||
|
if (rt_spec && shamt_spec)
|
||||||
|
result_spec = *rt_spec >> *shamt_spec;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InstructionFunct::sra:
|
case InstructionFunct::sra:
|
||||||
case InstructionFunct::srav:
|
case InstructionFunct::srav:
|
||||||
{
|
{
|
||||||
result = SarValues(rt, shamt, false);
|
|
||||||
if (rt_spec && shamt_spec)
|
|
||||||
result_spec = static_cast<u32>(static_cast<s32>(*rt_spec) << *shamt_spec);
|
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
{
|
{
|
||||||
if (cbi.instruction.r.funct == InstructionFunct::sra)
|
if (cbi.instruction.r.funct == InstructionFunct::sra)
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SRA, Value::FromConstantU32(cbi.instruction.bits), result, rt);
|
EmitFunctionCall(nullptr, &PGXP::CPU_SRA, Value::FromConstantU32(cbi.instruction.bits), rt);
|
||||||
else // if (cbi.instruction.r.funct == InstructionFunct::srav)
|
else // if (cbi.instruction.r.funct == InstructionFunct::srav)
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SRAV, Value::FromConstantU32(cbi.instruction.bits), result, rt, shamt);
|
EmitFunctionCall(nullptr, &PGXP::CPU_SRAV, Value::FromConstantU32(cbi.instruction.bits), rt, shamt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = SarValues(rt, shamt, false);
|
||||||
|
if (rt_spec && shamt_spec)
|
||||||
|
result_spec = static_cast<u32>(static_cast<s32>(*rt_spec) << *shamt_spec);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1721,32 +1721,23 @@ bool CodeGenerator::Compile_Add(const CodeBlockInstruction& cbi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect register moves and handle them for pgxp
|
// detect register moves and handle them for pgxp
|
||||||
bool do_pgxp_cpu = g_settings.UsingPGXPCPUMode();
|
|
||||||
if (g_settings.gpu_pgxp_enable && rhs.HasConstantValue(0))
|
if (g_settings.gpu_pgxp_enable && rhs.HasConstantValue(0))
|
||||||
{
|
{
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_MOVE,
|
EmitFunctionCall(nullptr, &PGXP::CPU_MOVE,
|
||||||
Value::FromConstantU32((static_cast<u32>(dest) << 8) | (static_cast<u32>(lhs_src))), lhs);
|
Value::FromConstantU32((static_cast<u32>(dest) << 8) | (static_cast<u32>(lhs_src))), lhs);
|
||||||
do_pgxp_cpu = false;
|
}
|
||||||
|
else if (g_settings.UsingPGXPCPUMode())
|
||||||
|
{
|
||||||
|
if (cbi.instruction.op != InstructionOp::funct)
|
||||||
|
EmitFunctionCall(nullptr, &PGXP::CPU_ADDI, Value::FromConstantU32(cbi.instruction.bits), lhs);
|
||||||
|
else
|
||||||
|
EmitFunctionCall(nullptr, &PGXP::CPU_ADD, Value::FromConstantU32(cbi.instruction.bits), lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value result = AddValues(lhs, rhs, check_overflow);
|
Value result = AddValues(lhs, rhs, check_overflow);
|
||||||
if (check_overflow)
|
if (check_overflow)
|
||||||
GenerateExceptionExit(cbi, Exception::Ov, Condition::Overflow);
|
GenerateExceptionExit(cbi, Exception::Ov, Condition::Overflow);
|
||||||
|
|
||||||
if (do_pgxp_cpu)
|
|
||||||
{
|
|
||||||
if (cbi.instruction.op != InstructionOp::funct)
|
|
||||||
{
|
|
||||||
// addiu/addiu
|
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_ADDI, Value::FromConstantU32(cbi.instruction.bits), result, lhs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// add/addu
|
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_ADD, Value::FromConstantU32(cbi.instruction.bits), result, lhs, rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_register_cache.WriteGuestRegister(dest, std::move(result));
|
m_register_cache.WriteGuestRegister(dest, std::move(result));
|
||||||
|
|
||||||
SpeculativeValue value_spec;
|
SpeculativeValue value_spec;
|
||||||
|
@ -1771,13 +1762,13 @@ bool CodeGenerator::Compile_Subtract(const CodeBlockInstruction& cbi)
|
||||||
SpeculativeValue lhs_spec = SpeculativeReadReg(cbi.instruction.r.rs);
|
SpeculativeValue lhs_spec = SpeculativeReadReg(cbi.instruction.r.rs);
|
||||||
SpeculativeValue rhs_spec = SpeculativeReadReg(cbi.instruction.r.rt);
|
SpeculativeValue rhs_spec = SpeculativeReadReg(cbi.instruction.r.rt);
|
||||||
|
|
||||||
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
|
EmitFunctionCall(nullptr, &PGXP::CPU_SUB, Value::FromConstantU32(cbi.instruction.bits), lhs, rhs);
|
||||||
|
|
||||||
Value result = SubValues(lhs, rhs, check_overflow);
|
Value result = SubValues(lhs, rhs, check_overflow);
|
||||||
if (check_overflow)
|
if (check_overflow)
|
||||||
GenerateExceptionExit(cbi, Exception::Ov, Condition::Overflow);
|
GenerateExceptionExit(cbi, Exception::Ov, Condition::Overflow);
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SUB, Value::FromConstantU32(cbi.instruction.bits), result, lhs, rhs);
|
|
||||||
|
|
||||||
m_register_cache.WriteGuestRegister(cbi.instruction.r.rd, std::move(result));
|
m_register_cache.WriteGuestRegister(cbi.instruction.r.rd, std::move(result));
|
||||||
|
|
||||||
SpeculativeValue value_spec;
|
SpeculativeValue value_spec;
|
||||||
|
@ -2037,22 +2028,22 @@ bool CodeGenerator::Compile_SetLess(const CodeBlockInstruction& cbi)
|
||||||
m_register_cache.InvalidateGuestRegister(dest);
|
m_register_cache.InvalidateGuestRegister(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value result = m_register_cache.AllocateScratch(RegSize_32);
|
|
||||||
EmitCmp(lhs.host_reg, rhs);
|
|
||||||
EmitSetConditionResult(result.host_reg, result.size, signed_comparison ? Condition::Less : Condition::Below);
|
|
||||||
|
|
||||||
if (g_settings.UsingPGXPCPUMode())
|
if (g_settings.UsingPGXPCPUMode())
|
||||||
{
|
{
|
||||||
if (cbi.instruction.op == InstructionOp::slti)
|
if (cbi.instruction.op == InstructionOp::slti)
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SLTI, Value::FromConstantU32(cbi.instruction.bits), result, lhs);
|
EmitFunctionCall(nullptr, &PGXP::CPU_SLTI, Value::FromConstantU32(cbi.instruction.bits), lhs);
|
||||||
else if (cbi.instruction.op == InstructionOp::sltiu)
|
else if (cbi.instruction.op == InstructionOp::sltiu)
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SLTIU, Value::FromConstantU32(cbi.instruction.bits), result, lhs);
|
EmitFunctionCall(nullptr, &PGXP::CPU_SLTIU, Value::FromConstantU32(cbi.instruction.bits), lhs);
|
||||||
else if (cbi.instruction.r.funct == InstructionFunct::slt)
|
else if (cbi.instruction.r.funct == InstructionFunct::slt)
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SLT, Value::FromConstantU32(cbi.instruction.bits), result, lhs, rhs);
|
EmitFunctionCall(nullptr, &PGXP::CPU_SLT, Value::FromConstantU32(cbi.instruction.bits), lhs, rhs);
|
||||||
else // if (cbi.instruction.r.funct == InstructionFunct::sltu)
|
else // if (cbi.instruction.r.funct == InstructionFunct::sltu)
|
||||||
EmitFunctionCall(nullptr, &PGXP::CPU_SLTU, Value::FromConstantU32(cbi.instruction.bits), result, lhs, rhs);
|
EmitFunctionCall(nullptr, &PGXP::CPU_SLTU, Value::FromConstantU32(cbi.instruction.bits), lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value result = m_register_cache.AllocateScratch(RegSize_32);
|
||||||
|
EmitCmp(lhs.host_reg, rhs);
|
||||||
|
EmitSetConditionResult(result.host_reg, result.size, signed_comparison ? Condition::Less : Condition::Below);
|
||||||
|
|
||||||
m_register_cache.WriteGuestRegister(dest, std::move(result));
|
m_register_cache.WriteGuestRegister(dest, std::move(result));
|
||||||
|
|
||||||
SpeculativeValue value_spec;
|
SpeculativeValue value_spec;
|
||||||
|
|
|
@ -784,6 +784,8 @@ bool GetPreciseVertex(u32 addr, u32 value, int x, int y, int xOffs, int yOffs, f
|
||||||
#define rt(_instr) ((_instr >> 16) & 0x1F) // The rt part of the instruction register
|
#define rt(_instr) ((_instr >> 16) & 0x1F) // The rt part of the instruction register
|
||||||
#define rs(_instr) ((_instr >> 21) & 0x1F) // The rs part of the instruction register
|
#define rs(_instr) ((_instr >> 21) & 0x1F) // The rs part of the instruction register
|
||||||
#define imm(_instr) (_instr & 0xFFFF) // The immediate part of the instruction register
|
#define imm(_instr) (_instr & 0xFFFF) // The immediate part of the instruction register
|
||||||
|
#define imm_sext(_instr) \
|
||||||
|
static_cast<s32>(static_cast<s16>(_instr & 0xFFFF)) // The immediate part of the instruction register
|
||||||
|
|
||||||
void PGXP_InitCPU()
|
void PGXP_InitCPU()
|
||||||
{
|
{
|
||||||
|
@ -884,7 +886,7 @@ void CPU_MOVE(u32 rd_and_rs, u32 rsVal)
|
||||||
CPU_reg[(rd_and_rs >> 8)] = CPU_reg[Rs];
|
CPU_reg[(rd_and_rs >> 8)] = CPU_reg[Rs];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_ADDI(u32 instr, u32 rtVal, u32 rsVal)
|
void CPU_ADDI(u32 instr, u32 rsVal)
|
||||||
{
|
{
|
||||||
// Rt = Rs + Imm (signed)
|
// Rt = Rs + Imm (signed)
|
||||||
psx_value tempImm;
|
psx_value tempImm;
|
||||||
|
@ -911,12 +913,13 @@ void CPU_ADDI(u32 instr, u32 rtVal, u32 rsVal)
|
||||||
}
|
}
|
||||||
|
|
||||||
CPU_reg[rt(instr)] = ret;
|
CPU_reg[rt(instr)] = ret;
|
||||||
CPU_reg[rt(instr)].value = rtVal;
|
CPU_reg[rt(instr)].value = rsVal + imm_sext(instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_ANDI(u32 instr, u32 rtVal, u32 rsVal)
|
void CPU_ANDI(u32 instr, u32 rsVal)
|
||||||
{
|
{
|
||||||
// Rt = Rs & Imm
|
// Rt = Rs & Imm
|
||||||
|
const u32 rtVal = rsVal & imm(instr);
|
||||||
psx_value vRt;
|
psx_value vRt;
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
|
|
||||||
|
@ -948,9 +951,10 @@ void CPU_ANDI(u32 instr, u32 rtVal, u32 rsVal)
|
||||||
CPU_reg[rt(instr)].value = rtVal;
|
CPU_reg[rt(instr)].value = rtVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_ORI(u32 instr, u32 rtVal, u32 rsVal)
|
void CPU_ORI(u32 instr, u32 rsVal)
|
||||||
{
|
{
|
||||||
// Rt = Rs | Imm
|
// Rt = Rs | Imm
|
||||||
|
const u32 rtVal = rsVal | imm(instr);
|
||||||
psx_value vRt;
|
psx_value vRt;
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
|
|
||||||
|
@ -974,9 +978,10 @@ void CPU_ORI(u32 instr, u32 rtVal, u32 rsVal)
|
||||||
CPU_reg[rt(instr)] = ret;
|
CPU_reg[rt(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_XORI(u32 instr, u32 rtVal, u32 rsVal)
|
void CPU_XORI(u32 instr, u32 rsVal)
|
||||||
{
|
{
|
||||||
// Rt = Rs ^ Imm
|
// Rt = Rs ^ Imm
|
||||||
|
const u32 rtVal = rsVal ^ imm(instr);
|
||||||
psx_value vRt;
|
psx_value vRt;
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
|
|
||||||
|
@ -1000,7 +1005,7 @@ void CPU_XORI(u32 instr, u32 rtVal, u32 rsVal)
|
||||||
CPU_reg[rt(instr)] = ret;
|
CPU_reg[rt(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_SLTI(u32 instr, u32 rtVal, u32 rsVal)
|
void CPU_SLTI(u32 instr, u32 rsVal)
|
||||||
{
|
{
|
||||||
// Rt = Rs < Imm (signed)
|
// Rt = Rs < Imm (signed)
|
||||||
psx_value tempImm;
|
psx_value tempImm;
|
||||||
|
@ -1013,12 +1018,12 @@ void CPU_SLTI(u32 instr, u32 rtVal, u32 rsVal)
|
||||||
ret.y = 0.f;
|
ret.y = 0.f;
|
||||||
ret.x = (CPU_reg[rs(instr)].x < tempImm.sw.h) ? 1.f : 0.f;
|
ret.x = (CPU_reg[rs(instr)].x < tempImm.sw.h) ? 1.f : 0.f;
|
||||||
ret.flags |= VALID_1;
|
ret.flags |= VALID_1;
|
||||||
ret.value = rtVal;
|
ret.value = BoolToUInt32(static_cast<s32>(rsVal) < imm_sext(instr));
|
||||||
|
|
||||||
CPU_reg[rt(instr)] = ret;
|
CPU_reg[rt(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_SLTIU(u32 instr, u32 rtVal, u32 rsVal)
|
void CPU_SLTIU(u32 instr, u32 rsVal)
|
||||||
{
|
{
|
||||||
// Rt = Rs < Imm (Unsigned)
|
// Rt = Rs < Imm (Unsigned)
|
||||||
psx_value tempImm;
|
psx_value tempImm;
|
||||||
|
@ -1031,7 +1036,7 @@ void CPU_SLTIU(u32 instr, u32 rtVal, u32 rsVal)
|
||||||
ret.y = 0.f;
|
ret.y = 0.f;
|
||||||
ret.x = (f16Unsign(CPU_reg[rs(instr)].x) < tempImm.w.h) ? 1.f : 0.f;
|
ret.x = (f16Unsign(CPU_reg[rs(instr)].x) < tempImm.w.h) ? 1.f : 0.f;
|
||||||
ret.flags |= VALID_1;
|
ret.flags |= VALID_1;
|
||||||
ret.value = rtVal;
|
ret.value = BoolToUInt32(rsVal < imm(instr));
|
||||||
|
|
||||||
CPU_reg[rt(instr)] = ret;
|
CPU_reg[rt(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
@ -1053,7 +1058,7 @@ void CPU_LUI(u32 instr)
|
||||||
// Register Arithmetic
|
// Register Arithmetic
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
|
|
||||||
void CPU_ADD(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
void CPU_ADD(u32 instr, u32 rsVal, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rs + Rt (signed)
|
// Rd = Rs + Rt (signed)
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
|
@ -1095,12 +1100,12 @@ void CPU_ADD(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
||||||
ret = CPU_reg[rs(instr)];
|
ret = CPU_reg[rs(instr)];
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.value = rdVal;
|
ret.value = rsVal + rtVal;
|
||||||
|
|
||||||
CPU_reg[rd(instr)] = ret;
|
CPU_reg[rd(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_SUB(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
void CPU_SUB(u32 instr, u32 rsVal, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rs - Rt (signed)
|
// Rd = Rs - Rt (signed)
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
|
@ -1133,12 +1138,12 @@ void CPU_SUB(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
||||||
ret.lFlags |= CPU_reg[rt(instr)].lFlags;
|
ret.lFlags |= CPU_reg[rt(instr)].lFlags;
|
||||||
ret.hFlags |= CPU_reg[rt(instr)].hFlags;
|
ret.hFlags |= CPU_reg[rt(instr)].hFlags;
|
||||||
|
|
||||||
ret.value = rdVal;
|
ret.value = rsVal - rtVal;
|
||||||
|
|
||||||
CPU_reg[rd(instr)] = ret;
|
CPU_reg[rd(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_AND_(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
static void CPU_BITWISE(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rs & Rt
|
// Rd = Rs & Rt
|
||||||
psx_value vald, vals, valt;
|
psx_value vald, vals, valt;
|
||||||
|
@ -1230,25 +1235,35 @@ void CPU_AND_(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
||||||
CPU_reg[rd(instr)] = ret;
|
CPU_reg[rd(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_OR_(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
void CPU_AND_(u32 instr, u32 rsVal, u32 rtVal)
|
||||||
|
{
|
||||||
|
// Rd = Rs & Rt
|
||||||
|
const u32 rdVal = rsVal & rtVal;
|
||||||
|
CPU_BITWISE(instr, rdVal, rsVal, rtVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPU_OR_(u32 instr, u32 rsVal, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rs | Rt
|
// Rd = Rs | Rt
|
||||||
CPU_AND_(instr, rdVal, rsVal, rtVal);
|
const u32 rdVal = rsVal | rtVal;
|
||||||
|
CPU_BITWISE(instr, rdVal, rsVal, rtVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_XOR_(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
void CPU_XOR_(u32 instr, u32 rsVal, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rs ^ Rt
|
// Rd = Rs ^ Rt
|
||||||
CPU_AND_(instr, rdVal, rsVal, rtVal);
|
const u32 rdVal = rsVal ^ rtVal;
|
||||||
|
CPU_BITWISE(instr, rdVal, rsVal, rtVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_NOR(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
void CPU_NOR(u32 instr, u32 rsVal, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rs NOR Rt
|
// Rd = Rs NOR Rt
|
||||||
CPU_AND_(instr, rdVal, rsVal, rtVal);
|
const u32 rdVal = ~(rsVal | rtVal);
|
||||||
|
CPU_BITWISE(instr, rdVal, rsVal, rtVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_SLT(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
void CPU_SLT(u32 instr, u32 rsVal, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rs < Rt (signed)
|
// Rd = Rs < Rt (signed)
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
|
@ -1270,11 +1285,11 @@ void CPU_SLT(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
||||||
1.f :
|
1.f :
|
||||||
(f16Unsign(CPU_reg[rs(instr)].x) < f16Unsign(CPU_reg[rt(instr)].x)) ? 1.f : 0.f;
|
(f16Unsign(CPU_reg[rs(instr)].x) < f16Unsign(CPU_reg[rt(instr)].x)) ? 1.f : 0.f;
|
||||||
|
|
||||||
ret.value = rdVal;
|
ret.value = BoolToUInt32(static_cast<s32>(rsVal) < static_cast<s32>(rtVal));
|
||||||
CPU_reg[rd(instr)] = ret;
|
CPU_reg[rd(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_SLTU(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
void CPU_SLTU(u32 instr, u32 rsVal, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rs < Rt (unsigned)
|
// Rd = Rs < Rt (unsigned)
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
|
@ -1296,7 +1311,7 @@ void CPU_SLTU(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal)
|
||||||
1.f :
|
1.f :
|
||||||
(f16Unsign(CPU_reg[rs(instr)].x) < f16Unsign(CPU_reg[rt(instr)].x)) ? 1.f : 0.f;
|
(f16Unsign(CPU_reg[rs(instr)].x) < f16Unsign(CPU_reg[rt(instr)].x)) ? 1.f : 0.f;
|
||||||
|
|
||||||
ret.value = rdVal;
|
ret.value = BoolToUInt32(rsVal < rtVal);
|
||||||
CPU_reg[rd(instr)] = ret;
|
CPU_reg[rd(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1494,9 +1509,10 @@ void CPU_DIVU(u32 instr, u32 rsVal, u32 rtVal)
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
// Shift operations (sa)
|
// Shift operations (sa)
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
void CPU_SLL(u32 instr, u32 rdVal, u32 rtVal)
|
void CPU_SLL(u32 instr, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rt << Sa
|
// Rd = Rt << Sa
|
||||||
|
const u32 rdVal = rtVal << sa(instr);
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
u32 sh = sa(instr);
|
u32 sh = sa(instr);
|
||||||
Validate(&CPU_reg[rt(instr)], rtVal);
|
Validate(&CPU_reg[rt(instr)], rtVal);
|
||||||
|
@ -1538,9 +1554,10 @@ void CPU_SLL(u32 instr, u32 rdVal, u32 rtVal)
|
||||||
CPU_reg[rd(instr)] = ret;
|
CPU_reg[rd(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_SRL(u32 instr, u32 rdVal, u32 rtVal)
|
void CPU_SRL(u32 instr, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rt >> Sa
|
// Rd = Rt >> Sa
|
||||||
|
const u32 rdVal = rtVal >> sa(instr);
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
u32 sh = sa(instr);
|
u32 sh = sa(instr);
|
||||||
Validate(&CPU_reg[rt(instr)], rtVal);
|
Validate(&CPU_reg[rt(instr)], rtVal);
|
||||||
|
@ -1601,9 +1618,10 @@ void CPU_SRL(u32 instr, u32 rdVal, u32 rtVal)
|
||||||
CPU_reg[rd(instr)] = ret;
|
CPU_reg[rd(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_SRA(u32 instr, u32 rdVal, u32 rtVal)
|
void CPU_SRA(u32 instr, u32 rtVal)
|
||||||
{
|
{
|
||||||
// Rd = Rt >> Sa
|
// Rd = Rt >> Sa
|
||||||
|
const u32 rdVal = static_cast<u32>(static_cast<s32>(rtVal) >> sa(instr));
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
u32 sh = sa(instr);
|
u32 sh = sa(instr);
|
||||||
Validate(&CPU_reg[rt(instr)], rtVal);
|
Validate(&CPU_reg[rt(instr)], rtVal);
|
||||||
|
@ -1666,9 +1684,10 @@ void CPU_SRA(u32 instr, u32 rdVal, u32 rtVal)
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
// Shift operations variable
|
// Shift operations variable
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
void CPU_SLLV(u32 instr, u32 rdVal, u32 rtVal, u32 rsVal)
|
void CPU_SLLV(u32 instr, u32 rtVal, u32 rsVal)
|
||||||
{
|
{
|
||||||
// Rd = Rt << Rs
|
// Rd = Rt << Rs
|
||||||
|
const u32 rdVal = rtVal << rsVal;
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
u32 sh = rsVal & 0x1F;
|
u32 sh = rsVal & 0x1F;
|
||||||
Validate(&CPU_reg[rt(instr)], rtVal);
|
Validate(&CPU_reg[rt(instr)], rtVal);
|
||||||
|
@ -1710,9 +1729,10 @@ void CPU_SLLV(u32 instr, u32 rdVal, u32 rtVal, u32 rsVal)
|
||||||
CPU_reg[rd(instr)] = ret;
|
CPU_reg[rd(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_SRLV(u32 instr, u32 rdVal, u32 rtVal, u32 rsVal)
|
void CPU_SRLV(u32 instr, u32 rtVal, u32 rsVal)
|
||||||
{
|
{
|
||||||
// Rd = Rt >> Sa
|
// Rd = Rt >> Sa
|
||||||
|
const u32 rdVal = rtVal >> rsVal;
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
u32 sh = rsVal & 0x1F;
|
u32 sh = rsVal & 0x1F;
|
||||||
Validate(&CPU_reg[rt(instr)], rtVal);
|
Validate(&CPU_reg[rt(instr)], rtVal);
|
||||||
|
@ -1774,9 +1794,10 @@ void CPU_SRLV(u32 instr, u32 rdVal, u32 rtVal, u32 rsVal)
|
||||||
CPU_reg[rd(instr)] = ret;
|
CPU_reg[rd(instr)] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_SRAV(u32 instr, u32 rdVal, u32 rtVal, u32 rsVal)
|
void CPU_SRAV(u32 instr, u32 rtVal, u32 rsVal)
|
||||||
{
|
{
|
||||||
// Rd = Rt >> Sa
|
// Rd = Rt >> Sa
|
||||||
|
const u32 rdVal = static_cast<u32>(static_cast<s32>(rtVal) >> rsVal);
|
||||||
PGXP_value ret;
|
PGXP_value ret;
|
||||||
u32 sh = rsVal & 0x1F;
|
u32 sh = rsVal & 0x1F;
|
||||||
Validate(&CPU_reg[rt(instr)], rtVal);
|
Validate(&CPU_reg[rt(instr)], rtVal);
|
||||||
|
|
|
@ -55,25 +55,25 @@ void CPU_SW(u32 instr, u32 rtVal, u32 addr);
|
||||||
void CPU_MOVE(u32 rd_and_rs, u32 rsVal);
|
void CPU_MOVE(u32 rd_and_rs, u32 rsVal);
|
||||||
|
|
||||||
// Arithmetic with immediate value
|
// Arithmetic with immediate value
|
||||||
void CPU_ADDI(u32 instr, u32 rtVal, u32 rsVal);
|
void CPU_ADDI(u32 instr, u32 rsVal);
|
||||||
void CPU_ANDI(u32 instr, u32 rtVal, u32 rsVal);
|
void CPU_ANDI(u32 instr, u32 rsVal);
|
||||||
void CPU_ORI(u32 instr, u32 rtVal, u32 rsVal);
|
void CPU_ORI(u32 instr, u32 rsVal);
|
||||||
void CPU_XORI(u32 instr, u32 rtVal, u32 rsVal);
|
void CPU_XORI(u32 instr, u32 rsVal);
|
||||||
void CPU_SLTI(u32 instr, u32 rtVal, u32 rsVal);
|
void CPU_SLTI(u32 instr, u32 rsVal);
|
||||||
void CPU_SLTIU(u32 instr, u32 rtVal, u32 rsVal);
|
void CPU_SLTIU(u32 instr, u32 rsVal);
|
||||||
|
|
||||||
// Load Upper
|
// Load Upper
|
||||||
void CPU_LUI(u32 instr);
|
void CPU_LUI(u32 instr);
|
||||||
|
|
||||||
// Register Arithmetic
|
// Register Arithmetic
|
||||||
void CPU_ADD(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal);
|
void CPU_ADD(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
void CPU_SUB(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal);
|
void CPU_SUB(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
void CPU_AND_(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal);
|
void CPU_AND_(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
void CPU_OR_(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal);
|
void CPU_OR_(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
void CPU_XOR_(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal);
|
void CPU_XOR_(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
void CPU_NOR(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal);
|
void CPU_NOR(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
void CPU_SLT(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal);
|
void CPU_SLT(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
void CPU_SLTU(u32 instr, u32 rdVal, u32 rsVal, u32 rtVal);
|
void CPU_SLTU(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
|
|
||||||
// Register mult/div
|
// Register mult/div
|
||||||
void CPU_MULT(u32 instr, u32 rsVal, u32 rtVal);
|
void CPU_MULT(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
|
@ -82,14 +82,14 @@ void CPU_DIV(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
void CPU_DIVU(u32 instr, u32 rsVal, u32 rtVal);
|
void CPU_DIVU(u32 instr, u32 rsVal, u32 rtVal);
|
||||||
|
|
||||||
// Shift operations (sa)
|
// Shift operations (sa)
|
||||||
void CPU_SLL(u32 instr, u32 rdVal, u32 rtVal);
|
void CPU_SLL(u32 instr, u32 rtVal);
|
||||||
void CPU_SRL(u32 instr, u32 rdVal, u32 rtVal);
|
void CPU_SRL(u32 instr, u32 rtVal);
|
||||||
void CPU_SRA(u32 instr, u32 rdVal, u32 rtVal);
|
void CPU_SRA(u32 instr, u32 rtVal);
|
||||||
|
|
||||||
// Shift operations variable
|
// Shift operations variable
|
||||||
void CPU_SLLV(u32 instr, u32 rdVal, u32 rtVal, u32 rsVal);
|
void CPU_SLLV(u32 instr, u32 rtVal, u32 rsVal);
|
||||||
void CPU_SRLV(u32 instr, u32 rdVal, u32 rtVal, u32 rsVal);
|
void CPU_SRLV(u32 instr, u32 rtVal, u32 rsVal);
|
||||||
void CPU_SRAV(u32 instr, u32 rdVal, u32 rtVal, u32 rsVal);
|
void CPU_SRAV(u32 instr, u32 rtVal, u32 rsVal);
|
||||||
|
|
||||||
// Move registers
|
// Move registers
|
||||||
void CPU_MFHI(u32 instr, u32 hiVal);
|
void CPU_MFHI(u32 instr, u32 hiVal);
|
||||||
|
|
Loading…
Reference in a new issue