+static unsigned
+print_dest(unsigned reg, midgard_reg_mode mode, midgard_dest_override override)
+{
+ /* Depending on the mode and override, we determine the type of
+ * destination addressed. Absent an override, we address just the
+ * type of the operation itself */
+
+ unsigned bits = bits_for_mode(mode);
+
+ if (override != midgard_dest_override_none)
+ bits /= 2;
+
+ print_reg(reg, bits);
+
+ return bits;
+}
+
+static void
+print_mask_vec16(uint8_t mask, midgard_dest_override override)
+{
+ printf(".");
+
+ if (override == midgard_dest_override_none) {
+ for (unsigned i = 0; i < 8; i++) {
+ if (mask & (1 << i))
+ printf("%c%c",
+ components[i*2 + 0],
+ components[i*2 + 1]);
+ }
+ } else {
+ bool upper = (override == midgard_dest_override_upper);
+
+ for (unsigned i = 0; i < 8; i++) {
+ if (mask & (1 << i))
+ printf("%c", components[i + (upper ? 8 : 0)]);
+ }
+ }
+}
+
+/* For 16-bit+ masks, we read off from the 8-bit mask field. For 16-bit (vec8),
+ * it's just one bit per channel, easy peasy. For 32-bit (vec4), it's one bit
+ * per channel with one duplicate bit in the middle. For 64-bit (vec2), it's
+ * one-bit per channel with _3_ duplicate bits in the middle. Basically, just
+ * subdividing the 128-bit word in 16-bit increments. For 64-bit, we uppercase
+ * the mask to make it obvious what happened */
+
+static void
+print_mask(uint8_t mask, unsigned bits, midgard_dest_override override)
+{
+ if (bits == 8) {
+ print_mask_vec16(mask, override);
+ return;
+ }
+
+ /* Skip 'complete' masks */
+
+ if (bits >= 32 && mask == 0xFF) return;
+
+ if (bits == 16) {
+ if (mask == 0x0F)
+ return;
+ else if (mask == 0xF0) {
+ printf("'");
+ return;
+ }
+ }
+
+ printf(".");
+
+ unsigned skip = (bits / 16);
+ bool uppercase = bits > 32;
+ bool tripped = false;
+
+ for (unsigned i = 0; i < 8; i += skip) {
+ bool a = (mask & (1 << i)) != 0;
+
+ for (unsigned j = 1; j < skip; ++j) {
+ bool dupe = (mask & (1 << (i + j))) != 0;
+ tripped |= (dupe != a);
+ }
+
+ if (a) {
+ char c = components[i / skip];
+
+ if (uppercase)
+ c = toupper(c);
+
+ printf("%c", c);
+ }
+ }
+
+ if (tripped)
+ printf(" /* %X */", mask);
+}
+
+static void
+print_mask_4(unsigned mask)
+{
+ printf(".");
+
+ for (unsigned i = 0; i < 4; ++i) {
+ bool a = (mask & (1 << i)) != 0;
+ if (a)
+ printf("%c", components[i]);
+ }
+}
+