mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +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::VCmpGeU32: return "v_cmp_ge_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::VCmpxLtU32: return "v_cmpx_lt_u32";
|
||||
case Opcode::VCmpxEqU32: return "v_cmpx_eq_u32";
|
||||
|
||||
@@ -374,6 +374,7 @@ enum class Opcode {
|
||||
VCmpNeU32,
|
||||
VCmpGeU32,
|
||||
VCmpTU32,
|
||||
VCmpEqI64,
|
||||
VCmpNeU64,
|
||||
VCmpxLtU32,
|
||||
VCmpxEqU32,
|
||||
|
||||
@@ -157,13 +157,14 @@ constexpr OpcodeMap VOPC_OPS[] = {
|
||||
{0xaeu, Opcode::VCmpGeU16}, {0xc0u, Opcode::VCmpFU32}, {0xc1u, Opcode::VCmpLtU32},
|
||||
{0xc2u, Opcode::VCmpEqU32}, {0xc3u, Opcode::VCmpLeU32}, {0xc4u, Opcode::VCmpGtU32},
|
||||
{0xc5u, Opcode::VCmpNeU32}, {0xc6u, Opcode::VCmpGeU32}, {0xc7u, Opcode::VCmpTU32},
|
||||
{0xd1u, Opcode::VCmpxLtU32}, {0xd2u, Opcode::VCmpxEqU32}, {0xd3u, Opcode::VCmpxLeU32},
|
||||
{0xd4u, Opcode::VCmpxGtU32}, {0xd5u, Opcode::VCmpxNeU32}, {0xd6u, Opcode::VCmpxGeU32},
|
||||
{0xe5u, Opcode::VCmpNeU64}, {0xc9u, Opcode::VCmpLtF16}, {0xcau, Opcode::VCmpEqF16},
|
||||
{0xcbu, Opcode::VCmpLeF16}, {0xccu, Opcode::VCmpGtF16}, {0xcdu, Opcode::VCmpLgF16},
|
||||
{0xceu, Opcode::VCmpGeF16}, {0xedu, Opcode::VCmpNeqF16}, {0xd9u, Opcode::VCmpxLtF16},
|
||||
{0xdau, Opcode::VCmpxEqF16}, {0xdbu, Opcode::VCmpxLeF16}, {0xdcu, Opcode::VCmpxGtF16},
|
||||
{0xdeu, Opcode::VCmpxGeF16}, {0xfdu, Opcode::VCmpxNeqF16}, {0xfeu, Opcode::VCmpxNltF16},
|
||||
{0xa2u, Opcode::VCmpEqI64}, {0xd1u, Opcode::VCmpxLtU32}, {0xd2u, Opcode::VCmpxEqU32},
|
||||
{0xd3u, Opcode::VCmpxLeU32}, {0xd4u, Opcode::VCmpxGtU32}, {0xd5u, Opcode::VCmpxNeU32},
|
||||
{0xd6u, Opcode::VCmpxGeU32}, {0xe5u, Opcode::VCmpNeU64}, {0xc9u, Opcode::VCmpLtF16},
|
||||
{0xcau, Opcode::VCmpEqF16}, {0xcbu, Opcode::VCmpLeF16}, {0xccu, Opcode::VCmpGtF16},
|
||||
{0xcdu, Opcode::VCmpLgF16}, {0xceu, Opcode::VCmpGeF16}, {0xedu, Opcode::VCmpNeqF16},
|
||||
{0xd9u, Opcode::VCmpxLtF16}, {0xdau, Opcode::VCmpxEqF16}, {0xdbu, Opcode::VCmpxLeF16},
|
||||
{0xdcu, Opcode::VCmpxGtF16}, {0xdeu, Opcode::VCmpxGeF16}, {0xfdu, Opcode::VCmpxNeqF16},
|
||||
{0xfeu, Opcode::VCmpxNltF16},
|
||||
};
|
||||
|
||||
constexpr OpcodeMap VOP3_OPS[] = {
|
||||
|
||||
@@ -1486,17 +1486,19 @@ void EmitBitCompareB32(EmitterState& state, const IR::Instruction& inst, bool bi
|
||||
EmitStoreU32(state, inst.dst, ret);
|
||||
}
|
||||
|
||||
void EmitCompareNeU64(EmitterState& state, const IR::Instruction& inst) {
|
||||
const auto lhs_low = EmitSequentialValueLoad(state, inst.src[0], 0);
|
||||
const auto lhs_high = EmitSequentialValueLoad(state, inst.src[0], 1);
|
||||
const auto rhs_low = EmitSequentialValueLoad(state, inst.src[1], 0);
|
||||
const auto rhs_high = EmitSequentialValueLoad(state, inst.src[1], 1);
|
||||
const auto ne_low = state.builder.AllocateId();
|
||||
const auto ne_high = state.builder.AllocateId();
|
||||
const auto cond = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpINotEqual, state.bool_type, ne_low, lhs_low, rhs_low});
|
||||
state.builder.AddFunction({OpINotEqual, state.bool_type, ne_high, lhs_high, rhs_high});
|
||||
state.builder.AddFunction({OpLogicalOr, state.bool_type, cond, ne_low, ne_high});
|
||||
void EmitCompareU64(EmitterState& state, const IR::Instruction& inst, bool equal) {
|
||||
const auto lhs_low = EmitSequentialValueLoad(state, inst.src[0], 0);
|
||||
const auto lhs_high = EmitSequentialValueLoad(state, inst.src[0], 1);
|
||||
const auto rhs_low = EmitSequentialValueLoad(state, inst.src[1], 0);
|
||||
const auto rhs_high = EmitSequentialValueLoad(state, inst.src[1], 1);
|
||||
const auto low = state.builder.AllocateId();
|
||||
const auto high = state.builder.AllocateId();
|
||||
const auto cond = state.builder.AllocateId();
|
||||
const auto compare_op = equal ? OpIEqual : OpINotEqual;
|
||||
state.builder.AddFunction({compare_op, state.bool_type, low, lhs_low, rhs_low});
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ void CollectRegisters(const IR::Program& program, std::vector<RegisterBinding>&
|
||||
if (inst.op == IR::Opcode::BitCountU64 || inst.op == IR::Opcode::FindMsbFromHighU64) {
|
||||
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[1], 2);
|
||||
}
|
||||
@@ -394,6 +394,7 @@ bool IsCompareOpcode(IR::Opcode op) {
|
||||
case IR::Opcode::CompareGeU32:
|
||||
case IR::Opcode::CompareLtU32:
|
||||
case IR::Opcode::CompareLeU32:
|
||||
case IR::Opcode::CompareEqU64:
|
||||
case IR::Opcode::CompareNeU64:
|
||||
case IR::Opcode::CompareMaskEqU32:
|
||||
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::CompareLtU32: EmitCompareU32(state, inst, OpULessThan); 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::CompareMaskNeU32: EmitCompareMaskU32(state, inst, OpINotEqual); 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 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);
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ enum class Opcode {
|
||||
CompareGeU32,
|
||||
CompareLtU32,
|
||||
CompareLeU32,
|
||||
CompareEqU64,
|
||||
CompareNeU64,
|
||||
CompareMaskEqU32,
|
||||
CompareMaskNeU32,
|
||||
|
||||
@@ -279,6 +279,7 @@ std::string InstructionToString(const Instruction& inst) {
|
||||
case Opcode::CompareGeU32: text += "CompareGeU32"; break;
|
||||
case Opcode::CompareLtU32: text += "CompareLtU32"; break;
|
||||
case Opcode::CompareLeU32: text += "CompareLeU32"; break;
|
||||
case Opcode::CompareEqU64: text += "CompareEqU64"; break;
|
||||
case Opcode::CompareNeU64: text += "CompareNeU64"; break;
|
||||
case Opcode::CompareMaskEqU32: text += "CompareMaskEqU32"; break;
|
||||
case Opcode::CompareMaskNeU32: text += "CompareMaskNeU32"; break;
|
||||
|
||||
@@ -325,6 +325,7 @@ constexpr LowerMap LOWER_OPS[] = {
|
||||
{Decoder::Opcode::VCmpNeU32, Opcode::CompareNeU32},
|
||||
{Decoder::Opcode::VCmpGeU32, Opcode::CompareGeU32},
|
||||
{Decoder::Opcode::VCmpTU32, Opcode::CompareTrue},
|
||||
{Decoder::Opcode::VCmpEqI64, Opcode::CompareEqU64},
|
||||
{Decoder::Opcode::VCmpNeU64, Opcode::CompareNeU64},
|
||||
{Decoder::Opcode::VCmpxLtU32, Opcode::CompareMaskLtU32},
|
||||
{Decoder::Opcode::VCmpxEqU32, Opcode::CompareMaskEqU32},
|
||||
|
||||
Reference in New Issue
Block a user