nouveau/mme: Add a bfe helper

This extracts a fixed number of bits from a possibly variable position
in the source value.  Very helpful for testing for a bit.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
Faith Ekstrand 2023-03-17 13:29:34 -05:00 committed by Marge Bot
parent b0658acf17
commit 37505e9bba
5 changed files with 95 additions and 0 deletions

View file

@ -342,6 +342,29 @@ mme_mul64(struct mme_builder *b,
return dst;
}
static inline void
mme_bfe_to(struct mme_builder *b, struct mme_value dst,
struct mme_value x, struct mme_value pos, uint8_t bits)
{
if (b->devinfo->cls_eng3d >= MME_CLS_TURING) {
mme_srl_to(b, dst, x, pos);
mme_and_to(b, dst, dst, mme_imm(BITFIELD_MASK(bits)));
} else if (b->devinfo->cls_eng3d >= MME_CLS_FERMI) {
mme_fermi_bfe_to(b, dst, x, pos, bits);
} else {
unreachable("Unsupported GPU class");
}
}
static inline struct mme_value
mme_bfe(struct mme_builder *b,
struct mme_value x, struct mme_value pos, uint8_t bits)
{
struct mme_value dst = mme_alloc_reg(b);
mme_bfe_to(b, dst, x, pos, bits);
return dst;
}
static inline void
mme_merge_to(struct mme_builder *b, struct mme_value dst,
struct mme_value x, struct mme_value y,

View file

@ -309,6 +309,16 @@ mme_fermi_srl_to(struct mme_fermi_builder *b,
mme_fermi_bfe(b, dst, y, x, mme_zero(), 31);
}
void
mme_fermi_bfe_to(struct mme_builder *b, struct mme_value dst,
struct mme_value x, struct mme_value pos, uint8_t bits)
{
struct mme_fermi_builder *fb = &b->fermi;
assert(mme_fermi_is_zero_or_reg(dst));
mme_fermi_bfe(fb, dst, pos, x, mme_zero(), bits);
}
static struct mme_value
mme_fermi_load_imm_to_reg(struct mme_builder *b, struct mme_value data)
{

View file

@ -101,6 +101,10 @@ mme_fermi_alu64_to(struct mme_builder *b,
mme_fermi_alu_to(b, dst.hi, op_hi, x.hi, y.hi);
}
void
mme_fermi_bfe_to(struct mme_builder *b, struct mme_value dst,
struct mme_value x, struct mme_value pos, uint8_t bits);
void
mme_fermi_merge_to(struct mme_builder *b, struct mme_value dst,
struct mme_value x, struct mme_value y,

View file

@ -357,6 +357,35 @@ SHIFT_TEST(srl)
#undef SHIFT_TEST
TEST_F(mme_fermi_sim_test, bfe)
{
const uint32_t canary = 0xc0ffee01;
mme_builder b;
mme_builder_init(&b, devinfo);
mme_value val = mme_load(&b);
mme_value pos = mme_load(&b);
mme_store_imm_addr(&b, data_addr + 0, mme_bfe(&b, val, pos, 1), true);
mme_store_imm_addr(&b, data_addr + 4, mme_bfe(&b, val, pos, 2), true);
mme_store_imm_addr(&b, data_addr + 8, mme_bfe(&b, val, pos, 5), true);
auto macro = mme_builder_finish_vec(&b);
for (unsigned i = 0; i < 31; i++) {
std::vector<uint32_t> params;
params.push_back(canary);
params.push_back(i);
test_macro(&b, macro, params);
ASSERT_EQ(data[0], (canary >> i) & 0x1);
ASSERT_EQ(data[1], (canary >> i) & 0x3);
ASSERT_EQ(data[2], (canary >> i) & 0x1f);
}
}
#define BITOP_TEST(op) \
TEST_F(mme_fermi_sim_test, op) \
{ \

View file

@ -876,6 +876,35 @@ SHIFT_TEST(sra)
#undef SHIFT_TEST
TEST_F(mme_tu104_sim_test, bfe)
{
const uint32_t canary = 0xc0ffee01;
mme_builder b;
mme_builder_init(&b, devinfo);
mme_value val = mme_load(&b);
mme_value pos = mme_load(&b);
mme_store_imm_addr(&b, data_addr + 0, mme_bfe(&b, val, pos, 1), true);
mme_store_imm_addr(&b, data_addr + 4, mme_bfe(&b, val, pos, 2), true);
mme_store_imm_addr(&b, data_addr + 8, mme_bfe(&b, val, pos, 5), true);
auto macro = mme_builder_finish_vec(&b);
for (unsigned i = 0; i < 31; i++) {
std::vector<uint32_t> params;
params.push_back(canary);
params.push_back(i);
test_macro(&b, macro, params);
ASSERT_EQ(data[0], (canary >> i) & 0x1);
ASSERT_EQ(data[1], (canary >> i) & 0x3);
ASSERT_EQ(data[2], (canary >> i) & 0x1f);
}
}
#define BITOP_TEST(op) \
TEST_F(mme_tu104_sim_test, op) \
{ \