Merge pull request #152 from Digote/feat/shader-s-bitcmp-b64

feat(shader): support 64-bit scalar bit compare
This commit is contained in:
boykopovar 2026-09-30 19:25:12 +03:00 committed by GitHub
commit c09b8759b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 20 additions and 0 deletions

View File

@ -153,6 +153,8 @@ enum class RdnaOpcode : std::uint16_t {
SSubbU32,
SBitcmp0B32,
SBitcmp1B32,
SBitcmp0B64,
SBitcmp1B64,
SBitset0B32,
SBitset1B32,
SBitset0B64,

View File

@ -72,6 +72,8 @@ bool IsScalarAluOpcode(RdnaOpcode opcode) {
case RdnaOpcode::SSubbU32:
case RdnaOpcode::SBitcmp0B32:
case RdnaOpcode::SBitcmp1B32:
case RdnaOpcode::SBitcmp0B64:
case RdnaOpcode::SBitcmp1B64:
case RdnaOpcode::SBitset0B32:
case RdnaOpcode::SBitset1B32:
case RdnaOpcode::SBitset0B64:

View File

@ -123,6 +123,8 @@ RdnaOpcode decodeSopcOpcode(std::uint32_t opcode) {
case 0x0bu: return RdnaOpcode::SCmpLeU32;
case 0x0cu: return RdnaOpcode::SBitcmp0B32;
case 0x0du: return RdnaOpcode::SBitcmp1B32;
case 0x0eu: return RdnaOpcode::SBitcmp0B64;
case 0x0fu: return RdnaOpcode::SBitcmp1B64;
case 0x12u: return RdnaOpcode::SCmpEqU64;
case 0x13u: return RdnaOpcode::SCmpLgU64;
default: throw std::invalid_argument("unsupported SOPC opcode " + std::to_string(opcode));

View File

@ -184,6 +184,7 @@ private:
bool vBfeU32(const RdnaInstruction& inst, bool sign);
bool vBfiB32(const RdnaInstruction& inst);
bool sBitcmpB32(const RdnaInstruction& inst, bool expected);
bool sBitcmpB64(const RdnaInstruction& inst, bool expected);
bool vAlignbitB32(const RdnaInstruction& inst);
bool vAlignbyteB32(const RdnaInstruction& inst);
bool vLshlAddU32(const RdnaInstruction& inst);

View File

@ -484,6 +484,15 @@ bool TranslationContext::sBitcmpB32(const RdnaInstruction& inst, bool expected)
return true;
}
bool TranslationContext::sBitcmpB64(const RdnaInstruction& inst, bool expected) {
const IrU64 value = readU64(sourceAt(inst, 0u));
const IrU32 offset(ir.BitwiseAnd(readU32(sourceAt(inst, 1u)).Value(), ir.Constant(63u)));
const IrU64 shifted(ir.Emit(IrOpcode::ShiftRightLogical64, IrType::U64, {&value.Value(), &offset.Value()}));
const IrU64 bit(ir.Emit(IrOpcode::BitwiseAnd64, IrType::U64, {&shifted.Value(), &ir.ConstantU64(1u)}));
writeCompareResult(inst.destination, IrU1(ir.Emit(IrOpcode::IEqual64, IrType::U1, {&bit.Value(), &ir.ConstantU64(expected ? 1u : 0u)})));
return true;
}
bool TranslationContext::vAlignbitB32(const RdnaInstruction& inst) {
const IrU32 hi = readU32(sourceAt(inst, 0u));
const IrU32 lo = readU32(sourceAt(inst, 1u));

View File

@ -290,6 +290,10 @@ bool TranslationContext::emitScalar(const RdnaInstruction& inst) {
return sBitcmpB32(inst, false);
case RdnaOpcode::SBitcmp1B32:
return sBitcmpB32(inst, true);
case RdnaOpcode::SBitcmp0B64:
return sBitcmpB64(inst, false);
case RdnaOpcode::SBitcmp1B64:
return sBitcmpB64(inst, true);
case RdnaOpcode::SPackLlB32B16:
return packB16(inst, false, false);
case RdnaOpcode::SPackLhB32B16: