mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 11:26:56 +02:00
shader: implement V_CMP_EQ_I64
This commit is contained in:
@@ -766,6 +766,7 @@ std::string OpcodeToString(Opcode opcode) {
|
|||||||
case Opcode::VCmpNeU32: return "v_cmp_ne_u32";
|
case Opcode::VCmpNeU32: return "v_cmp_ne_u32";
|
||||||
case Opcode::VCmpGeU32: return "v_cmp_ge_u32";
|
case Opcode::VCmpGeU32: return "v_cmp_ge_u32";
|
||||||
case Opcode::VCmpTU32: return "v_cmp_t_u32";
|
case Opcode::VCmpTU32: return "v_cmp_t_u32";
|
||||||
|
case Opcode::VCmpEqI64: return "v_cmp_eq_i64";
|
||||||
case Opcode::VCmpNeU64: return "v_cmp_ne_u64";
|
case Opcode::VCmpNeU64: return "v_cmp_ne_u64";
|
||||||
case Opcode::VCmpxLtU32: return "v_cmpx_lt_u32";
|
case Opcode::VCmpxLtU32: return "v_cmpx_lt_u32";
|
||||||
case Opcode::VCmpxEqU32: return "v_cmpx_eq_u32";
|
case Opcode::VCmpxEqU32: return "v_cmpx_eq_u32";
|
||||||
|
|||||||
@@ -374,6 +374,7 @@ enum class Opcode {
|
|||||||
VCmpNeU32,
|
VCmpNeU32,
|
||||||
VCmpGeU32,
|
VCmpGeU32,
|
||||||
VCmpTU32,
|
VCmpTU32,
|
||||||
|
VCmpEqI64,
|
||||||
VCmpNeU64,
|
VCmpNeU64,
|
||||||
VCmpxLtU32,
|
VCmpxLtU32,
|
||||||
VCmpxEqU32,
|
VCmpxEqU32,
|
||||||
|
|||||||
@@ -157,13 +157,14 @@ constexpr OpcodeMap VOPC_OPS[] = {
|
|||||||
{0xaeu, Opcode::VCmpGeU16}, {0xc0u, Opcode::VCmpFU32}, {0xc1u, Opcode::VCmpLtU32},
|
{0xaeu, Opcode::VCmpGeU16}, {0xc0u, Opcode::VCmpFU32}, {0xc1u, Opcode::VCmpLtU32},
|
||||||
{0xc2u, Opcode::VCmpEqU32}, {0xc3u, Opcode::VCmpLeU32}, {0xc4u, Opcode::VCmpGtU32},
|
{0xc2u, Opcode::VCmpEqU32}, {0xc3u, Opcode::VCmpLeU32}, {0xc4u, Opcode::VCmpGtU32},
|
||||||
{0xc5u, Opcode::VCmpNeU32}, {0xc6u, Opcode::VCmpGeU32}, {0xc7u, Opcode::VCmpTU32},
|
{0xc5u, Opcode::VCmpNeU32}, {0xc6u, Opcode::VCmpGeU32}, {0xc7u, Opcode::VCmpTU32},
|
||||||
{0xd1u, Opcode::VCmpxLtU32}, {0xd2u, Opcode::VCmpxEqU32}, {0xd3u, Opcode::VCmpxLeU32},
|
{0xa2u, Opcode::VCmpEqI64}, {0xd1u, Opcode::VCmpxLtU32}, {0xd2u, Opcode::VCmpxEqU32},
|
||||||
{0xd4u, Opcode::VCmpxGtU32}, {0xd5u, Opcode::VCmpxNeU32}, {0xd6u, Opcode::VCmpxGeU32},
|
{0xd3u, Opcode::VCmpxLeU32}, {0xd4u, Opcode::VCmpxGtU32}, {0xd5u, Opcode::VCmpxNeU32},
|
||||||
{0xe5u, Opcode::VCmpNeU64}, {0xc9u, Opcode::VCmpLtF16}, {0xcau, Opcode::VCmpEqF16},
|
{0xd6u, Opcode::VCmpxGeU32}, {0xe5u, Opcode::VCmpNeU64}, {0xc9u, Opcode::VCmpLtF16},
|
||||||
{0xcbu, Opcode::VCmpLeF16}, {0xccu, Opcode::VCmpGtF16}, {0xcdu, Opcode::VCmpLgF16},
|
{0xcau, Opcode::VCmpEqF16}, {0xcbu, Opcode::VCmpLeF16}, {0xccu, Opcode::VCmpGtF16},
|
||||||
{0xceu, Opcode::VCmpGeF16}, {0xedu, Opcode::VCmpNeqF16}, {0xd9u, Opcode::VCmpxLtF16},
|
{0xcdu, Opcode::VCmpLgF16}, {0xceu, Opcode::VCmpGeF16}, {0xedu, Opcode::VCmpNeqF16},
|
||||||
{0xdau, Opcode::VCmpxEqF16}, {0xdbu, Opcode::VCmpxLeF16}, {0xdcu, Opcode::VCmpxGtF16},
|
{0xd9u, Opcode::VCmpxLtF16}, {0xdau, Opcode::VCmpxEqF16}, {0xdbu, Opcode::VCmpxLeF16},
|
||||||
{0xdeu, Opcode::VCmpxGeF16}, {0xfdu, Opcode::VCmpxNeqF16}, {0xfeu, Opcode::VCmpxNltF16},
|
{0xdcu, Opcode::VCmpxGtF16}, {0xdeu, Opcode::VCmpxGeF16}, {0xfdu, Opcode::VCmpxNeqF16},
|
||||||
|
{0xfeu, Opcode::VCmpxNltF16},
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr OpcodeMap VOP3_OPS[] = {
|
constexpr OpcodeMap VOP3_OPS[] = {
|
||||||
|
|||||||
@@ -1486,17 +1486,19 @@ void EmitBitCompareB32(EmitterState& state, const IR::Instruction& inst, bool bi
|
|||||||
EmitStoreU32(state, inst.dst, ret);
|
EmitStoreU32(state, inst.dst, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitCompareNeU64(EmitterState& state, const IR::Instruction& inst) {
|
void EmitCompareU64(EmitterState& state, const IR::Instruction& inst, bool equal) {
|
||||||
const auto lhs_low = EmitSequentialValueLoad(state, inst.src[0], 0);
|
const auto lhs_low = EmitSequentialValueLoad(state, inst.src[0], 0);
|
||||||
const auto lhs_high = EmitSequentialValueLoad(state, inst.src[0], 1);
|
const auto lhs_high = EmitSequentialValueLoad(state, inst.src[0], 1);
|
||||||
const auto rhs_low = EmitSequentialValueLoad(state, inst.src[1], 0);
|
const auto rhs_low = EmitSequentialValueLoad(state, inst.src[1], 0);
|
||||||
const auto rhs_high = EmitSequentialValueLoad(state, inst.src[1], 1);
|
const auto rhs_high = EmitSequentialValueLoad(state, inst.src[1], 1);
|
||||||
const auto ne_low = state.builder.AllocateId();
|
const auto low = state.builder.AllocateId();
|
||||||
const auto ne_high = state.builder.AllocateId();
|
const auto high = state.builder.AllocateId();
|
||||||
const auto cond = state.builder.AllocateId();
|
const auto cond = state.builder.AllocateId();
|
||||||
state.builder.AddFunction({OpINotEqual, state.bool_type, ne_low, lhs_low, rhs_low});
|
const auto compare_op = equal ? OpIEqual : OpINotEqual;
|
||||||
state.builder.AddFunction({OpINotEqual, state.bool_type, ne_high, lhs_high, rhs_high});
|
state.builder.AddFunction({compare_op, state.bool_type, low, lhs_low, rhs_low});
|
||||||
state.builder.AddFunction({OpLogicalOr, state.bool_type, cond, ne_low, ne_high});
|
state.builder.AddFunction({compare_op, state.bool_type, high, lhs_high, rhs_high});
|
||||||
|
state.builder.AddFunction(
|
||||||
|
{equal ? OpLogicalAnd : OpLogicalOr, state.bool_type, cond, low, high});
|
||||||
EmitCompareResult(state, inst.dst, cond);
|
EmitCompareResult(state, inst.dst, cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ void CollectRegisters(const IR::Program& program, std::vector<RegisterBinding>&
|
|||||||
if (inst.op == IR::Opcode::BitCountU64 || inst.op == IR::Opcode::FindMsbFromHighU64) {
|
if (inst.op == IR::Opcode::BitCountU64 || inst.op == IR::Opcode::FindMsbFromHighU64) {
|
||||||
CollectSequentialRegisters(registers, inst.src[0], 2);
|
CollectSequentialRegisters(registers, inst.src[0], 2);
|
||||||
}
|
}
|
||||||
if (inst.op == IR::Opcode::CompareNeU64) {
|
if (inst.op == IR::Opcode::CompareEqU64 || inst.op == IR::Opcode::CompareNeU64) {
|
||||||
CollectSequentialRegisters(registers, inst.src[0], 2);
|
CollectSequentialRegisters(registers, inst.src[0], 2);
|
||||||
CollectSequentialRegisters(registers, inst.src[1], 2);
|
CollectSequentialRegisters(registers, inst.src[1], 2);
|
||||||
}
|
}
|
||||||
@@ -394,6 +394,7 @@ bool IsCompareOpcode(IR::Opcode op) {
|
|||||||
case IR::Opcode::CompareGeU32:
|
case IR::Opcode::CompareGeU32:
|
||||||
case IR::Opcode::CompareLtU32:
|
case IR::Opcode::CompareLtU32:
|
||||||
case IR::Opcode::CompareLeU32:
|
case IR::Opcode::CompareLeU32:
|
||||||
|
case IR::Opcode::CompareEqU64:
|
||||||
case IR::Opcode::CompareNeU64:
|
case IR::Opcode::CompareNeU64:
|
||||||
case IR::Opcode::CompareMaskEqU32:
|
case IR::Opcode::CompareMaskEqU32:
|
||||||
case IR::Opcode::CompareMaskNeU32:
|
case IR::Opcode::CompareMaskNeU32:
|
||||||
|
|||||||
@@ -516,7 +516,8 @@ void EmitInstruction(EmitterState& state, const IR::Instruction& inst) {
|
|||||||
case IR::Opcode::CompareGeU32: EmitCompareU32(state, inst, OpUGreaterThanEqual); break;
|
case IR::Opcode::CompareGeU32: EmitCompareU32(state, inst, OpUGreaterThanEqual); break;
|
||||||
case IR::Opcode::CompareLtU32: EmitCompareU32(state, inst, OpULessThan); break;
|
case IR::Opcode::CompareLtU32: EmitCompareU32(state, inst, OpULessThan); break;
|
||||||
case IR::Opcode::CompareLeU32: EmitCompareU32(state, inst, OpULessThanEqual); break;
|
case IR::Opcode::CompareLeU32: EmitCompareU32(state, inst, OpULessThanEqual); break;
|
||||||
case IR::Opcode::CompareNeU64: EmitCompareNeU64(state, inst); break;
|
case IR::Opcode::CompareEqU64: EmitCompareU64(state, inst, true); break;
|
||||||
|
case IR::Opcode::CompareNeU64: EmitCompareU64(state, inst, false); break;
|
||||||
case IR::Opcode::CompareMaskEqU32: EmitCompareMaskU32(state, inst, OpIEqual); break;
|
case IR::Opcode::CompareMaskEqU32: EmitCompareMaskU32(state, inst, OpIEqual); break;
|
||||||
case IR::Opcode::CompareMaskNeU32: EmitCompareMaskU32(state, inst, OpINotEqual); break;
|
case IR::Opcode::CompareMaskNeU32: EmitCompareMaskU32(state, inst, OpINotEqual); break;
|
||||||
case IR::Opcode::CompareMaskGtU32: EmitCompareMaskU32(state, inst, OpUGreaterThan); break;
|
case IR::Opcode::CompareMaskGtU32: EmitCompareMaskU32(state, inst, OpUGreaterThan); break;
|
||||||
|
|||||||
@@ -1345,7 +1345,7 @@ void EmitCompareI16(EmitterState& state, const IR::Instruction& inst, uint32_t o
|
|||||||
|
|
||||||
void EmitBitCompareB32(EmitterState& state, const IR::Instruction& inst, bool bit_set);
|
void EmitBitCompareB32(EmitterState& state, const IR::Instruction& inst, bool bit_set);
|
||||||
|
|
||||||
void EmitCompareNeU64(EmitterState& state, const IR::Instruction& inst);
|
void EmitCompareU64(EmitterState& state, const IR::Instruction& inst, bool equal);
|
||||||
|
|
||||||
void EmitCompareConstant(EmitterState& state, const IR::Instruction& inst, bool value);
|
void EmitCompareConstant(EmitterState& state, const IR::Instruction& inst, bool value);
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ enum class Opcode {
|
|||||||
CompareGeU32,
|
CompareGeU32,
|
||||||
CompareLtU32,
|
CompareLtU32,
|
||||||
CompareLeU32,
|
CompareLeU32,
|
||||||
|
CompareEqU64,
|
||||||
CompareNeU64,
|
CompareNeU64,
|
||||||
CompareMaskEqU32,
|
CompareMaskEqU32,
|
||||||
CompareMaskNeU32,
|
CompareMaskNeU32,
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ std::string InstructionToString(const Instruction& inst) {
|
|||||||
case Opcode::CompareGeU32: text += "CompareGeU32"; break;
|
case Opcode::CompareGeU32: text += "CompareGeU32"; break;
|
||||||
case Opcode::CompareLtU32: text += "CompareLtU32"; break;
|
case Opcode::CompareLtU32: text += "CompareLtU32"; break;
|
||||||
case Opcode::CompareLeU32: text += "CompareLeU32"; break;
|
case Opcode::CompareLeU32: text += "CompareLeU32"; break;
|
||||||
|
case Opcode::CompareEqU64: text += "CompareEqU64"; break;
|
||||||
case Opcode::CompareNeU64: text += "CompareNeU64"; break;
|
case Opcode::CompareNeU64: text += "CompareNeU64"; break;
|
||||||
case Opcode::CompareMaskEqU32: text += "CompareMaskEqU32"; break;
|
case Opcode::CompareMaskEqU32: text += "CompareMaskEqU32"; break;
|
||||||
case Opcode::CompareMaskNeU32: text += "CompareMaskNeU32"; break;
|
case Opcode::CompareMaskNeU32: text += "CompareMaskNeU32"; break;
|
||||||
|
|||||||
@@ -325,6 +325,7 @@ constexpr LowerMap LOWER_OPS[] = {
|
|||||||
{Decoder::Opcode::VCmpNeU32, Opcode::CompareNeU32},
|
{Decoder::Opcode::VCmpNeU32, Opcode::CompareNeU32},
|
||||||
{Decoder::Opcode::VCmpGeU32, Opcode::CompareGeU32},
|
{Decoder::Opcode::VCmpGeU32, Opcode::CompareGeU32},
|
||||||
{Decoder::Opcode::VCmpTU32, Opcode::CompareTrue},
|
{Decoder::Opcode::VCmpTU32, Opcode::CompareTrue},
|
||||||
|
{Decoder::Opcode::VCmpEqI64, Opcode::CompareEqU64},
|
||||||
{Decoder::Opcode::VCmpNeU64, Opcode::CompareNeU64},
|
{Decoder::Opcode::VCmpNeU64, Opcode::CompareNeU64},
|
||||||
{Decoder::Opcode::VCmpxLtU32, Opcode::CompareMaskLtU32},
|
{Decoder::Opcode::VCmpxLtU32, Opcode::CompareMaskLtU32},
|
||||||
{Decoder::Opcode::VCmpxEqU32, Opcode::CompareMaskEqU32},
|
{Decoder::Opcode::VCmpxEqU32, Opcode::CompareMaskEqU32},
|
||||||
|
|||||||
@@ -11593,6 +11593,33 @@ TestCase VectorVop3CompareNeU64OnGpu() {
|
|||||||
O::SEndpgm}};
|
O::SEndpgm}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase VectorVop3CompareEqI64OnGpu() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
|
std::vector<u32> code;
|
||||||
|
code.push_back(EncodeVop1(0x01, 1, InlineU32(1)));
|
||||||
|
code.push_back(EncodeSop1(0x04, 4, 126)); // s_mov_b64 s[4:5], exec
|
||||||
|
|
||||||
|
code.push_back(0xd4a2006au);
|
||||||
|
code.push_back(0x0000087eu); // v_cmp_eq_i64 vcc, exec, s[4:5]
|
||||||
|
code.push_back(EncodeVop2(0x01, 2, InlineU32(0), 1));
|
||||||
|
AppendStoreVgpr(&code, 2, 0);
|
||||||
|
|
||||||
|
AppendSMovLiteral(&code, 4, 0);
|
||||||
|
code.push_back(0xd4a2006au);
|
||||||
|
code.push_back(0x0000087eu); // low dword mismatch
|
||||||
|
code.push_back(EncodeVop2(0x01, 3, InlineU32(0), 1));
|
||||||
|
AppendStoreVgpr(&code, 3, 1);
|
||||||
|
AppendEnd(&code);
|
||||||
|
|
||||||
|
return {"VectorVop3CompareEqI64OnGpu",
|
||||||
|
code,
|
||||||
|
{},
|
||||||
|
{1, 0},
|
||||||
|
{O::VMovB32, O::SMovB64, O::VCmpEqI64, O::VCndmaskB32, O::SMovB32,
|
||||||
|
O::BufferStoreDword, O::SEndpgm}};
|
||||||
|
}
|
||||||
|
|
||||||
TestCase VectorCompareClassF32() {
|
TestCase VectorCompareClassF32() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -15060,6 +15087,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(VectorSpecialF32FlushesDenormalInputs);
|
AddCase(VectorSpecialF32FlushesDenormalInputs);
|
||||||
AddCase(VectorSinCosMaxFiniteSpecialCases);
|
AddCase(VectorSinCosMaxFiniteSpecialCases);
|
||||||
AddCase(VectorCompareOps);
|
AddCase(VectorCompareOps);
|
||||||
|
AddCase(VectorVop3CompareEqI64OnGpu);
|
||||||
AddCase(VectorVop3CompareNeU64OnGpu);
|
AddCase(VectorVop3CompareNeU64OnGpu);
|
||||||
AddCase(VectorCompareClassF32);
|
AddCase(VectorCompareClassF32);
|
||||||
AddCase(VectorCompareF16Ops);
|
AddCase(VectorCompareF16Ops);
|
||||||
|
|||||||
Reference in New Issue
Block a user