shader_recompiler/frontend: Implement bitcmp instructions (#1550)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions

This commit is contained in:
Daniel R. 2024-11-19 21:38:32 +01:00 committed by GitHub
parent c45af9a2ca
commit 17c47bcd96
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 52 additions and 0 deletions

View File

@ -132,6 +132,16 @@ void Translator::EmitSOPC(const GcnInst& inst) {
return S_CMP(ConditionOp::LT, false, inst); return S_CMP(ConditionOp::LT, false, inst);
case Opcode::S_CMP_LE_U32: case Opcode::S_CMP_LE_U32:
return S_CMP(ConditionOp::LE, false, inst); return S_CMP(ConditionOp::LE, false, inst);
case Opcode::S_BITCMP0_B32:
return S_BITCMP(false, 32, inst);
case Opcode::S_BITCMP1_B32:
return S_BITCMP(true, 32, inst);
case Opcode::S_BITCMP0_B64:
return S_BITCMP(false, 64, inst);
case Opcode::S_BITCMP1_B64:
return S_BITCMP(true, 64, inst);
default: default:
LogMissingOpcode(inst); LogMissingOpcode(inst);
} }
@ -615,4 +625,33 @@ void Translator::S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst) {
ir.SetScc(result); ir.SetScc(result);
} }
void Translator::S_BITCMP(bool compare_mode, u32 bits, const GcnInst& inst) {
const IR::U1 result = [&] {
const IR::U32 src0 = GetSrc(inst.src[0]);
const IR::U32 src1 = GetSrc(inst.src[1]);
IR::U32 mask;
switch (bits) {
case 32:
mask = ir.Imm32(0x1f);
break;
case 64:
mask = ir.Imm32(0x3f);
break;
default:
UNREACHABLE();
}
const IR::U32 bitpos{ir.BitwiseAnd(src1, mask)};
const IR::U32 bittest{ir.BitwiseAnd(ir.ShiftRightLogical(src0, bitpos), ir.Imm32(1))};
if (!compare_mode) {
return ir.IEqual(bittest, ir.Imm32(0));
} else {
return ir.IEqual(bittest, ir.Imm32(1));
}
}();
ir.SetScc(result);
}
} // namespace Shader::Gcn } // namespace Shader::Gcn

View File

@ -174,6 +174,13 @@ T Translator::GetSrc(const InstOperand& operand) {
value = ir.GetM0(); value = ir.GetM0();
} }
break; break;
case OperandField::Scc:
if constexpr (is_float) {
UNREACHABLE();
} else {
value = ir.BitCast<IR::U32>(ir.GetScc());
}
break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }

View File

@ -114,6 +114,7 @@ public:
// SOPC // SOPC
void S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst); void S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst);
void S_BITCMP(bool compare_mode, u32 bits, const GcnInst& inst);
// SOPP // SOPP
void S_BARRIER(); void S_BARRIER();

View File

@ -59,6 +59,11 @@ F64 IREmitter::Imm64(f64 value) const {
return F64{Value{value}}; return F64{Value{value}};
} }
template <>
IR::U32 IREmitter::BitCast<IR::U32, IR::U1>(const IR::U1& value) {
return IR::U32{Select(value, Imm32(1), Imm32(0))};
}
template <> template <>
IR::U32 IREmitter::BitCast<IR::U32, IR::F32>(const IR::F32& value) { IR::U32 IREmitter::BitCast<IR::U32, IR::F32>(const IR::F32& value) {
return Inst<IR::U32>(Opcode::BitCastU32F32, value); return Inst<IR::U32>(Opcode::BitCastU32F32, value);