mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
shader: implement S_ORN2_SAVEEXEC_B32
This commit is contained in:
@@ -62,6 +62,7 @@ constexpr OpcodeMap SOP1_OPCODE_LIST[] = {
|
||||
{0x37u, Opcode::S_ANDN1_SAVEEXEC_B64},
|
||||
{0x3bu, Opcode::S_BITREPLICATE_B64_B32},
|
||||
{0x3cu, Opcode::S_AND_SAVEEXEC_B32},
|
||||
{0x40u, Opcode::S_ORN2_SAVEEXEC_B32},
|
||||
{0x44u, Opcode::S_ANDN1_SAVEEXEC_B32},
|
||||
};
|
||||
|
||||
|
||||
@@ -485,6 +485,7 @@ std::string InstructionToString(const Instruction& inst) {
|
||||
case Opcode::S_WQM_B64:
|
||||
case Opcode::S_QUADMASK_B64:
|
||||
case Opcode::S_AND_SAVEEXEC_B32:
|
||||
case Opcode::S_ORN2_SAVEEXEC_B32:
|
||||
case Opcode::S_ANDN1_SAVEEXEC_B32:
|
||||
case Opcode::S_AND_SAVEEXEC_B64:
|
||||
case Opcode::S_ORN2_SAVEEXEC_B64:
|
||||
|
||||
@@ -54,6 +54,7 @@ enum class Opcode {
|
||||
S_GETPC_B64,
|
||||
S_SETPC_B64,
|
||||
S_AND_SAVEEXEC_B32,
|
||||
S_ORN2_SAVEEXEC_B32,
|
||||
S_ANDN1_SAVEEXEC_B32,
|
||||
S_AND_SAVEEXEC_B64,
|
||||
S_ORN2_SAVEEXEC_B64,
|
||||
|
||||
@@ -24,27 +24,34 @@ Decoder::Operand ConditionOperand(Decoder::OperandKind kind) {
|
||||
|
||||
void Translator::S_SAVEEXEC(const Decoder::Instruction& inst, IR::ValueOpcode operation,
|
||||
bool negate_exec, bool negate_source, bool write_64) {
|
||||
if (!write_64) {
|
||||
// Read the encoded scalar word and preserve EXEC_HI, including in wave32.
|
||||
const auto old = ir.GetExecLo();
|
||||
const auto src = ReadU32(inst.src0);
|
||||
const auto lhs = negate_exec ? ir.BitwiseNot(old) : old;
|
||||
const auto rhs = negate_source ? ir.BitwiseNot(src) : src;
|
||||
IR::U32 result;
|
||||
switch (operation) {
|
||||
case IR::ValueOpcode::LogicalAnd: result = ir.BitwiseAnd(lhs, rhs); break;
|
||||
case IR::ValueOpcode::LogicalOr: result = ir.BitwiseOr(lhs, rhs); break;
|
||||
default: EXIT("unsupported SAVEEXEC operation");
|
||||
}
|
||||
WriteRawU32(inst.dst, old);
|
||||
WriteRawU32(ConditionOperand(Decoder::OperandKind::ExecLo), result);
|
||||
ir.SetScc(ir.INotEqual(result, IR::U32(IR::Value(0u))));
|
||||
return;
|
||||
}
|
||||
const auto old = ir.GetExec();
|
||||
const auto src = ReadMask(inst.src0);
|
||||
const auto lhs = negate_exec ? ir.LogicalNot(old) : old;
|
||||
const auto rhs = negate_source ? ir.LogicalNot(src) : src;
|
||||
auto result = IR::U1(ir.Emit(operation, {lhs, rhs}));
|
||||
if (write_64) {
|
||||
WriteMask(inst.dst, old, true);
|
||||
} else {
|
||||
WriteRawU32(inst.dst, ir.GetExecLo());
|
||||
if (program.wave_size == 64u) {
|
||||
const auto low_half =
|
||||
ir.ULessThan(IR::U32(ir.Emit(IR::ValueOpcode::LaneId)), IR::U32(IR::Value(32u)));
|
||||
result = IR::U1(ir.Emit(IR::ValueOpcode::SelectU1, {low_half, result, old}));
|
||||
}
|
||||
}
|
||||
const auto result = IR::U1(ir.Emit(operation, {lhs, rhs}));
|
||||
WriteMask(inst.dst, old, true);
|
||||
const auto mask = BallotMask(result);
|
||||
ir.SetExec(result);
|
||||
ir.SetExecLo(mask[0]);
|
||||
ir.SetExecHi(mask[1]);
|
||||
ir.SetScc(
|
||||
ir.INotEqual(write_64 ? ir.BitwiseOr(mask[0], mask[1]) : mask[0], IR::U32(IR::Value(0u))));
|
||||
ir.SetScc(ir.INotEqual(ir.BitwiseOr(mask[0], mask[1]), IR::U32(IR::Value(0u))));
|
||||
}
|
||||
|
||||
void Translator::ADD_U32(const Decoder::Instruction& inst, bool vector, bool use_carry_in) {
|
||||
|
||||
@@ -23,6 +23,9 @@ bool Translator::EmitScalar(const Decoder::Instruction& inst) {
|
||||
case O::S_ANDN1_SAVEEXEC_B32:
|
||||
S_SAVEEXEC(inst, IR::ValueOpcode::LogicalAnd, false, true, false);
|
||||
return true;
|
||||
case O::S_ORN2_SAVEEXEC_B32:
|
||||
S_SAVEEXEC(inst, IR::ValueOpcode::LogicalOr, true, false, false);
|
||||
return true;
|
||||
case O::S_AND_SAVEEXEC_B64:
|
||||
S_SAVEEXEC(inst, IR::ValueOpcode::LogicalAnd, false, false, true);
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user