From: Rob Clark Date: Wed, 18 Mar 2015 23:26:13 +0000 (-0400) Subject: freedreno/ir3: add ir3 builder helpers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=203f37540a698a812f0a66e2f3f1fff954af22ab;p=mesa.git freedreno/ir3: add ir3 builder helpers 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 --- diff --git a/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c b/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c index bed9aca795f..22e0dc2044c 100644 --- a/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c +++ b/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c @@ -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) { diff --git a/src/gallium/drivers/freedreno/ir3/instr-a3xx.h b/src/gallium/drivers/freedreno/ir3/instr-a3xx.h index c685fb15666..4d75d771435 100644 --- a/src/gallium/drivers/freedreno/ir3/instr-a3xx.h +++ b/src/gallium/drivers/freedreno/ir3/instr-a3xx.h @@ -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: */ diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index 14369ce772c..ce14807cb01 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -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.. */