Merge pull request #70 from SamG-Coder/main

fix(shader): support scalar bit operations and 64-bit SAVEEXEC
This commit is contained in:
boykopovar 2026-09-28 11:57:56 +03:00 committed by GitHub
commit cdc95d9a70
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 50 additions and 0 deletions

View File

@ -114,14 +114,17 @@ enum class RdnaOpcode : std::uint16_t {
ExpParam,
Unknown,
Unsupported,
SCmovB32,
SCmovB64,
SAbsI32,
SAbsdiffI32,
SBrevB32,
SSextI32I8,
SSextI32I16,
SBcnt0I32B32,
SBcnt1I32B32,
SBcnt1I32B64,
SFf0I32B32,
SFf1I32B32,
SFf1I32B64,
SFlbitI32B32,
@ -135,6 +138,9 @@ enum class RdnaOpcode : std::uint16_t {
SOrn2SaveexecB32,
SAndn1SaveexecB32,
SAndSaveexecB64,
SOrSaveexecB64,
SXorSaveexecB64,
SAndn2SaveexecB64,
SOrn2SaveexecB64,
SAndn1SaveexecB64,
SNotB32,

View File

@ -36,14 +36,17 @@ bool IsScalarAluOpcode(RdnaOpcode opcode) {
case RdnaOpcode::SCmpLtI32:
case RdnaOpcode::SCmpGtI32:
case RdnaOpcode::SCmpEqU32:
case RdnaOpcode::SCmovB32:
case RdnaOpcode::SCmovB64:
case RdnaOpcode::SAbsI32:
case RdnaOpcode::SAbsdiffI32:
case RdnaOpcode::SBrevB32:
case RdnaOpcode::SSextI32I8:
case RdnaOpcode::SSextI32I16:
case RdnaOpcode::SBcnt0I32B32:
case RdnaOpcode::SBcnt1I32B32:
case RdnaOpcode::SBcnt1I32B64:
case RdnaOpcode::SFf0I32B32:
case RdnaOpcode::SFf1I32B32:
case RdnaOpcode::SFf1I32B64:
case RdnaOpcode::SFlbitI32B32:
@ -54,6 +57,9 @@ bool IsScalarAluOpcode(RdnaOpcode opcode) {
case RdnaOpcode::SOrn2SaveexecB32:
case RdnaOpcode::SAndn1SaveexecB32:
case RdnaOpcode::SAndSaveexecB64:
case RdnaOpcode::SOrSaveexecB64:
case RdnaOpcode::SXorSaveexecB64:
case RdnaOpcode::SAndn2SaveexecB64:
case RdnaOpcode::SOrn2SaveexecB64:
case RdnaOpcode::SAndn1SaveexecB64:
case RdnaOpcode::SNotB32:

View File

@ -11,14 +11,17 @@ RdnaOpcode decodeSop1Opcode(std::uint32_t opcode) {
switch (opcode) {
case 0x03u: return RdnaOpcode::SMovB32;
case 0x04u: return RdnaOpcode::SMovB64;
case 0x05u: return RdnaOpcode::SCmovB32;
case 0x06u: return RdnaOpcode::SCmovB64;
case 0x07u: return RdnaOpcode::SNotB32;
case 0x08u: return RdnaOpcode::SNotB64;
case 0x09u: return RdnaOpcode::SWqmB32;
case 0x0au: return RdnaOpcode::SWqmB64;
case 0x0bu: return RdnaOpcode::SBrevB32;
case 0x0du: return RdnaOpcode::SBcnt0I32B32;
case 0x0fu: return RdnaOpcode::SBcnt1I32B32;
case 0x10u: return RdnaOpcode::SBcnt1I32B64;
case 0x11u: return RdnaOpcode::SFf0I32B32;
case 0x13u: return RdnaOpcode::SFf1I32B32;
case 0x14u: return RdnaOpcode::SFf1I32B64;
case 0x15u: return RdnaOpcode::SFlbitI32B32;
@ -32,6 +35,9 @@ RdnaOpcode decodeSop1Opcode(std::uint32_t opcode) {
case 0x1fu: return RdnaOpcode::SGetpcB64;
case 0x20u: return RdnaOpcode::SSetpcB64;
case 0x24u: return RdnaOpcode::SAndSaveexecB64;
case 0x25u: return RdnaOpcode::SOrSaveexecB64;
case 0x26u: return RdnaOpcode::SXorSaveexecB64;
case 0x27u: return RdnaOpcode::SAndn2SaveexecB64;
case 0x28u: return RdnaOpcode::SOrn2SaveexecB64;
case 0x2du: return RdnaOpcode::SQuadmaskB64;
case 0x34u: return RdnaOpcode::SAbsI32;
@ -196,6 +202,9 @@ std::uint32_t scalarDestinationDwordCount(RdnaOpcode opcode) {
case RdnaOpcode::SBitset1B64:
case RdnaOpcode::SGetpcB64:
case RdnaOpcode::SAndSaveexecB64:
case RdnaOpcode::SOrSaveexecB64:
case RdnaOpcode::SXorSaveexecB64:
case RdnaOpcode::SAndn2SaveexecB64:
case RdnaOpcode::SOrn2SaveexecB64:
case RdnaOpcode::SQuadmaskB64:
case RdnaOpcode::SAndn1SaveexecB64:

View File

@ -28,6 +28,7 @@ void TranslationContext::sSaveexec(const RdnaInstruction& inst, IrOpcode operati
// Callers name the lane-wise operation; the exec mask words themselves combine bitwise.
if (operation == IrOpcode::LogicalAnd) operation = IrOpcode::BitwiseAnd32;
else if (operation == IrOpcode::LogicalOr) operation = IrOpcode::BitwiseOr32;
else if (operation == IrOpcode::LogicalXor) operation = IrOpcode::BitwiseXor32;
const bool writeFirst = SaveexecWritesDestinationFirst();
if (write64) {
const std::array<IrU32, 2> oldExec{IrU32(ir.GetExecLo()), IrU32(ir.GetExecHi())};

View File

@ -40,6 +40,13 @@ bool TranslationContext::emitScalar(const RdnaInstruction& inst) {
case RdnaOpcode::SCselectB64:
scalarSelect64(inst, sourceAt(inst, 1u));
return true;
case RdnaOpcode::SCmovB32: {
const IrU32 source = readU32(sourceAt(inst, 0u));
const IrU32 previous = readU32(inst.destination);
const IrU32 result(ir.Select(ir.GetScc(), source.Value(), previous.Value()));
writeRawU32(inst.destination, result);
return true;
}
case RdnaOpcode::SCmovB64:
scalarSelect64(inst, inst.destination);
return true;
@ -61,6 +68,15 @@ bool TranslationContext::emitScalar(const RdnaInstruction& inst) {
case RdnaOpcode::SAndSaveexecB64:
sSaveexec(inst, IrOpcode::LogicalAnd, false, false, true);
return true;
case RdnaOpcode::SOrSaveexecB64:
sSaveexec(inst, IrOpcode::LogicalOr, false, false, true);
return true;
case RdnaOpcode::SXorSaveexecB64:
sSaveexec(inst, IrOpcode::LogicalXor, false, false, true);
return true;
case RdnaOpcode::SAndn2SaveexecB64:
sSaveexec(inst, IrOpcode::LogicalAnd, true, false, true);
return true;
case RdnaOpcode::SAndn1SaveexecB64:
sSaveexec(inst, IrOpcode::LogicalAnd, false, true, true);
return true;
@ -195,6 +211,18 @@ bool TranslationContext::emitScalar(const RdnaInstruction& inst) {
writeOperand(inst.destination, &result);
return true;
}
case RdnaOpcode::SBcnt0I32B32:
case RdnaOpcode::SFf0I32B32: {
const IrU32 source = readU32(sourceAt(inst, 0u));
auto& inverted = ir.BitwiseNot(source.Value());
const bool count = inst.op == RdnaOpcode::SBcnt0I32B32;
auto& result = ir.Emit(count ? IrOpcode::BitCount32 : IrOpcode::FindILsb32, IrType::U32, {&inverted});
writeOperand(inst.destination, &result);
if (count) {
ir.SetScc(ir.INotEqual(result, ir.Constant(0u)));
}
return true;
}
case RdnaOpcode::SBcnt1I32B32:
return simpleInteger(inst, IrOpcode::BitCount32, IrType::U32, false, false, true);
case RdnaOpcode::SBcnt1I32B64: