freedreno/ir3: add ir3 builder helpers
authorRob Clark <robclark@freedesktop.org>
Wed, 18 Mar 2015 23:26:13 +0000 (19:26 -0400)
committerRob Clark <robclark@freedesktop.org>
Sun, 5 Apr 2015 16:44:01 +0000 (12:44 -0400)
Add helpers for constructing SSA forms of instructions.

Only partial cat5/cat6 coverage.. but we can add stuff as needed.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/ir3/disasm-a3xx.c
src/gallium/drivers/freedreno/ir3/instr-a3xx.h
src/gallium/drivers/freedreno/ir3/ir3.h

index bed9aca795f572efb9c345f8fb46a78bb1cb4d13..22e0dc2044cdacc912110a2d8841e0bcece8f247 100644 (file)
@@ -180,6 +180,8 @@ static void print_instr_cat1(instr_t *instr)
        if (cat1->src_im) {
                if (type_float(cat1->src_type))
                        printf("(%f)", cat1->fim_val);
+               else if (type_uint(cat1->src_type))
+                       printf("0x%08x", cat1->uim_val);
                else
                        printf("%d", cat1->iim_val);
        } else if (cat1->src_rel && !cat1->src_c) {
index c685fb156667bd191272882f51222f2403df3243..4d75d77143564d09672eba139bd9b657cf2fbe34 100644 (file)
@@ -317,8 +317,9 @@ typedef struct PACKED {
                        uint32_t unknown : 20;
                };
                /* for immediate: */
-               int32_t iim_val;
-               float   fim_val;
+               int32_t  iim_val;
+               uint32_t uim_val;
+               float    fim_val;
        };
 
        /* dword1: */
index 14369ce772cde7b7648da5e2f0b32e69069720cd..ce14807cb014b0027bd7f5b158ec1ae7acdf5ba6 100644 (file)
@@ -79,8 +79,9 @@ struct ir3_register {
                 */
                int   num;
                /* immediate: */
-               int   iim_val;
-               float fim_val;
+               int32_t  iim_val;
+               uint32_t uim_val;
+               float    fim_val;
                /* relative: */
                int   offset;
        };
