nouveau/mme: Add NOT and AND_NOT ops

Fermi has AND_NOT natively and NOT is just AND_NOT(0, x).

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30703>
This commit is contained in:
Faith Ekstrand 2024-08-15 10:08:56 -05:00 committed by Marge Bot
parent da96084392
commit c218bd798f
6 changed files with 136 additions and 2 deletions

View file

@ -28,7 +28,9 @@ enum mme_alu_op {
MME_ALU_OP_SLL,
MME_ALU_OP_SRL,
MME_ALU_OP_SRA,
MME_ALU_OP_NOT,
MME_ALU_OP_AND,
MME_ALU_OP_AND_NOT,
MME_ALU_OP_NAND,
MME_ALU_OP_OR,
MME_ALU_OP_XOR,
@ -248,7 +250,9 @@ MME_DEF_ALU1(clz, CLZ);
MME_DEF_ALU2(sll, SLL);
MME_DEF_ALU2(srl, SRL);
MME_DEF_ALU2(sra, SRA);
MME_DEF_ALU1(not, NOT);
MME_DEF_ALU2(and, AND);
MME_DEF_ALU2(and_not,AND_NOT);
MME_DEF_ALU2(nand, NAND);
MME_DEF_ALU2(or, OR);
MME_DEF_ALU2(xor, XOR);

View file

@ -689,6 +689,7 @@ mme_to_fermi_alu_op(enum mme_alu_op op)
ALU_CASE(SUB)
ALU_CASE(SUBB)
ALU_CASE(AND)
ALU_CASE(AND_NOT)
ALU_CASE(NAND)
ALU_CASE(OR)
ALU_CASE(XOR)
@ -742,6 +743,9 @@ mme_fermi_build_alu(struct mme_builder *b,
case MME_ALU_OP_SRL:
mme_fermi_srl_to(fb, dst, x, y);
return;
case MME_ALU_OP_NOT:
mme_and_not_to(b, dst, mme_imm(~(uint32_t)0), x);
return;
default:
break;
}

View file

@ -340,7 +340,43 @@ mme_tu104_alu_to(struct mme_builder *b,
struct mme_value x,
struct mme_value y)
{
build_alu_to(b, dst, mme_to_tu104_alu_op(op), x, y, 0, false);
switch (op) {
case MME_ALU_OP_NOT:
mme_xor_to(b, dst, x, mme_imm(~(uint32_t)0));
break;
case MME_ALU_OP_AND_NOT: {
struct mme_value not_y;
switch (y.type) {
case MME_VALUE_TYPE_ZERO:
not_y = mme_imm(~(uint32_t)0);
break;
case MME_VALUE_TYPE_IMM:
if (y.imm == ~(uint32_t)0)
not_y = mme_zero();
else
not_y = mme_imm(~y.imm);
break;
case MME_VALUE_TYPE_REG:
not_y = mme_not(b, y);
break;
default:
unreachable("Unknown MME value type");
}
mme_and_to(b, dst, x, not_y);
if (not_y.type == MME_VALUE_TYPE_REG)
mme_free_reg(b, not_y);
break;
}
default:
build_alu_to(b, dst, mme_to_tu104_alu_op(op), x, y, 0, false);
}
}
void

View file

@ -335,6 +335,61 @@ TEST_F(mme_builder_test, sll_srl)
}
}
TEST_F(mme_builder_test, not)
{
static const uint32_t x = 0xac406fe1;
for (auto sim : sims) {
mme_builder b;
mme_builder_init(&b, sim->devinfo);
mme_value xv = mme_load(&b);
sim->mme_store_data(&b, 0, mme_not(&b, xv));
auto macro = mme_builder_finish_vec(&b);
/* Fermi can't shift by 0 */
for (uint32_t i = 1; i < 31; i++) {
std::vector<uint32_t> params;
params.push_back(x);
sim->run_macro(macro, params);
ASSERT_EQ(sim->data[0], ~x);
}
}
}
TEST_F(mme_builder_test, and_not)
{
static const uint32_t x = 0xac406fe1;
static const uint32_t y = 0x00fff0c0;
for (auto sim : sims) {
mme_builder b;
mme_builder_init(&b, sim->devinfo);
mme_value xv = mme_load(&b);
mme_value yv = mme_load(&b);
sim->mme_store_data(&b, 0, mme_and(&b, xv, yv));
sim->mme_store_data(&b, 1, mme_and_not(&b, xv, yv));
auto macro = mme_builder_finish_vec(&b);
/* Fermi can't shift by 0 */
for (uint32_t i = 1; i < 31; i++) {
std::vector<uint32_t> params;
params.push_back(x);
params.push_back(y);
sim->run_macro(macro, params);
ASSERT_EQ(sim->data[0], x & y);
ASSERT_EQ(sim->data[1], x & ~y);
}
}
}
TEST_F(mme_builder_test, merge)
{
static const struct {

View file

@ -478,6 +478,23 @@ TEST_F(mme_fermi_sim_test, bfe)
}
}
TEST_F(mme_fermi_sim_test, not)
{
mme_builder b;
mme_builder_init(&b, devinfo);
mme_value x = mme_load(&b);
mme_value v1 = mme_not(&b, x);
mme_store_imm_addr(&b, data_addr + 0, v1, true);
auto macro = mme_builder_finish_vec(&b);
std::vector<uint32_t> params;
params.push_back(0x0c406fe0);
test_macro(&b, macro, params);
}
#define BITOP_TEST(op) \
TEST_F(mme_fermi_sim_test, op) \
{ \
@ -503,7 +520,7 @@ TEST_F(mme_fermi_sim_test, op) \
}
BITOP_TEST(and)
//BITOP_TEST(and_not)
BITOP_TEST(and_not)
BITOP_TEST(nand)
BITOP_TEST(or)
BITOP_TEST(xor)

View file

@ -909,6 +909,23 @@ TEST_F(mme_tu104_sim_test, bfe)
}
}
TEST_F(mme_tu104_sim_test, not)
{
mme_builder b;
mme_builder_init(&b, devinfo);
mme_value x = mme_load(&b);
mme_value v1 = mme_not(&b, x);
mme_store_imm_addr(&b, data_addr + 0, v1);
auto macro = mme_builder_finish_vec(&b);
std::vector<uint32_t> params;
params.push_back(0x0c406fe0);
test_macro(&b, macro, params);
}
#define BITOP_TEST(op) \
TEST_F(mme_tu104_sim_test, op) \
{ \
@ -934,6 +951,7 @@ TEST_F(mme_tu104_sim_test, op) \
}
BITOP_TEST(and)
BITOP_TEST(and_not)
BITOP_TEST(nand)
BITOP_TEST(or)
BITOP_TEST(xor)