diff --git a/src/nouveau/mme/mme_fermi_builder.c b/src/nouveau/mme/mme_fermi_builder.c index c5d9092ceda..6bf9395f840 100644 --- a/src/nouveau/mme/mme_fermi_builder.c +++ b/src/nouveau/mme/mme_fermi_builder.c @@ -292,25 +292,39 @@ mme_fermi_bfe(struct mme_fermi_builder *fb, } static void -mme_fermi_sll_to(struct mme_fermi_builder *b, +mme_fermi_sll_to(struct mme_builder *b, struct mme_value dst, struct mme_value x, struct mme_value y) { + struct mme_fermi_builder *fb = &b->fermi; assert(mme_fermi_is_zero_or_reg(dst)); - mme_fermi_bfe(b, dst, mme_zero(), x, y, 31); + if (x.type == MME_VALUE_TYPE_REG) { + mme_fermi_bfe(fb, dst, mme_zero(), x, y, 31); + } else { + assert(y.type != MME_VALUE_TYPE_REG || y.reg != dst.reg); + mme_mov_to(b, dst, x); + mme_fermi_bfe(fb, dst, mme_zero(), dst, y, 31); + } } static void -mme_fermi_srl_to(struct mme_fermi_builder *b, +mme_fermi_srl_to(struct mme_builder *b, struct mme_value dst, struct mme_value x, struct mme_value y) { + struct mme_fermi_builder *fb = &b->fermi; assert(mme_fermi_is_zero_or_reg(dst)); - mme_fermi_bfe(b, dst, y, x, mme_zero(), 31); + if (x.type == MME_VALUE_TYPE_REG) { + mme_fermi_bfe(fb, dst, y, x, mme_zero(), 31); + } else { + assert(y.type != MME_VALUE_TYPE_REG || y.reg != dst.reg); + mme_mov_to(b, dst, x); + mme_fermi_bfe(fb, dst, y, dst, mme_zero(), 31); + } } void @@ -388,7 +402,7 @@ mme_fermi_load_imm_to_reg(struct mme_builder *b, struct mme_value data) uint32_t low_bits = imm & UINT16_MAX; mme_fermi_add_imm18(fb, dst, mme_zero(), high_bits); - mme_fermi_sll_to(fb, dst, dst, mme_imm(16)); + mme_fermi_sll_to(b, dst, dst, mme_imm(16)); mme_fermi_add_imm18(fb, dst, dst, low_bits); } @@ -738,10 +752,10 @@ mme_fermi_build_alu(struct mme_builder *b, mme_fermi_umul_32x32_32_to_free_srcs(b, dst, x, y); return; case MME_ALU_OP_SLL: - mme_fermi_sll_to(fb, dst, x, y); + mme_fermi_sll_to(b, dst, x, y); return; case MME_ALU_OP_SRL: - mme_fermi_srl_to(fb, dst, x, y); + mme_fermi_srl_to(b, dst, x, y); return; case MME_ALU_OP_NOT: mme_and_not_to(b, dst, mme_imm(~(uint32_t)0), x); diff --git a/src/nouveau/mme/tests/mme_builder_test.cpp b/src/nouveau/mme/tests/mme_builder_test.cpp index 901077a8ab6..6c9afd43871 100644 --- a/src/nouveau/mme/tests/mme_builder_test.cpp +++ b/src/nouveau/mme/tests/mme_builder_test.cpp @@ -319,6 +319,8 @@ TEST_F(mme_builder_test, sll_srl) sim->mme_store_data(&b, 0, mme_sll(&b, xv, yv)); sim->mme_store_data(&b, 1, mme_srl(&b, xv, yv)); + sim->mme_store_data(&b, 2, mme_sll(&b, mme_imm(x), yv)); + sim->mme_store_data(&b, 3, mme_srl(&b, mme_imm(x), yv)); auto macro = mme_builder_finish_vec(&b); @@ -331,6 +333,8 @@ TEST_F(mme_builder_test, sll_srl) sim->run_macro(macro, params); ASSERT_EQ(sim->data[0], x << i); ASSERT_EQ(sim->data[1], x >> i); + ASSERT_EQ(sim->data[2], x << i); + ASSERT_EQ(sim->data[3], x >> i); } } }