freedreno/ir3: add encoding/decoding for (sat) bit
authorRob Clark <robdclark@gmail.com>
Sun, 21 Jan 2018 17:20:01 +0000 (12:20 -0500)
committerRob Clark <robdclark@gmail.com>
Sat, 10 Feb 2018 19:54:58 +0000 (14:54 -0500)
Seems to be there since a3xx, but we always lowered fsat.  But we can
shave some instructions, especially in shaders that use lots of
clamp(foo, 0.0, 1.0) by not lowering fsat.

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/ir3/disasm-a3xx.c
src/gallium/drivers/freedreno/ir3/instr-a3xx.h
src/gallium/drivers/freedreno/ir3/ir3.c
src/gallium/drivers/freedreno/ir3/ir3.h

index 1c81c3871271a963253bb21e3a9964383548afac..5499e19b44692361cb430e0f8c210cf9e36280da 100644 (file)
@@ -980,18 +980,18 @@ static void print_instr(uint32_t *dwords, int level, int n)
         * diff'ing..
         */
 
+       repeat = instr_repeat(instr);
+
        if (instr->sync)
                printf("(sy)");
        if (instr->ss && ((instr->opc_cat <= 4) || (instr->opc_cat == 7)))
                printf("(ss)");
        if (instr->jmp_tgt)
                printf("(jp)");
-       if (instr->repeat && (instr->opc_cat <= 4)) {
-               printf("(rpt%d)", instr->repeat);
-               repeat = instr->repeat;
-       } else {
-               repeat = 0;
-       }
+       if (instr_sat(instr))
+               printf("(sat)");
+       if (repeat)
+               printf("(rpt%d)", repeat);
        if (instr->ul && ((2 <= instr->opc_cat) && (instr->opc_cat <= 4)))
                printf("(ul)");
 
index 65fc212c1c2796bef154dad0440fc66a71e8b6e3..6aebb057619c89abe01401dd215ffa22ccf17f27 100644 (file)
@@ -410,7 +410,8 @@ typedef struct PACKED {
 
        /* dword1: */
        uint32_t dst      : 8;
-       uint32_t repeat   : 3;
+       uint32_t repeat   : 2;
+       uint32_t sat      : 1;
        uint32_t src1_r   : 1;
        uint32_t ss       : 1;
        uint32_t ul       : 1;   /* dunno */
@@ -473,7 +474,8 @@ typedef struct PACKED {
 
        /* dword1: */
        uint32_t dst      : 8;
-       uint32_t repeat   : 3;
+       uint32_t repeat   : 2;
+       uint32_t sat      : 1;
        uint32_t src1_r   : 1;
        uint32_t ss       : 1;
        uint32_t ul       : 1;
@@ -529,7 +531,8 @@ typedef struct PACKED {
 
        /* dword1: */
        uint32_t dst      : 8;
-       uint32_t repeat   : 3;
+       uint32_t repeat   : 2;
+       uint32_t sat      : 1;
        uint32_t src_r    : 1;
        uint32_t ss       : 1;
        uint32_t ul       : 1;
@@ -752,9 +755,10 @@ typedef union PACKED {
        instr_cat7_t cat7;
        struct PACKED {
                /* dword0: */
-               uint64_t pad1     : 40;
-               uint32_t repeat   : 3;  /* cat0-cat4 */
-               uint32_t pad2     : 1;
+               uint32_t pad1     : 32;
+
+               /* dword1: */
+               uint32_t pad2     : 12;
                uint32_t ss       : 1;  /* cat1-cat4 (cat0??) and cat7 (?) */
                uint32_t ul       : 1;  /* cat2-cat4 (and cat1 in blob.. which may be bug??) */
                uint32_t pad3     : 13;
@@ -765,6 +769,28 @@ typedef union PACKED {
        };
 } instr_t;
 
+static inline uint32_t instr_repeat(instr_t *instr)
+{
+       switch (instr->opc_cat) {
+       case 0:  return instr->cat0.repeat;
+       case 1:  return instr->cat1.repeat;
+       case 2:  return instr->cat2.repeat;
+       case 3:  return instr->cat3.repeat;
+       case 4:  return instr->cat4.repeat;
+       default: return 0;
+       }
+}
+
+static inline bool instr_sat(instr_t *instr)
+{
+       switch (instr->opc_cat) {
+       case 2:  return instr->cat2.sat;
+       case 3:  return instr->cat3.sat;
+       case 4:  return instr->cat4.sat;
+       default: return false;
+       }
+}
+
 static inline uint32_t instr_opc(instr_t *instr)
 {
        switch (instr->opc_cat) {
index e59f10dab9368be0dae97c158772660b6817f554..04c02340940e61e9702df4bfafcc0d1d96d19200 100644 (file)
@@ -258,6 +258,7 @@ static int emit_cat2(struct ir3_instruction *instr, void *ptr,
        cat2->dst      = reg(dst, info, instr->repeat,
                        IR3_REG_R | IR3_REG_EI | IR3_REG_HALF);
        cat2->repeat   = instr->repeat;
+       cat2->sat      = !!(instr->flags & IR3_INSTR_SAT);
        cat2->ss       = !!(instr->flags & IR3_INSTR_SS);
        cat2->ul       = !!(instr->flags & IR3_INSTR_UL);
        cat2->dst_half = !!((src1->flags ^ dst->flags) & IR3_REG_HALF);
@@ -354,6 +355,7 @@ static int emit_cat3(struct ir3_instruction *instr, void *ptr,
 
        cat3->dst      = reg(dst, info, instr->repeat, IR3_REG_R | IR3_REG_HALF);
        cat3->repeat   = instr->repeat;
+       cat3->sat      = !!(instr->flags & IR3_INSTR_SAT);
        cat3->ss       = !!(instr->flags & IR3_INSTR_SS);
        cat3->ul       = !!(instr->flags & IR3_INSTR_UL);
        cat3->dst_half = !!((src_flags ^ dst->flags) & IR3_REG_HALF);
@@ -401,6 +403,7 @@ static int emit_cat4(struct ir3_instruction *instr, void *ptr,
 
        cat4->dst      = reg(dst, info, instr->repeat, IR3_REG_R | IR3_REG_HALF);
        cat4->repeat   = instr->repeat;
+       cat4->sat      = !!(instr->flags & IR3_INSTR_SAT);
        cat4->ss       = !!(instr->flags & IR3_INSTR_SS);
        cat4->ul       = !!(instr->flags & IR3_INSTR_UL);
        cat4->dst_half = !!((src->flags ^ dst->flags) & IR3_REG_HALF);
index b8e41718da48e205c7f4e6501ef176571c869de6..210df20b812c22fecb08ed07ad44365a315b2f33 100644 (file)
@@ -204,6 +204,7 @@ struct ir3_instruction {
                IR3_INSTR_S     = 0x100,
                IR3_INSTR_S2EN  = 0x200,
                IR3_INSTR_G     = 0x400,
+               IR3_INSTR_SAT   = 0x800,
                /* meta-flags, for intermediate stages of IR, ie.
                 * before register assignment is done:
                 */