shader: implement s_bfe_i32

This commit is contained in:
nmzik committed 2026-08-18 03:53:42 +02:00
1 parent b4809e7170
commit 7556a74f19
8 files changed
+60 -6

No files matched your search

@@ -20,10 +20,10 @@ constexpr OpcodeMap SOP2_OPCODE_LIST[] = {
{0x1du, Opcode::SXnorB64}, {0x1eu, Opcode::SLshlB32}, {0x1fu, Opcode::SLshlB64},
{0x20u, Opcode::SLshrB32}, {0x21u, Opcode::SLshrB64}, {0x22u, Opcode::SAshrI32},
{0x24u, Opcode::SBfmB32}, {0x25u, Opcode::SBfmB64}, {0x26u, Opcode::SMulI32},
{0x27u, Opcode::SBfeU32}, {0x29u, Opcode::SBfeU64}, {0x2eu, Opcode::SLshl1AddU32},
{0x2fu, Opcode::SLshl2AddU32}, {0x30u, Opcode::SLshl3AddU32}, {0x31u, Opcode::SLshl4AddU32},
{0x32u, Opcode::SPackLlB32B16}, {0x33u, Opcode::SPackLhB32B16}, {0x34u, Opcode::SPackHhB32B16},
{0x35u, Opcode::SMulHiU32},
{0x27u, Opcode::SBfeU32}, {0x28u, Opcode::SBfeI32}, {0x29u, Opcode::SBfeU64},
{0x2eu, Opcode::SLshl1AddU32}, {0x2fu, Opcode::SLshl2AddU32}, {0x30u, Opcode::SLshl3AddU32},
{0x31u, Opcode::SLshl4AddU32}, {0x32u, Opcode::SPackLlB32B16}, {0x33u, Opcode::SPackLhB32B16},
{0x34u, Opcode::SPackHhB32B16}, {0x35u, Opcode::SMulHiU32},
};
constexpr OpcodeMap SOP1_OPCODE_LIST[] = {
@@ -516,6 +516,7 @@ std::string OpcodeToString(Opcode opcode) {
case Opcode::SMulHiU32: return "s_mul_hi_u32";
case Opcode::SMulkI32: return "s_mulk_i32";
case Opcode::SBfeU32: return "s_bfe_u32";
case Opcode::SBfeI32: return "s_bfe_i32";
case Opcode::SBfeU64: return "s_bfe_u64";
case Opcode::SBfmB32: return "s_bfm_b32";
case Opcode::SBfmB64: return "s_bfm_b64";
@@ -100,6 +100,7 @@ enum class Opcode {
SMulHiU32,
SMulkI32,
SBfeU32,
SBfeI32,
SBfeU64,
SBfmB32,
SBfmB64,
@@ -515,14 +515,18 @@ bool Translator::TranslateExtendedInteger(const IR::Instruction& inst) {
result = ir.Emit(IR::ValueOpcode::ShiftLeftLogical64, {right_mask64(count), offset});
break;
}
case IR::Opcode::BitFieldExtractU32: {
case IR::Opcode::BitFieldExtractU32:
case IR::Opcode::BitFieldExtractI32: {
const auto source = ReadU32(inst.src[0]);
const auto field = ReadU32(inst.src[1]);
const auto offset = extract(field, imm(0), imm(5), false);
const auto count =
IR::U32(ir.Emit(IR::ValueOpcode::UMin32, {extract(field, imm(16), imm(7), false),
ir.ISub(imm(32), offset)}));
result = ir.Emit(IR::ValueOpcode::BitFieldUExtract, {source, offset, count});
const auto opcode = inst.op == IR::Opcode::BitFieldExtractI32
? IR::ValueOpcode::BitFieldSExtract
: IR::ValueOpcode::BitFieldUExtract;
result = ir.Emit(opcode, {source, offset, count});
break;
}
case IR::Opcode::BitFieldExtractU64: {