mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 15:20:17 +01:00
nouveau/mme: add a macro exit helper
At the moment it's turing+ only. Signed-off-by: Karol Herbst <kherbst@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
parent
dc099bd808
commit
63bb25f87d
4 changed files with 124 additions and 0 deletions
|
|
@ -633,6 +633,39 @@ MME_DEF_END_WHILE(ine, EQ, false)
|
|||
for (bool run = (mme_start_while(b), true); run; \
|
||||
run = false, mme_end_while_##cmp((b), x, y))
|
||||
|
||||
#define MME_DEF_EXIT(op, OP, if_true) \
|
||||
static inline void \
|
||||
mme_exit_if_##op(struct mme_builder *b, \
|
||||
struct mme_value x, struct mme_value y) \
|
||||
{ \
|
||||
if (b->devinfo->cls_eng3d >= MME_CLS_TURING) \
|
||||
mme_tu104_exit_if(b, MME_CMP_OP_##OP, if_true, x, y); \
|
||||
else \
|
||||
unreachable("Unsupported GPU class"); \
|
||||
}
|
||||
|
||||
MME_DEF_EXIT(ilt, LT, true)
|
||||
MME_DEF_EXIT(ult, LTU, true)
|
||||
MME_DEF_EXIT(ile, LE, true)
|
||||
MME_DEF_EXIT(ule, LEU, true)
|
||||
MME_DEF_EXIT(ieq, EQ, true)
|
||||
MME_DEF_EXIT(ige, LT, false)
|
||||
MME_DEF_EXIT(uge, LTU, false)
|
||||
MME_DEF_EXIT(igt, LE, false)
|
||||
MME_DEF_EXIT(ugt, LEU, false)
|
||||
MME_DEF_EXIT(ine, EQ, false)
|
||||
|
||||
#undef MME_DEF_EXIT
|
||||
|
||||
#define mme_exit_if(b, cmp, x, y) \
|
||||
mme_exit_if_##cmp(b, x, y)
|
||||
|
||||
static inline void
|
||||
mme_exit(struct mme_builder *b)
|
||||
{
|
||||
mme_exit_if_ieq(b, mme_zero(), mme_zero());
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -688,6 +688,24 @@ mme_tu104_end_while(struct mme_builder *b,
|
|||
mme_tu104_new_inst(tb);
|
||||
}
|
||||
|
||||
void mme_tu104_exit_if(struct mme_builder *b,
|
||||
enum mme_cmp_op op,
|
||||
bool if_true,
|
||||
struct mme_value x,
|
||||
struct mme_value y)
|
||||
{
|
||||
struct mme_tu104_builder *tb = &b->tu104;
|
||||
|
||||
/* we reverse it as we want to take the branch if the condition is true */
|
||||
uint16_t control = if_true ? BITFIELD_BIT(15) : 0;
|
||||
/* magic offset to exit the macro */
|
||||
control |= 0x1000;
|
||||
build_alu_to(b, mme_zero(), mme_cmp_to_tu104_branch_op(op), x, y, control,
|
||||
true);
|
||||
|
||||
mme_tu104_new_inst(tb);
|
||||
}
|
||||
|
||||
uint32_t *
|
||||
mme_tu104_builder_finish(struct mme_tu104_builder *tb, size_t *size_out)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -85,6 +85,12 @@ void mme_tu104_end_while(struct mme_builder *b,
|
|||
struct mme_value x,
|
||||
struct mme_value y);
|
||||
|
||||
void mme_tu104_exit_if(struct mme_builder *b,
|
||||
enum mme_cmp_op op,
|
||||
bool if_true,
|
||||
struct mme_value x,
|
||||
struct mme_value y);
|
||||
|
||||
uint32_t *mme_tu104_builder_finish(struct mme_tu104_builder *b,
|
||||
size_t *size_out);
|
||||
|
||||
|
|
|
|||
|
|
@ -1200,6 +1200,73 @@ TEST_F(mme_tu104_sim_test, bxx_exit)
|
|||
ASSERT_EQ(data[i], 0);
|
||||
}
|
||||
|
||||
TEST_F(mme_tu104_sim_test, mme_exit)
|
||||
{
|
||||
mme_builder b;
|
||||
mme_builder_init(&b, devinfo);
|
||||
|
||||
mme_value vals[10];
|
||||
for (uint32_t i = 0; i < 10; i++)
|
||||
vals[i] = mme_mov(&b, mme_zero());
|
||||
|
||||
for (uint32_t i = 0; i < 10; i++)
|
||||
mme_store_imm_addr(&b, data_addr + i * 4, mme_imm(0));
|
||||
|
||||
/* abort */
|
||||
mme_exit(&b);
|
||||
|
||||
/* those writes won't be visible */
|
||||
for (uint32_t i = 0; i < 10; i++)
|
||||
vals[i] = mme_mov(&b, mme_imm(i));
|
||||
|
||||
for (uint32_t i = 0; i < 10; i++) {
|
||||
mme_store_imm_addr(&b, data_addr + i * 4, vals[i]);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> params;
|
||||
|
||||
auto macro = mme_builder_finish_vec(&b);
|
||||
test_macro(&b, macro, params);
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < 10; i++)
|
||||
ASSERT_EQ(data[i], 0);
|
||||
}
|
||||
|
||||
TEST_F(mme_tu104_sim_test, mme_exit_if)
|
||||
{
|
||||
mme_builder b;
|
||||
mme_builder_init(&b, devinfo);
|
||||
|
||||
mme_value vals[10];
|
||||
for (uint32_t i = 0; i < 10; i++)
|
||||
vals[i] = mme_mov(&b, mme_zero());
|
||||
|
||||
for (uint32_t i = 0; i < 10; i++)
|
||||
mme_store_imm_addr(&b, data_addr + i * 4, mme_imm(0));
|
||||
|
||||
/* shouldn't do anything */
|
||||
mme_exit_if(&b, ieq, mme_zero(), mme_imm(1));
|
||||
|
||||
for (uint32_t i = 0; i < 10; i++)
|
||||
vals[i] = mme_mov(&b, mme_imm(i));
|
||||
|
||||
for (uint32_t i = 0; i < 10; i++) {
|
||||
/* abort on reaching 5 */
|
||||
mme_exit_if(&b, ile, mme_imm(5), vals[i]);
|
||||
mme_store_imm_addr(&b, data_addr + i * 4, vals[i]);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> params;
|
||||
|
||||
auto macro = mme_builder_finish_vec(&b);
|
||||
test_macro(&b, macro, params);
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < 10; i++)
|
||||
ASSERT_EQ(data[i], i < 5 ? i : 0);
|
||||
}
|
||||
|
||||
static bool c_ilt(int32_t x, int32_t y) { return x < y; };
|
||||
static bool c_ult(uint32_t x, uint32_t y) { return x < y; };
|
||||
static bool c_ile(int32_t x, int32_t y) { return x <= y; };
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue