nir: Report progress from nir_lower_alu_to_scalar.
[mesa.git] / src / gallium / drivers / freedreno / ir3 / disasm-a3xx.c
index 48ae7c71b9f16e3d5b4f0b479cffe7985fe847f8..e29d15682561c608ed461af465e0b678e47320a5 100644 (file)
@@ -103,7 +103,7 @@ static void print_reg(reg_t reg, bool full, bool r, bool c, bool im,
        } else if ((reg.num == REG_P0) && !c) {
                printf("p0.%c", component[reg.comp]);
        } else {
-               printf("%s%c%d.%c", full ? "" : "h", type, reg.num, component[reg.comp]);
+               printf("%s%c%d.%c", full ? "" : "h", type, reg.num & 0x3f, component[reg.comp]);
        }
 }
 
@@ -122,6 +122,32 @@ static void print_reg_src(reg_t reg, bool full, bool r, bool c, bool im,
        print_reg(reg, full, r, c, im, neg, abs, addr_rel);
 }
 
+/* TODO switch to using reginfo struct everywhere, since more readable
+ * than passing a bunch of bools to print_reg_src
+ */
+
+struct reginfo {
+       reg_t reg;
+       bool full;
+       bool r;
+       bool c;
+       bool im;
+       bool neg;
+       bool abs;
+       bool addr_rel;
+};
+
+static void print_src(struct reginfo *info)
+{
+       print_reg_src(info->reg, info->full, info->r, info->c, info->im,
+                       info->neg, info->abs, info->addr_rel);
+}
+
+//static void print_dst(struct reginfo *info)
+//{
+//     print_reg_dst(info->reg, info->full, info->addr_rel);
+//}
+
 static void print_instr_cat0(instr_t *instr)
 {
        instr_cat0_t *cat0 = &instr->cat0;
@@ -194,7 +220,7 @@ static void print_instr_cat1(instr_t *instr)
                else if (cat1->off > 0)
                        printf("%c<a0.x + %d>", type, cat1->off);
                else
-                       printf("c<a0.x>");
+                       printf("%c<a0.x>", type);
        } else {
                print_reg_src((reg_t)(cat1->src), type_size(cat1->src_type) == 32,
                                cat1->src_r, cat1->src_c, cat1->src_im, false, false, false);
@@ -217,7 +243,7 @@ static void print_instr_cat2(instr_t *instr)
                        "?6?",
        };
 
-       switch (cat2->opc) {
+       switch (_OPC(2, cat2->opc)) {
        case OPC_CMPS_F:
        case OPC_CMPS_U:
        case OPC_CMPS_S:
@@ -248,7 +274,7 @@ static void print_instr_cat2(instr_t *instr)
                                cat2->src1_abs, false);
        }
 