@@ -604,6 +605,160 @@ int ir3_block_ra(struct ir3_block *block, enum shader_t type,
 void ir3_block_legalize(struct ir3_block *block,
                bool *has_samp, int *max_bary);
 
+/* ************************************************************************* */
+/* instruction helpers */
+
+static inline struct ir3_instruction *
+ir3_MOV(struct ir3_block *block, struct ir3_instruction *src, type_t type)
+{
+       struct ir3_instruction *instr =
+               ir3_instr_create(block, 1, 0);
+       ir3_reg_create(instr, 0, 0);   /* dst */
+       ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src;
+       instr->cat1.src_type = type;
+       instr->cat1.dst_type = type;
+       return instr;
+}
+
+static inline struct ir3_instruction *
+ir3_COV(struct ir3_block *block, struct ir3_instruction *src,
+               type_t src_type, type_t dst_type)
+{
+       struct ir3_instruction *instr =
+               ir3_instr_create(block, 1, 0);
+       ir3_reg_create(instr, 0, 0);   /* dst */
+       ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src;
+       instr->cat1.src_type = src_type;
+       instr->cat1.dst_type = dst_type;
+       return instr;
+}
+
+#define INSTR1(CAT, name)                                                \
+static inline struct ir3_instruction *                                   \
+ir3_##name(struct ir3_block *block,                                      \
+               struct ir3_instruction *a, unsigned aflags)                      \
+{                                                                        \
+       struct ir3_instruction *instr =                                      \
+               ir3_instr_create(block, CAT, OPC_##name);                        \
+       ir3_reg_create(instr, 0, 0);   /* dst */                             \
+       ir3_reg_create(instr, 0, IR3_REG_SSA | aflags)->instr = a;           \
+       return instr;                                                        \
+}
+
+#define INSTR2(CAT, name)                                                \
+static inline struct ir3_instruction *                                   \
+ir3_##name(struct ir3_block *block,                                      \
+               struct ir3_instruction *a, unsigned aflags,                      \
+               struct ir3_instruction *b, unsigned bflags)                      \
+{                                                                        \
+       struct ir3_instruction *instr =                                      \
+               ir3_instr_create(block, CAT, OPC_##name);                        \
+       ir3_reg_create(instr, 0, 0);   /* dst */                             \
+       ir3_reg_create(instr, 0, IR3_REG_SSA | aflags)->instr = a;           \
+       ir3_reg_create(instr, 0, IR3_REG_SSA | bflags)->instr = b;           \
+       return instr;                                                        \
+}
+
+#define INSTR3(CAT, name)                                                \
+static inline struct ir3_instruction *                                   \
+ir3_##name(struct ir3_block *block,                                      \
+               struct ir3_instruction *a, unsigned aflags,                      \
+               struct ir3_instruction *b, unsigned bflags,                      \
+               struct ir3_instruction *c, unsigned cflags)                      \
+{                                                                        \
+       struct ir3_instruction *instr =                                      \
+               ir3_instr_create(block, CAT, OPC_##name);                        \
+       ir3_reg_create(instr, 0, 0);   /* dst */                             \
+       ir3_reg_create(instr, 0, IR3_REG_SSA | aflags)->instr = a;           \
+       ir3_reg_create(instr, 0, IR3_REG_SSA | bflags)->instr = b;           \
+       ir3_reg_create(instr, 0, IR3_REG_SSA | cflags)->instr = c;           \
+       return instr;                                                        \
+}
+
+/* cat0 instructions: */
+INSTR1(0, KILL);
+
+/* cat2 instructions, most 2 src but some 1 src: */
+INSTR2(2, ADD_F)
+INSTR2(2, MIN_F)
+INSTR2(2, MAX_F)
+INSTR2(2, MUL_F)
+INSTR1(2, SIGN_F)
+INSTR2(2, CMPS_F)
+INSTR1(2, ABSNEG_F)
+INSTR2(2, CMPV_F)
+INSTR1(2, FLOOR_F)
+INSTR1(2, CEIL_F)
+INSTR1(2, RNDNE_F)
+INSTR1(2, RNDAZ_F)
+INSTR1(2, TRUNC_F)
+INSTR2(2, ADD_U)
+INSTR2(2, ADD_S)
+INSTR2(2, SUB_U)
+INSTR2(2, SUB_S)
+INSTR2(2, CMPS_U)
+INSTR2(2, CMPS_S)
+INSTR2(2, MIN_U)
+INSTR2(2, MIN_S)
+INSTR2(2, MAX_U)
+INSTR2(2, MAX_S)
+INSTR1(2, ABSNEG_S)
+INSTR2(2, AND_B)
+INSTR2(2, OR_B)
+INSTR1(2, NOT_B)
+INSTR2(2, XOR_B)
+INSTR2(2, CMPV_U)
+INSTR2(2, CMPV_S)
+INSTR2(2, MUL_U)
+INSTR2(2, MUL_S)
+INSTR2(2, MULL_U)
+INSTR1(2, BFREV_B)
+INSTR1(2, CLZ_S)
+INSTR1(2, CLZ_B)
+INSTR2(2, SHL_B)
+INSTR2(2, SHR_B)
+INSTR2(2, ASHR_B)
+INSTR2(2, BARY_F)
+INSTR2(2, MGEN_B)
+INSTR2(2, GETBIT_B)
+INSTR1(2, SETRM)
+INSTR1(2, CBITS_B)
+INSTR2(2, SHB)
+INSTR2(2, MSAD)
+
+/* cat3 instructions: */
+INSTR3(3, MAD_U16)
+INSTR3(3, MADSH_U16)
+INSTR3(3, MAD_S16)
+INSTR3(3, MADSH_M16)
+INSTR3(3, MAD_U24)
+INSTR3(3, MAD_S24)
+INSTR3(3, MAD_F16)
+INSTR3(3, MAD_F32)
+INSTR3(3, SEL_B16)
+INSTR3(3, SEL_B32)
+INSTR3(3, SEL_S16)
+INSTR3(3, SEL_S32)
+INSTR3(3, SEL_F16)
+INSTR3(3, SEL_F32)
+INSTR3(3, SAD_S16)
+INSTR3(3, SAD_S32)
+
+/* cat4 instructions: */
+INSTR1(4, RCP)
+INSTR1(4, RSQ)
+INSTR1(4, LOG2)
+INSTR1(4, EXP2)
+INSTR1(4, SIN)
+INSTR1(4, COS)
+INSTR1(4, SQRT)
+
+/* cat5 instructions: */
+INSTR1(5, DSX)
+INSTR1(5, DSY)
+
+/* cat6 instructions: */
+INSTR2(6, LDLV)
 
 /* ************************************************************************* */
 /* split this out or find some helper to use.. like main/bitset.h.. */