freedreno/ir3: fix sam.s2en encoding
[mesa.git] / src / freedreno / ir3 / ir3.h
index e710022f5d2af5115d1713e664ba36e5499de9b0..4bd7601b8dd4f79b9d1e24e8970b72ebb3eb12ac 100644 (file)
@@ -29,8 +29,9 @@
 
 #include "compiler/shader_enums.h"
 
-#include "util/u_debug.h"
+#include "util/bitscan.h"
 #include "util/list.h"
+#include "util/u_debug.h"
 
 #include "instr-a3xx.h"
 
@@ -212,7 +213,8 @@ struct ir3_instruction {
                IR3_INSTR_MARK  = 0x1000,
                IR3_INSTR_UNUSED= 0x2000,
        } flags;
-       int repeat;
+       uint8_t repeat;
+       uint8_t nop;
 #ifdef DEBUG
        unsigned regs_max;
 #endif
@@ -247,7 +249,7 @@ struct ir3_instruction {
                        int src_offset;
                        int dst_offset;
                        int iim_val : 3;      /* for ldgb/stgb, # of components */
-                       int d : 3;
+                       unsigned d : 3;
                        bool typed : 1;
                } cat6;
                struct {
@@ -291,6 +293,9 @@ struct ir3_instruction {
         */
        void *data;
 
+       int sun;            /* Sethi–Ullman number, used by sched */
+       int use_count;      /* currently just updated/used by cp */
+
        /* Used during CP and RA stages.  For fanin and shader inputs/
         * outputs where we need a sequence of consecutive registers,
         * keep track of each src instructions left (ie 'n-1') and right
@@ -362,8 +367,6 @@ struct ir3_instruction {
        /* Entry in ir3_block's instruction list: */
        struct list_head node;
 
-       int use_count;      /* currently just updated/used by cp */
-
 #ifdef DEBUG
        uint32_t serialno;
 #endif
@@ -442,6 +445,8 @@ struct ir3 {
        /* List of ir3_array's: */
        struct list_head array_list;
 
+       unsigned max_sun;   /* max Sethi–Ullman number */
+
 #ifdef DEBUG
        unsigned block_count, instr_count;
 #endif
@@ -688,6 +693,7 @@ static inline bool is_load(struct ir3_instruction *instr)
        switch (instr->opc) {
        case OPC_LDG:
        case OPC_LDGB:
+       case OPC_LDIB:
        case OPC_LDL:
        case OPC_LDP:
        case OPC_L2G:
@@ -737,6 +743,14 @@ static inline bool is_meta(struct ir3_instruction *instr)
        return (opc_cat(instr->opc) == -1);
 }
 
+static inline unsigned dest_regs(struct ir3_instruction *instr)
+{
+       if ((instr->regs_count == 0) || is_store(instr))
+               return 0;
+
+       return util_last_bit(instr->regs[0]->wrmask);
+}
+
 static inline bool writes_addr(struct ir3_instruction *instr)
 {
        if (instr->regs_count > 0) {
@@ -997,6 +1011,9 @@ void ir3_cp(struct ir3 *ir, struct ir3_shader_variant *so);
 /* group neighbors and insert mov's to resolve conflicts: */
 void ir3_group(struct ir3 *ir);
 
+/* Sethi–Ullman numbering: */
+void ir3_sun(struct ir3 *ir);
+
 /* scheduling: */
 void ir3_sched_add_deps(struct ir3 *ir);
 int ir3_sched(struct ir3 *ir);
@@ -1076,6 +1093,7 @@ static inline struct ir3_register * __ssa_src(struct ir3_instruction *instr,
                flags |= IR3_REG_HALF;
        reg = ir3_reg_create(instr, 0, IR3_REG_SSA | flags);
        reg->instr = src;
+       reg->wrmask = src->regs[0]->wrmask;
        return reg;
 }
 
@@ -1088,7 +1106,7 @@ ir3_MOV(struct ir3_block *block, struct ir3_instruction *src, type_t type)
                struct ir3_register *src_reg = __ssa_src(instr, src, IR3_REG_ARRAY);
                src_reg->array = src->regs[0]->array;
        } else {
-               __ssa_src(instr, src, 0);
+               __ssa_src(instr, src, src->regs[0]->flags & IR3_REG_HIGH);
        }
        debug_assert(!(src->regs[0]->flags & IR3_REG_RELATIV));
        instr->cat1.src_type = type;
@@ -1321,6 +1339,9 @@ ir3_SAM(struct ir3_block *block, opc_t opc, type_t type,
        sam = ir3_instr_create(block, opc);
        sam->flags |= flags;
        ir3_reg_create(sam, 0, 0)->wrmask = wrmask;
+       // temporary step, extra dummy src which will become the
+       // hvec2(samp, tex) argument:
+       ir3_reg_create(sam, 0, 0);
        if (src0) {
                reg = ir3_reg_create(sam, 0, IR3_REG_SSA);
                reg->wrmask = (1 << (src0->regs_count - 1)) - 1;
@@ -1359,6 +1380,7 @@ INSTR2(ATOMIC_OR)
 INSTR2(ATOMIC_XOR)
 #if GPU >= 600
 INSTR3(STIB);
+INSTR2(LDIB);
 INSTR3F(G, ATOMIC_ADD)
 INSTR3F(G, ATOMIC_SUB)
 INSTR3F(G, ATOMIC_XCHG)