mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-25 20:36:54 +01:00
shader: add missing F64 VOPC compares
Co-authored-by: Hector Mödinger S. <hectormodinger@gmail.com>
This commit is contained in:
@@ -374,10 +374,38 @@ enum class Opcode {
|
||||
V_CMP_NEQ_F32,
|
||||
V_CMP_NLT_F32,
|
||||
V_CMP_TRU_F32,
|
||||
V_CMP_F_F64,
|
||||
V_CMP_LT_F64,
|
||||
V_CMP_EQ_F64,
|
||||
V_CMP_LE_F64,
|
||||
V_CMP_GT_F64,
|
||||
V_CMP_LG_F64,
|
||||
V_CMP_GE_F64,
|
||||
V_CMP_O_F64,
|
||||
V_CMP_U_F64,
|
||||
V_CMP_NGE_F64,
|
||||
V_CMP_NLG_F64,
|
||||
V_CMP_NGT_F64,
|
||||
V_CMP_NLE_F64,
|
||||
V_CMP_NEQ_F64,
|
||||
V_CMP_NLT_F64,
|
||||
V_CMP_TRU_F64,
|
||||
V_CMPX_F_F64,
|
||||
V_CMPX_LT_F64,
|
||||
V_CMPX_EQ_F64,
|
||||
V_CMPX_LE_F64,
|
||||
V_CMPX_GT_F64,
|
||||
V_CMPX_LG_F64,
|
||||
V_CMPX_GE_F64,
|
||||
V_CMPX_O_F64,
|
||||
V_CMPX_U_F64,
|
||||
V_CMPX_NGE_F64,
|
||||
V_CMPX_NLG_F64,
|
||||
V_CMPX_NGT_F64,
|
||||
V_CMPX_NLE_F64,
|
||||
V_CMPX_NEQ_F64,
|
||||
V_CMPX_NLT_F64,
|
||||
V_CMPX_TRU_F64,
|
||||
V_CMPX_LT_F32,
|
||||
V_CMPX_EQ_F32,
|
||||
V_CMPX_LE_F32,
|
||||
|
||||
@@ -236,8 +236,23 @@ constexpr VopcOpcodeInfo VOPC_OPCODE_LIST[] = {
|
||||
{0x19u, Opcode::V_CMPX_NGE_F32}, {0x1au, Opcode::V_CMPX_NLG_F32},
|
||||
{0x1bu, Opcode::V_CMPX_NGT_F32}, {0x1cu, Opcode::V_CMPX_NLE_F32},
|
||||
{0x1du, Opcode::V_CMPX_NEQ_F32}, {0x1eu, Opcode::V_CMPX_NLT_F32},
|
||||
{0x22u, Opcode::V_CMP_EQ_F64, false}, {0x23u, Opcode::V_CMP_LE_F64, false},
|
||||
{0x33u, Opcode::V_CMPX_LE_F64, false}, {0x36u, Opcode::V_CMPX_GE_F64, false},
|
||||
{0x20u, Opcode::V_CMP_F_F64, false}, {0x21u, Opcode::V_CMP_LT_F64, false},
|
||||
{0x22u, Opcode::V_CMP_EQ_F64, false}, {0x23u, Opcode::V_CMP_LE_F64, false},
|
||||
{0x24u, Opcode::V_CMP_GT_F64, false}, {0x25u, Opcode::V_CMP_LG_F64, false},
|
||||
{0x26u, Opcode::V_CMP_GE_F64, false}, {0x27u, Opcode::V_CMP_O_F64, false},
|
||||
{0x28u, Opcode::V_CMP_U_F64, false}, {0x29u, Opcode::V_CMP_NGE_F64, false},
|
||||
{0x2au, Opcode::V_CMP_NLG_F64, false}, {0x2bu, Opcode::V_CMP_NGT_F64, false},
|
||||
{0x2cu, Opcode::V_CMP_NLE_F64, false}, {0x2du, Opcode::V_CMP_NEQ_F64, false},
|
||||
{0x2eu, Opcode::V_CMP_NLT_F64, false}, {0x2fu, Opcode::V_CMP_TRU_F64, false},
|
||||
{0x30u, Opcode::V_CMPX_F_F64, false},
|
||||
{0x31u, Opcode::V_CMPX_LT_F64, false}, {0x32u, Opcode::V_CMPX_EQ_F64, false},
|
||||
{0x33u, Opcode::V_CMPX_LE_F64, false}, {0x34u, Opcode::V_CMPX_GT_F64, false},
|
||||
{0x35u, Opcode::V_CMPX_LG_F64, false}, {0x36u, Opcode::V_CMPX_GE_F64, false},
|
||||
{0x37u, Opcode::V_CMPX_O_F64, false}, {0x38u, Opcode::V_CMPX_U_F64, false},
|
||||
{0x39u, Opcode::V_CMPX_NGE_F64, false}, {0x3au, Opcode::V_CMPX_NLG_F64, false},
|
||||
{0x3bu, Opcode::V_CMPX_NGT_F64, false}, {0x3cu, Opcode::V_CMPX_NLE_F64, false},
|
||||
{0x3du, Opcode::V_CMPX_NEQ_F64, false}, {0x3eu, Opcode::V_CMPX_NLT_F64, false},
|
||||
{0x3fu, Opcode::V_CMPX_TRU_F64, false},
|
||||
{0x80u, Opcode::V_CMP_F_I32}, {0x81u, Opcode::V_CMP_LT_I32},
|
||||
{0x82u, Opcode::V_CMP_EQ_I32}, {0x83u, Opcode::V_CMP_LE_I32},
|
||||
{0x84u, Opcode::V_CMP_GT_I32}, {0x85u, Opcode::V_CMP_NE_I32},
|
||||
@@ -879,10 +894,38 @@ bool IsVopcFloatCompareOpcode(Opcode opcode) {
|
||||
case Opcode::V_CMP_F_F32:
|
||||
case Opcode::V_CMP_LT_F32:
|
||||
case Opcode::V_CMP_EQ_F32:
|
||||
case Opcode::V_CMP_F_F64:
|
||||
case Opcode::V_CMP_LT_F64:
|
||||
case Opcode::V_CMP_EQ_F64:
|
||||
case Opcode::V_CMP_LE_F64:
|
||||
case Opcode::V_CMP_GT_F64:
|
||||
case Opcode::V_CMP_LG_F64:
|
||||
case Opcode::V_CMP_GE_F64:
|
||||
case Opcode::V_CMP_O_F64:
|
||||
case Opcode::V_CMP_U_F64:
|
||||
case Opcode::V_CMP_NGE_F64:
|
||||
case Opcode::V_CMP_NLG_F64:
|
||||
case Opcode::V_CMP_NGT_F64:
|
||||
case Opcode::V_CMP_NLE_F64:
|
||||
case Opcode::V_CMP_NEQ_F64:
|
||||
case Opcode::V_CMP_NLT_F64:
|
||||
case Opcode::V_CMP_TRU_F64:
|
||||
case Opcode::V_CMPX_F_F64:
|
||||
case Opcode::V_CMPX_LT_F64:
|
||||
case Opcode::V_CMPX_EQ_F64:
|
||||
case Opcode::V_CMPX_LE_F64:
|
||||
case Opcode::V_CMPX_GT_F64:
|
||||
case Opcode::V_CMPX_LG_F64:
|
||||
case Opcode::V_CMPX_GE_F64:
|
||||
case Opcode::V_CMPX_O_F64:
|
||||
case Opcode::V_CMPX_U_F64:
|
||||
case Opcode::V_CMPX_NGE_F64:
|
||||
case Opcode::V_CMPX_NLG_F64:
|
||||
case Opcode::V_CMPX_NGT_F64:
|
||||
case Opcode::V_CMPX_NLE_F64:
|
||||
case Opcode::V_CMPX_NEQ_F64:
|
||||
case Opcode::V_CMPX_NLT_F64:
|
||||
case Opcode::V_CMPX_TRU_F64:
|
||||
case Opcode::V_CMP_LE_F32:
|
||||
case Opcode::V_CMP_GT_F32:
|
||||
case Opcode::V_CMP_LG_F32:
|
||||
@@ -1202,10 +1245,9 @@ VopcSdwaFields DecodeVopcSdwaFields(uint32_t modifier) {
|
||||
}
|
||||
|
||||
bool SupportsVopcSdwa(Opcode opcode) {
|
||||
// F64 SDWA operand handling is not implemented.
|
||||
return opcode != Opcode::UNSUPPORTED && opcode != Opcode::V_CMP_NE_I64 &&
|
||||
opcode != Opcode::V_CMP_EQ_F64 &&
|
||||
opcode != Opcode::V_CMP_LE_F64 && opcode != Opcode::V_CMPX_LE_F64 &&
|
||||
opcode != Opcode::V_CMPX_GE_F64;
|
||||
(opcode < Opcode::V_CMP_F_F64 || opcode > Opcode::V_CMPX_TRU_F64);
|
||||
}
|
||||
|
||||
void DecodeVopcSdwa(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index,
|
||||
@@ -1538,8 +1580,22 @@ void ApplyNativeVop3SourceModifiers(Instruction& inst, uint32_t abs, uint32_t ne
|
||||
|
||||
bool IsVopcCompareExec(Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Opcode::V_CMPX_F_F64:
|
||||
case Opcode::V_CMPX_LT_F64:
|
||||
case Opcode::V_CMPX_EQ_F64:
|
||||
case Opcode::V_CMPX_LE_F64:
|
||||
case Opcode::V_CMPX_GT_F64:
|
||||
case Opcode::V_CMPX_LG_F64:
|
||||
case Opcode::V_CMPX_GE_F64:
|
||||
case Opcode::V_CMPX_O_F64:
|
||||
case Opcode::V_CMPX_U_F64:
|
||||
case Opcode::V_CMPX_NGE_F64:
|
||||
case Opcode::V_CMPX_NLG_F64:
|
||||
case Opcode::V_CMPX_NGT_F64:
|
||||
case Opcode::V_CMPX_NLE_F64:
|
||||
case Opcode::V_CMPX_NEQ_F64:
|
||||
case Opcode::V_CMPX_NLT_F64:
|
||||
case Opcode::V_CMPX_TRU_F64:
|
||||
case Opcode::V_CMPX_LT_F32:
|
||||
case Opcode::V_CMPX_EQ_F32:
|
||||
case Opcode::V_CMPX_LE_F32:
|
||||
|
||||
@@ -65,11 +65,14 @@ void Translator::EmitFloatCompare(const Decoder::Instruction& inst, IR::ValueOpc
|
||||
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs}, flags)), false, cmpx);
|
||||
}
|
||||
|
||||
void Translator::EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered, bool cmpx) {
|
||||
const auto lhs = IR::F32(ReadOperand(inst.src0, IR::Type::F32));
|
||||
const auto rhs = IR::F32(ReadOperand(inst.src1, IR::Type::F32));
|
||||
const auto unordered = ir.LogicalOr(IR::U1(ir.Emit(IR::ValueOpcode::FPIsNan32, {lhs})),
|
||||
IR::U1(ir.Emit(IR::ValueOpcode::FPIsNan32, {rhs})));
|
||||
void Translator::EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered, bool cmpx,
|
||||
bool is64) {
|
||||
const auto type = is64 ? IR::Type::F64 : IR::Type::F32;
|
||||
const auto is_nan_op = is64 ? IR::ValueOpcode::FPIsNan64 : IR::ValueOpcode::FPIsNan32;
|
||||
const auto lhs = ReadOperand(inst.src0, type);
|
||||
const auto rhs = ReadOperand(inst.src1, type);
|
||||
const auto unordered = ir.LogicalOr(IR::U1(ir.Emit(is_nan_op, {lhs})),
|
||||
IR::U1(ir.Emit(is_nan_op, {rhs})));
|
||||
EmitCompareResult(inst, ordered ? ir.LogicalNot(unordered) : unordered, false, cmpx);
|
||||
}
|
||||
|
||||
|
||||
@@ -875,10 +875,38 @@ void IncludeInstructionVectorRegisters(const Decoder::Instruction& inst, uint32_
|
||||
case Decoder::Opcode::V_FLOOR_F64:
|
||||
case Decoder::Opcode::V_FRACT_F64: include_vector(inst.dst, 2u); [[fallthrough]];
|
||||
case Decoder::Opcode::V_CVT_F32_F64: include_vector(inst.src0, 2u); break;
|
||||
case Decoder::Opcode::V_CMP_F_F64:
|
||||
case Decoder::Opcode::V_CMP_LT_F64:
|
||||
case Decoder::Opcode::V_CMP_EQ_F64:
|
||||
case Decoder::Opcode::V_CMP_LE_F64:
|
||||
case Decoder::Opcode::V_CMP_GT_F64:
|
||||
case Decoder::Opcode::V_CMP_LG_F64:
|
||||
case Decoder::Opcode::V_CMP_GE_F64:
|
||||
case Decoder::Opcode::V_CMP_O_F64:
|
||||
case Decoder::Opcode::V_CMP_U_F64:
|
||||
case Decoder::Opcode::V_CMP_NGE_F64:
|
||||
case Decoder::Opcode::V_CMP_NLG_F64:
|
||||
case Decoder::Opcode::V_CMP_NGT_F64:
|
||||
case Decoder::Opcode::V_CMP_NLE_F64:
|
||||
case Decoder::Opcode::V_CMP_NEQ_F64:
|
||||
case Decoder::Opcode::V_CMP_NLT_F64:
|
||||
case Decoder::Opcode::V_CMP_TRU_F64:
|
||||
case Decoder::Opcode::V_CMPX_F_F64:
|
||||
case Decoder::Opcode::V_CMPX_LT_F64:
|
||||
case Decoder::Opcode::V_CMPX_EQ_F64:
|
||||
case Decoder::Opcode::V_CMPX_LE_F64:
|
||||
case Decoder::Opcode::V_CMPX_GT_F64:
|
||||
case Decoder::Opcode::V_CMPX_LG_F64:
|
||||
case Decoder::Opcode::V_CMPX_GE_F64:
|
||||
case Decoder::Opcode::V_CMPX_O_F64:
|
||||
case Decoder::Opcode::V_CMPX_U_F64:
|
||||
case Decoder::Opcode::V_CMPX_NGE_F64:
|
||||
case Decoder::Opcode::V_CMPX_NLG_F64:
|
||||
case Decoder::Opcode::V_CMPX_NGT_F64:
|
||||
case Decoder::Opcode::V_CMPX_NLE_F64:
|
||||
case Decoder::Opcode::V_CMPX_NEQ_F64:
|
||||
case Decoder::Opcode::V_CMPX_NLT_F64:
|
||||
case Decoder::Opcode::V_CMPX_TRU_F64:
|
||||
case Decoder::Opcode::V_CMP_EQ_I64:
|
||||
case Decoder::Opcode::V_CMP_LT_I64:
|
||||
case Decoder::Opcode::V_CMP_LE_I64:
|
||||
|
||||
@@ -127,7 +127,8 @@ private:
|
||||
bool signed_value, bool cmpx);
|
||||
void EmitFloatCompare(const Decoder::Instruction& inst, IR::ValueOpcode opcode, bool half,
|
||||
bool cmpx);
|
||||
void EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered, bool cmpx);
|
||||
void EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered, bool cmpx,
|
||||
bool is64 = false);
|
||||
void EmitFloatClassCompare(const Decoder::Instruction& inst, bool cmpx, bool half = false);
|
||||
void V_CVT_F32_UBYTE(const Decoder::Instruction& inst, uint32_t byte_index);
|
||||
void V_CVT_F32_U32(const Decoder::Instruction& inst);
|
||||
|
||||
@@ -242,6 +242,74 @@ void Translator::EmitVector(const Decoder::Instruction& inst) {
|
||||
case O::V_CMPX_GE_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdGreaterThanEqual64, false, true);
|
||||
return;
|
||||
case O::V_CMP_F_F64: EmitCompareConstant(inst, false, false, false); return;
|
||||
case O::V_CMP_TRU_F64: EmitCompareConstant(inst, true, false, false); return;
|
||||
case O::V_CMPX_F_F64: EmitCompareConstant(inst, false, false, true); return;
|
||||
case O::V_CMPX_TRU_F64: EmitCompareConstant(inst, true, false, true); return;
|
||||
case O::V_CMP_LT_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdLessThan64, false, false);
|
||||
return;
|
||||
case O::V_CMPX_LT_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdLessThan64, false, true);
|
||||
return;
|
||||
case O::V_CMPX_EQ_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdEqual64, false, true);
|
||||
return;
|
||||
case O::V_CMP_GT_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdGreaterThan64, false, false);
|
||||
return;
|
||||
case O::V_CMPX_GT_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdGreaterThan64, false, true);
|
||||
return;
|
||||
case O::V_CMP_LG_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdNotEqual64, false, false);
|
||||
return;
|
||||
case O::V_CMPX_LG_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdNotEqual64, false, true);
|
||||
return;
|
||||
case O::V_CMP_GE_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdGreaterThanEqual64, false, false);
|
||||
return;
|
||||
case O::V_CMP_NLG_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordEqual64, false, false);
|
||||
return;
|
||||
case O::V_CMPX_NLG_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordEqual64, false, true);
|
||||
return;
|
||||
case O::V_CMP_NEQ_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordNotEqual64, false, false);
|
||||
return;
|
||||
case O::V_CMPX_NEQ_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordNotEqual64, false, true);
|
||||
return;
|
||||
case O::V_CMP_NLE_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordGreaterThan64, false, false);
|
||||
return;
|
||||
case O::V_CMPX_NLE_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordGreaterThan64, false, true);
|
||||
return;
|
||||
case O::V_CMP_NLT_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordGreaterThanEqual64, false, false);
|
||||
return;
|
||||
case O::V_CMPX_NLT_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordGreaterThanEqual64, false, true);
|
||||
return;
|
||||
case O::V_CMP_NGE_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordLessThan64, false, false);
|
||||
return;
|
||||
case O::V_CMPX_NGE_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordLessThan64, false, true);
|
||||
return;
|
||||
case O::V_CMP_NGT_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordLessThanEqual64, false, false);
|
||||
return;
|
||||
case O::V_CMPX_NGT_F64:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordLessThanEqual64, false, true);
|
||||
return;
|
||||
case O::V_CMP_O_F64: EmitFloatOrderedCompare(inst, true, false, true); return;
|
||||
case O::V_CMP_U_F64: EmitFloatOrderedCompare(inst, false, false, true); return;
|
||||
case O::V_CMPX_O_F64: EmitFloatOrderedCompare(inst, true, true, true); return;
|
||||
case O::V_CMPX_U_F64: EmitFloatOrderedCompare(inst, false, true, true); return;
|
||||
case O::V_CMPX_EQ_F32:
|
||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdEqual32, false, true);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user