-       switch (cat2->opc) {
+       switch (_OPC(2, cat2->opc)) {
        case OPC_ABSNEG_F:
        case OPC_ABSNEG_S:
        case OPC_CLZ_B:
@@ -356,34 +382,34 @@ static void print_instr_cat5(instr_t *instr)
        static const struct {
                bool src1, src2, samp, tex;
        } info[0x1f] = {
-                       [OPC_ISAM]     = { true,  false, true,  true,  },
-                       [OPC_ISAML]    = { true,  true,  true,  true,  },
-                       [OPC_ISAMM]    = { true,  false, true,  true,  },
-                       [OPC_SAM]      = { true,  false, true,  true,  },
-                       [OPC_SAMB]     = { true,  true,  true,  true,  },
-                       [OPC_SAML]     = { true,  true,  true,  true,  },
-                       [OPC_SAMGQ]    = { true,  false, true,  true,  },
-                       [OPC_GETLOD]   = { true,  false, true,  true,  },
-                       [OPC_CONV]     = { true,  true,  true,  true,  },
-                       [OPC_CONVM]    = { true,  true,  true,  true,  },
-                       [OPC_GETSIZE]  = { true,  false, false, true,  },
-                       [OPC_GETBUF]   = { false, false, false, true,  },
-                       [OPC_GETPOS]   = { true,  false, false, true,  },
-                       [OPC_GETINFO]  = { false, false, false, true,  },
-                       [OPC_DSX]      = { true,  false, false, false, },
-                       [OPC_DSY]      = { true,  false, false, false, },
-                       [OPC_GATHER4R] = { true,  false, true,  true,  },
-                       [OPC_GATHER4G] = { true,  false, true,  true,  },
-                       [OPC_GATHER4B] = { true,  false, true,  true,  },
-                       [OPC_GATHER4A] = { true,  false, true,  true,  },
-                       [OPC_SAMGP0]   = { true,  false, true,  true,  },
-                       [OPC_SAMGP1]   = { true,  false, true,  true,  },
-                       [OPC_SAMGP2]   = { true,  false, true,  true,  },
-                       [OPC_SAMGP3]   = { true,  false, true,  true,  },
-                       [OPC_DSXPP_1]  = { true,  false, false, false, },
-                       [OPC_DSYPP_1]  = { true,  false, false, false, },
-                       [OPC_RGETPOS]  = { false, false, false, false, },
-                       [OPC_RGETINFO] = { false, false, false, false, },
+                       [opc_op(OPC_ISAM)]     = { true,  false, true,  true,  },
+                       [opc_op(OPC_ISAML)]    = { true,  true,  true,  true,  },
+                       [opc_op(OPC_ISAMM)]    = { true,  false, true,  true,  },
+                       [opc_op(OPC_SAM)]      = { true,  false, true,  true,  },
+                       [opc_op(OPC_SAMB)]     = { true,  true,  true,  true,  },
+                       [opc_op(OPC_SAML)]     = { true,  true,  true,  true,  },
+                       [opc_op(OPC_SAMGQ)]    = { true,  false, true,  true,  },
+                       [opc_op(OPC_GETLOD)]   = { true,  false, true,  true,  },
+                       [opc_op(OPC_CONV)]     = { true,  true,  true,  true,  },
+                       [opc_op(OPC_CONVM)]    = { true,  true,  true,  true,  },
+                       [opc_op(OPC_GETSIZE)]  = { true,  false, false, true,  },
+                       [opc_op(OPC_GETBUF)]   = { false, false, false, true,  },
+                       [opc_op(OPC_GETPOS)]   = { true,  false, false, true,  },
+                       [opc_op(OPC_GETINFO)]  = { false, false, false, true,  },
+                       [opc_op(OPC_DSX)]      = { true,  false, false, false, },
+                       [opc_op(OPC_DSY)]      = { true,  false, false, false, },
+                       [opc_op(OPC_GATHER4R)] = { true,  false, true,  true,  },
+                       [opc_op(OPC_GATHER4G)] = { true,  false, true,  true,  },
+                       [opc_op(OPC_GATHER4B)] = { true,  false, true,  true,  },
+                       [opc_op(OPC_GATHER4A)] = { true,  false, true,  true,  },
+                       [opc_op(OPC_SAMGP0)]   = { true,  false, true,  true,  },
+                       [opc_op(OPC_SAMGP1)]   = { true,  false, true,  true,  },
+                       [opc_op(OPC_SAMGP2)]   = { true,  false, true,  true,  },
+                       [opc_op(OPC_SAMGP3)]   = { true,  false, true,  true,  },
+                       [opc_op(OPC_DSXPP_1)]  = { true,  false, false, false, },
+                       [opc_op(OPC_DSYPP_1)]  = { true,  false, false, false, },
+                       [opc_op(OPC_RGETPOS)]  = { false, false, false, false, },
+                       [opc_op(OPC_RGETINFO)] = { false, false, false, false, },
        };
        instr_cat5_t *cat5 = &instr->cat5;
        int i;
@@ -397,7 +423,7 @@ static void print_instr_cat5(instr_t *instr)
 
        printf(" ");
 
-       switch (cat5->opc) {
+       switch (_OPC(5, cat5->opc)) {
        case OPC_DSXPP_1:
        case OPC_DSYPP_1:
                break;
@@ -454,12 +480,72 @@ static void print_instr_cat6(instr_t *instr)
 {
        instr_cat6_t *cat6 = &instr->cat6;
        char sd = 0, ss = 0;  /* dst/src address space */
-       bool full = type_size(cat6->type) == 32;
        bool nodst = false;
+       struct reginfo dst, src1, src2;
+       int src1off = 0, dstoff = 0;
+
+       memset(&dst, 0, sizeof(dst));
+       memset(&src1, 0, sizeof(src1));
+       memset(&src2, 0, sizeof(src2));
+
+       switch (_OPC(6, cat6->opc)) {
+       case OPC_RESINFO:
+       case OPC_RESFMT:
+               dst.full  = type_size(cat6->type) == 32;
+               src1.full = type_size(cat6->type) == 32;
+               src2.full = type_size(cat6->type) == 32;
+               break;
+       case OPC_L2G:
+       case OPC_G2L:
+               dst.full = true;
+               src1.full = true;
+               src2.full = true;
+               break;
+       case OPC_STG:
+       case OPC_STL:
+       case OPC_STP:
+       case OPC_STI:
+       case OPC_STLW:
+       case OPC_STGB_4D_4:
+       case OPC_STIB:
+               dst.full  = true;
+               src1.full = type_size(cat6->type) == 32;
+               src2.full = type_size(cat6->type) == 32;
+               break;
+       default:
+               dst.full  = type_size(cat6->type) == 32;
+               src1.full = true;
+               src2.full = true;
+               break;
+       }
 
-       printf(".%s ", type[cat6->type]);
+       switch (_OPC(6, cat6->opc)) {
+       case OPC_PREFETCH:
+       case OPC_RESINFO:
+               break;
+       case OPC_ATOMIC_ADD:
+       case OPC_ATOMIC_SUB:
+       case OPC_ATOMIC_XCHG:
+       case OPC_ATOMIC_INC:
+       case OPC_ATOMIC_DEC:
+       case OPC_ATOMIC_CMPXCHG:
+       case OPC_ATOMIC_MIN:
+       case OPC_ATOMIC_MAX:
+       case OPC_ATOMIC_AND:
+       case OPC_ATOMIC_OR:
+       case OPC_ATOMIC_XOR:
+               ss = cat6->g ? 'g' : 'l';
+               printf(".%c", ss);
+               printf(".%s", type[cat6->type]);
+               break;
+       default:
+               dst.im = cat6->g && !cat6->dst_off;
+               printf(".%s", type[cat6->type]);
+               break;
+       }
+       printf(" ");
 
-       switch (cat6->opc) {
+       switch (_OPC(6, cat6->opc)) {
        case OPC_STG:
                sd = 'g';
                break;
@@ -499,81 +585,78 @@ static void print_instr_cat6(instr_t *instr)
                break;
 
        case OPC_STI:
-               full = false;  // XXX or inverts??
+               dst.full = false;  // XXX or inverts??
                break;
        }
 
-       if (cat6->has_off) {
-               if (!nodst) {
-                       if (sd)
-                               printf("%c[", sd);
-                       print_reg_dst((reg_t)(cat6->a.dst), full, false);
-                       if (sd)
-                               printf("]");
-                       printf(", ");
-               }
-               if (ss)
-                       printf("%c[", ss);
-               print_reg_src((reg_t)(cat6->a.src1), true,
-                               false, false, cat6->a.src1_im, false, false, false);
-               if (cat6->a.off)
-                       printf("%+d", cat6->a.off);
-               if (ss)
-                       printf("]");
-               printf(", ");
-               print_reg_src((reg_t)(cat6->a.src2), full,
-                               false, false, cat6->a.src2_im, false, false, false);
+       if (cat6->dst_off) {
+               dst.reg = (reg_t)(cat6->c.dst);
+               dstoff  = cat6->c.off;
        } else {
-               if (!nodst) {
-                       if (sd)
-                               printf("%c[", sd);
-                       print_reg_dst((reg_t)(cat6->b.dst), full, false);
-                       if (sd)
-                               printf("]");
-                       printf(", ");
-               }
-               if (ss)
-                       printf("%c[", ss);
-               print_reg_src((reg_t)(cat6->b.src1), true,
-                               false, false, cat6->b.src1_im, false, false, false);
-               if (ss)
+               dst.reg = (reg_t)(cat6->d.dst);
+       }
+
+       if (cat6->src_off) {
+               src1.reg = (reg_t)(cat6->a.src1);
+               src1.im  = cat6->a.src1_im;
+               src2.reg = (reg_t)(cat6->a.src2);
+               src2.im  = cat6->a.src2_im;
+               src1off  = cat6->a.off;
+       } else {
+               src1.reg = (reg_t)(cat6->b.src1);
+               src1.im  = cat6->b.src1_im;
+               src2.reg = (reg_t)(cat6->b.src2);
+               src2.im  = cat6->b.src2_im;
+       }
+
+       if (!nodst) {
+               if (sd)
+                       printf("%c[", sd);
+               /* note: dst might actually be a src (ie. address to store to) */
+               print_src(&dst);
+               if (dstoff)
+                       printf("%+d", dstoff);
+               if (sd)
                        printf("]");
                printf(", ");
-               print_reg_src((reg_t)(cat6->b.src2), full,
-                               false, false, cat6->b.src2_im, false, false, false);
        }
 
-       if (debug & PRINT_VERBOSE) {
-               switch (cat6->opc) {
-               case OPC_LDG:
-               case OPC_LDP:
-                       /* load instructions: */
-                       if (cat6->a.dummy2|cat6->a.dummy3)
-                               printf("\t{6: %x,%x}", cat6->a.dummy2, cat6->a.dummy3);
-                       break;
-               case OPC_STG:
-               case OPC_STP:
-               case OPC_STI:
-                       /* store instructions: */
-                       if (cat6->b.dummy2|cat6->b.dummy2)
-                               printf("\t{6: %x,%x}", cat6->b.dummy2, cat6->b.dummy3);
-                       if (cat6->b.ignore0)
-                               printf("\t{?? %x}", cat6->b.ignore0);
-                       break;
-               }
+       if (ss)
+               printf("%c[", ss);
+
+       /* can have a larger than normal immed, so hack: */
+       if (src1.im) {
+               printf("%u", src1.reg.dummy13);
+       } else {
+               print_src(&src1);
+       }
+
+       if (src1off)
+               printf("%+d", src1off);
+       if (ss)
+               printf("]");
+
+       switch (_OPC(6, cat6->opc)) {
+       case OPC_RESINFO:
+       case OPC_RESFMT:
+               break;
+       default:
+               printf(", ");
+               print_src(&src2);
+               break;
        }
 }
 
 /* size of largest OPC field of all the instruction categories: */
 #define NOPC_BITS 6
 
-struct opc_info {
+static const struct opc_info {
        uint16_t cat;
        uint16_t opc;
        const char *name;
        void (*print)(instr_t *instr);
 } opcs[1 << (3+NOPC_BITS)] = {
-#define OPC(cat, opc, name) [((cat) << NOPC_BITS) | (opc)] = { (cat), (opc), #name, print_instr_cat##cat }
+#define OPC(cat, opc, name) [(opc)] = { (cat), (opc), #name, print_instr_cat##cat }
        /* category 0: */
        OPC(0, OPC_NOP,          nop),
        OPC(0, OPC_BR,           br),
@@ -589,7 +672,7 @@ struct opc_info {
        OPC(0, OPC_FLOW_REV,     flow_rev),
 
        /* category 1: */
-       OPC(1, 0, ),
+       OPC(1, OPC_MOV, ),
 
        /* category 2: */
        OPC(2, OPC_ADD_F,        add.f),
@@ -711,19 +794,19 @@ struct opc_info {
        OPC(6, OPC_LDLW,         ldlw),
        OPC(6, OPC_STLW,         stlw),
        OPC(6, OPC_RESFMT,       resfmt),
-       OPC(6, OPC_RESINFO,      resinf),
-       OPC(6, OPC_ATOMIC_ADD_L,     atomic.add.l),
-       OPC(6, OPC_ATOMIC_SUB_L,     atomic.sub.l),
-       OPC(6, OPC_ATOMIC_XCHG_L,    atomic.xchg.l),
-       OPC(6, OPC_ATOMIC_INC_L,     atomic.inc.l),
-       OPC(6, OPC_ATOMIC_DEC_L,     atomic.dec.l),
-       OPC(6, OPC_ATOMIC_CMPXCHG_L, atomic.cmpxchg.l),
-       OPC(6, OPC_ATOMIC_MIN_L,     atomic.min.l),
-       OPC(6, OPC_ATOMIC_MAX_L,     atomic.max.l),
-       OPC(6, OPC_ATOMIC_AND_L,     atomic.and.l),
-       OPC(6, OPC_ATOMIC_OR_L,      atomic.or.l),
-       OPC(6, OPC_ATOMIC_XOR_L,     atomic.xor.l),
-       OPC(6, OPC_LDGB_TYPED_4D,    ldgb.typed.4d),
+       OPC(6, OPC_RESINFO,      resinfo),
+       OPC(6, OPC_ATOMIC_ADD,     atomic.add),
+       OPC(6, OPC_ATOMIC_SUB,     atomic.sub),
+       OPC(6, OPC_ATOMIC_XCHG,    atomic.xchg),
+       OPC(6, OPC_ATOMIC_INC,     atomic.inc),
+       OPC(6, OPC_ATOMIC_DEC,     atomic.dec),
+       OPC(6, OPC_ATOMIC_CMPXCHG, atomic.cmpxchg),
+       OPC(6, OPC_ATOMIC_MIN,     atomic.min),
+       OPC(6, OPC_ATOMIC_MAX,     atomic.max),
+       OPC(6, OPC_ATOMIC_AND,     atomic.and),
+       OPC(6, OPC_ATOMIC_OR,      atomic.or),
+       OPC(6, OPC_ATOMIC_XOR,     atomic.xor),
+       OPC(6, OPC_LDGB_TYPED_4D,    ldgb.typed.3d),
        OPC(6, OPC_STGB_4D_4,    stgb.4d.4),
        OPC(6, OPC_STIB,         stib),
        OPC(6, OPC_LDC_4,        ldc.4),
@@ -739,8 +822,8 @@ struct opc_info {
 #include "ir3.h"
 const char *ir3_instr_name(struct ir3_instruction *instr)
 {
-       if (instr->category == -1) return "??meta??";
-       return opcs[(instr->category << NOPC_BITS) | instr->opc].name;
+       if (opc_cat(instr->opc) == -1) return "??meta??";
+       return opcs[instr->opc].name;
 }
 
 static void print_instr(uint32_t *dwords, int level, int n)