+ if (mux0 == QPU_MUX_A) {
+ /* Make sure we use the same type of MOV as the instruction,
+ * in case of unpacks.
+ */
+ if (qir_is_float_input(inst))
+ queue(c, qpu_a_FMAX(qpu_rb(31), *src0, *src0));
+ else
+ queue(c, qpu_a_MOV(qpu_rb(31), *src0));
+
+ /* If we had an unpack on this A-file source, we need to put
+ * it into this MOV, not into the later move from regfile B.
+ */
+ if (inst->src[0].pack) {
+ *last_inst(c) |= *unpack;
+ *unpack = 0;
+ }
+ *src0 = qpu_rb(31);
+ } else {
+ queue(c, qpu_a_MOV(qpu_ra(31), *src0));
+ *src0 = qpu_ra(31);
+ }
+}
+
+static void
+set_last_dst_pack(struct vc4_compile *c, struct qinst *inst)
+{
+ bool had_pm = *last_inst(c) & QPU_PM;
+ bool had_ws = *last_inst(c) & QPU_WS;
+ uint32_t unpack = QPU_GET_FIELD(*last_inst(c), QPU_UNPACK);
+
+ if (!inst->dst.pack)
+ return;
+
+ *last_inst(c) |= QPU_SET_FIELD(inst->dst.pack, QPU_PACK);
+
+ if (qir_is_mul(inst)) {
+ assert(!unpack || had_pm);
+ *last_inst(c) |= QPU_PM;
+ } else {
+ assert(!unpack || !had_pm);
+ assert(!had_ws); /* dst must be a-file to pack. */
+ }
+}
+
+static void
+handle_r4_qpu_write(struct vc4_compile *c, struct qinst *qinst,
+ struct qpu_reg dst)
+{
+ if (dst.mux != QPU_MUX_R4)
+ queue(c, qpu_a_MOV(dst, qpu_r4()));
+ else if (qinst->sf)
+ queue(c, qpu_a_MOV(qpu_ra(QPU_W_NOP), qpu_r4()));