Mesa (master): freedreno/ir3: Remove legacy packed-struct encoding
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jan 13 18:53:09 UTC 2021
Module: Mesa
Branch: master
Commit: 74748f16c969c59096a0bf4ce9f86fc92c797905
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=74748f16c969c59096a0bf4ce9f86fc92c797905
Author: Rob Clark <robdclark at chromium.org>
Date: Mon Jan 11 10:30:12 2021 -0800
freedreno/ir3: Remove legacy packed-struct encoding
Note that we can't actually remove the packed structs themselves yet,
because tu still uses them in some hand-coded blit shaders.
Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7997>
---
src/freedreno/ir3/ir3.c | 890 +-----------------------------------------------
src/freedreno/ir3/ir3.h | 1 -
2 files changed, 1 insertion(+), 890 deletions(-)
diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c
index 61d3c7bab5a..cb7a507dc36 100644
--- a/src/freedreno/ir3/ir3.c
+++ b/src/freedreno/ir3/ir3.c
@@ -64,869 +64,6 @@ void ir3_destroy(struct ir3 *shader)
ralloc_free(shader);
}
-#define iassert(cond) do { \
- if (!(cond)) { \
- debug_assert(cond); \
- return -1; \
- } } while (0)
-
-#define iassert_type(reg, full) do { \
- if ((full)) { \
- iassert(!((reg)->flags & IR3_REG_HALF)); \
- } else { \
- iassert((reg)->flags & IR3_REG_HALF); \
- } } while (0);
-
-static uint32_t reg(struct ir3_register *reg, uint32_t valid_flags)
-{
- reg_t val = { .dummy32 = 0 };
-
- if (reg->flags & ~valid_flags) {
- mesa_logd("INVALID FLAGS: %x vs %x",
- reg->flags, valid_flags);
- }
-
- if (reg->flags & IR3_REG_IMMED) {
- val.iim_val = reg->iim_val;
- } else if (reg->flags & IR3_REG_RELATIV) {
- val.idummy10 = reg->array.offset;
- } else {
- val.comp = reg->num & 0x3;
- val.num = reg->num >> 2;
- }
-
- return val.dummy32;
-}
-
-static int emit_cat0(struct ir3_instruction *instr, void *ptr)
-{
- instr_cat0_t *cat0 = ptr;
-
- if (instr->block->shader->compiler->gpu_id >= 500) {
- cat0->a5xx.immed = instr->cat0.immed;
- } else if (instr->block->shader->compiler->gpu_id >= 400) {
- cat0->a4xx.immed = instr->cat0.immed;
- } else {
- cat0->a3xx.immed = instr->cat0.immed;
- }
- cat0->repeat = instr->repeat;
- cat0->ss = !!(instr->flags & IR3_INSTR_SS);
- cat0->inv1 = instr->cat0.inv1;
- cat0->comp1 = instr->cat0.comp1;
- cat0->inv2 = instr->cat0.inv2;
- cat0->comp2 = instr->cat0.comp2;
- cat0->brtype = instr->cat0.brtype;
- cat0->idx = instr->cat0.idx;
- cat0->opc = instr->opc;
- cat0->opc_hi = instr->opc >= 16;
- cat0->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
- cat0->sync = !!(instr->flags & IR3_INSTR_SY);
- cat0->opc_cat = 0;
-
- return 0;
-}
-
-static int emit_cat1(struct ir3_instruction *instr, void *ptr)
-{
- struct ir3_register *dst = instr->regs[0];
- instr_cat1_t *cat1 = ptr;
-
- switch (instr->opc) {
- case OPC_MOV: {
- struct ir3_register *src = instr->regs[1];
- iassert(instr->regs_count == 2);
- iassert_type(dst, type_size(instr->cat1.dst_type) == 32);
- if (!(src->flags & IR3_REG_IMMED))
- iassert_type(src, type_size(instr->cat1.src_type) == 32);
-
- if (src->flags & IR3_REG_IMMED) {
- cat1->iim_val = src->iim_val;
- cat1->src_im = 1;
- } else if (src->flags & IR3_REG_RELATIV) {
- cat1->off = reg(src,
- IR3_REG_R | IR3_REG_CONST | IR3_REG_HALF | IR3_REG_RELATIV |
- IR3_REG_SHARED);
- cat1->src_rel = 1;
- cat1->src_rel_c = !!(src->flags & IR3_REG_CONST);
- } else {
- cat1->src = reg(src,
- IR3_REG_R | IR3_REG_CONST | IR3_REG_HALF | IR3_REG_SHARED);
- cat1->src_c = !!(src->flags & IR3_REG_CONST);
- }
- cat1->src_r = !!(src->flags & IR3_REG_R);
- cat1->dst_type = instr->cat1.dst_type;
- cat1->src_type = instr->cat1.src_type;
- cat1->even = !!(dst->flags & IR3_REG_EVEN);
- cat1->pos_inf = !!(dst->flags & IR3_REG_POS_INF);
- cat1->repeat = instr->repeat;
- break;
- }
- case OPC_MOVMSK: {
- iassert(instr->regs_count == 1);
- iassert(!(dst->flags & IR3_REG_HALF));
- iassert(!(dst->flags & IR3_REG_EVEN));
- iassert(!(dst->flags & IR3_REG_POS_INF));
- iassert(instr->repeat == 0);
- iassert(util_is_power_of_two_or_zero(dst->wrmask + 1));
-
- unsigned components = util_last_bit(dst->wrmask);
- cat1->repeat = components - 1;
- cat1->src_type = cat1->dst_type = TYPE_U32;
-
- break;
- }
- default:
- iassert(0);
- }
-
- cat1->dst = reg(dst, IR3_REG_RELATIV | IR3_REG_EVEN |
- IR3_REG_R | IR3_REG_POS_INF | IR3_REG_HALF | IR3_REG_SHARED);
- cat1->ss = !!(instr->flags & IR3_INSTR_SS);
- cat1->ul = !!(instr->flags & IR3_INSTR_UL);
- cat1->dst_rel = !!(dst->flags & IR3_REG_RELATIV);
- cat1->opc = instr->opc;
- cat1->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
- cat1->sync = !!(instr->flags & IR3_INSTR_SY);
- cat1->opc_cat = 1;
-
- return 0;
-}
-
-static int emit_cat2(struct ir3_instruction *instr, void *ptr)
-{
- struct ir3_register *dst = instr->regs[0];
- struct ir3_register *src1 = instr->regs[1];
- struct ir3_register *src2 = (instr->regs_count > 2) ? instr->regs[2] : NULL;
- instr_cat2_t *cat2 = ptr;
- unsigned absneg = ir3_cat2_absneg(instr->opc);
-
- iassert((instr->regs_count == 2) || (instr->regs_count == 3));
-
- if (instr->nop) {
- iassert(!instr->repeat);
- iassert(instr->nop <= 3);
-
- cat2->src1_r = instr->nop & 0x1;
- cat2->src2_r = (instr->nop >> 1) & 0x1;
- } else {
- cat2->src1_r = !!(src1->flags & IR3_REG_R);
- if (src2)
- cat2->src2_r = !!(src2->flags & IR3_REG_R);
- }
-
- if (src1->flags & IR3_REG_RELATIV) {
- iassert(src1->array.offset < (1 << 10));
- cat2->rel1.src1 = reg(src1,
- IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_R |
- IR3_REG_HALF | IR3_REG_SHARED | absneg);
- cat2->rel1.src1_c = !!(src1->flags & IR3_REG_CONST);
- cat2->rel1.src1_rel = 1;
- } else if (src1->flags & IR3_REG_CONST) {
- iassert(src1->num < (1 << 12));
- cat2->c1.src1 = reg(src1,
- IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF |
- absneg);
- cat2->c1.src1_c = 1;
- } else {
- iassert(src1->num < (1 << 11));
- cat2->src1 = reg(src1,
- IR3_REG_IMMED | IR3_REG_R | IR3_REG_HALF | IR3_REG_SHARED |
- absneg);
- }
- cat2->src1_im = !!(src1->flags & IR3_REG_IMMED);
- cat2->src1_neg = !!(src1->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT));
- cat2->src1_abs = !!(src1->flags & (IR3_REG_FABS | IR3_REG_SABS));
-
- if (src2) {
- iassert((src2->flags & IR3_REG_IMMED) ||
- !((src1->flags ^ src2->flags) & IR3_REG_HALF));
-
- if (src2->flags & IR3_REG_RELATIV) {
- iassert(src2->array.offset < (1 << 10));
- cat2->rel2.src2 = reg(src2,
- IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_R |
- IR3_REG_HALF | IR3_REG_SHARED | absneg);
- cat2->rel2.src2_c = !!(src2->flags & IR3_REG_CONST);
- cat2->rel2.src2_rel = 1;
- } else if (src2->flags & IR3_REG_CONST) {
- iassert(src2->num < (1 << 12));
- cat2->c2.src2 = reg(src2,
- IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF |
- absneg);
- cat2->c2.src2_c = 1;
- } else {
- iassert(src2->num < (1 << 11));
- cat2->src2 = reg(src2,
- IR3_REG_IMMED | IR3_REG_R | IR3_REG_HALF | IR3_REG_SHARED |
- absneg);
- }
-
- cat2->src2_im = !!(src2->flags & IR3_REG_IMMED);
- cat2->src2_neg = !!(src2->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT));
- cat2->src2_abs = !!(src2->flags & (IR3_REG_FABS | IR3_REG_SABS));
- }
-
- if (!ir3_cat2_int(instr->opc)) {
- /* For floating point ALU with immediate arg, it will be a
- * FLUT index
- */
- if (src1->flags & IR3_REG_IMMED) {
- cat2->must_be_zero1 = 1;
- if (src1->flags & IR3_REG_HALF)
- cat2->src1 |= 0x400;
- }
-
- if (src2 && (src2->flags & IR3_REG_IMMED)) {
- cat2->must_be_zero2 = 1;
- if (src2->flags & IR3_REG_HALF)
- cat2->src2 |= 0x400;
- }
- }
-
- cat2->dst = reg(dst, IR3_REG_R | IR3_REG_EI | IR3_REG_HALF | IR3_REG_SHARED);
- 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);
- /* dst widen/narrow doesn't apply to p0.c */
- if (dst->num < regid(REG_P0, 0))
- cat2->dst_half = !!((src1->flags ^ dst->flags) & IR3_REG_HALF);
- cat2->ei = !!(dst->flags & IR3_REG_EI);
- cat2->cond = instr->cat2.condition;
- cat2->full = ! (src1->flags & IR3_REG_HALF);
- cat2->opc = instr->opc;
- cat2->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
- cat2->sync = !!(instr->flags & IR3_INSTR_SY);
- cat2->opc_cat = 2;
-
- return 0;
-}
-
-static int emit_cat3(struct ir3_instruction *instr, void *ptr)
-{
- struct ir3_register *dst = instr->regs[0];
- struct ir3_register *src1 = instr->regs[1];
- struct ir3_register *src2 = instr->regs[2];
- struct ir3_register *src3 = instr->regs[3];
- unsigned absneg = ir3_cat3_absneg(instr->opc);
- instr_cat3_t *cat3 = ptr;
- uint32_t src_flags = 0;
-
- switch (instr->opc) {
- case OPC_MAD_F16:
- case OPC_MAD_U16:
- case OPC_MAD_S16:
- case OPC_SEL_B16:
- case OPC_SEL_S16:
- case OPC_SEL_F16:
- case OPC_SAD_S16:
- case OPC_SAD_S32: // really??
- src_flags |= IR3_REG_HALF;
- break;
- default:
- break;
- }
-
- iassert(instr->regs_count == 4);
- iassert(!((src1->flags ^ src_flags) & IR3_REG_HALF));
- iassert(!((src2->flags ^ src_flags) & IR3_REG_HALF));
- iassert(!((src3->flags ^ src_flags) & IR3_REG_HALF));
-
- if (instr->nop) {
- iassert(!instr->repeat);
- iassert(instr->nop <= 3);
-
- cat3->src1_r = instr->nop & 0x1;
- cat3->src2_r = (instr->nop >> 1) & 0x1;
- } else {
- cat3->src1_r = !!(src1->flags & IR3_REG_R);
- cat3->src2_r = !!(src2->flags & IR3_REG_R);
- }
-
- if (src1->flags & IR3_REG_RELATIV) {
- iassert(src1->array.offset < (1 << 10));
- cat3->rel1.src1 = reg(src1,
- IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_R |
- IR3_REG_HALF | IR3_REG_SHARED | absneg);
- cat3->rel1.src1_c = !!(src1->flags & IR3_REG_CONST);
- cat3->rel1.src1_rel = 1;
- } else if (src1->flags & IR3_REG_CONST) {
- iassert(src1->num < (1 << 12));
- cat3->c1.src1 = reg(src1,
- IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF | absneg);
- cat3->c1.src1_c = 1;
- } else {
- iassert(src1->num < (1 << 11));
- cat3->src1 = reg(src1,
- IR3_REG_R | IR3_REG_HALF | IR3_REG_SHARED | absneg);
- }
-
- cat3->src1_neg = !!(src1->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT));
-
- cat3->src2 = reg(src2,
- IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF | IR3_REG_SHARED | absneg);
- cat3->src2_c = !!(src2->flags & IR3_REG_CONST);
- cat3->src2_neg = !!(src2->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT));
-
- if (src3->flags & IR3_REG_RELATIV) {
- iassert(src3->array.offset < (1 << 10));
- cat3->rel2.src3 = reg(src3,
- IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_R |
- IR3_REG_HALF | IR3_REG_SHARED | absneg);
- cat3->rel2.src3_c = !!(src3->flags & IR3_REG_CONST);
- cat3->rel2.src3_rel = 1;
- } else if (src3->flags & IR3_REG_CONST) {
- iassert(src3->num < (1 << 12));
- cat3->c2.src3 = reg(src3,
- IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF | absneg);
- cat3->c2.src3_c = 1;
- } else {
- iassert(src3->num < (1 << 11));
- cat3->src3 = reg(src3,
- IR3_REG_R | IR3_REG_HALF | IR3_REG_SHARED | absneg);
- }
-
- cat3->src3_neg = !!(src3->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT));
- cat3->src3_r = !!(src3->flags & IR3_REG_R);
-
- cat3->dst = reg(dst, IR3_REG_R | IR3_REG_HALF | IR3_REG_SHARED);
- 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);
- cat3->opc = instr->opc;
- cat3->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
- cat3->sync = !!(instr->flags & IR3_INSTR_SY);
- cat3->opc_cat = 3;
-
- return 0;
-}
-
-static int emit_cat4(struct ir3_instruction *instr, void *ptr)
-{
- struct ir3_register *dst = instr->regs[0];
- struct ir3_register *src = instr->regs[1];
- instr_cat4_t *cat4 = ptr;
-
- iassert(instr->regs_count == 2);
-
- if (src->flags & IR3_REG_RELATIV) {
- iassert(src->array.offset < (1 << 10));
- cat4->rel.src = reg(src,
- IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_FNEG |
- IR3_REG_FABS | IR3_REG_R | IR3_REG_HALF);
- cat4->rel.src_c = !!(src->flags & IR3_REG_CONST);
- cat4->rel.src_rel = 1;
- } else if (src->flags & IR3_REG_CONST) {
- iassert(src->num < (1 << 12));
- cat4->c.src = reg(src,
- IR3_REG_CONST | IR3_REG_FNEG | IR3_REG_FABS |
- IR3_REG_R | IR3_REG_HALF);
- cat4->c.src_c = 1;
- } else {
- iassert(src->num < (1 << 11));
- cat4->src = reg(src,
- IR3_REG_IMMED | IR3_REG_FNEG | IR3_REG_FABS |
- IR3_REG_R | IR3_REG_HALF);
- }
-
- cat4->src_im = !!(src->flags & IR3_REG_IMMED);
- cat4->src_neg = !!(src->flags & IR3_REG_FNEG);
- cat4->src_abs = !!(src->flags & IR3_REG_FABS);
- cat4->src_r = !!(src->flags & IR3_REG_R);
-
- cat4->dst = reg(dst, 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);
- cat4->full = ! (src->flags & IR3_REG_HALF);
- cat4->opc = instr->opc;
- cat4->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
- cat4->sync = !!(instr->flags & IR3_INSTR_SY);
- cat4->opc_cat = 4;
-
- return 0;
-}
-
-static int emit_cat5(struct ir3_instruction *instr, void *ptr)
-{
- struct ir3_register *dst = instr->regs[0];
- /* To simplify things when there could be zero, one, or two args other
- * than tex/sampler idx, we use the first src reg in the ir to hold
- * samp_tex hvec2:
- */
- struct ir3_register *src1;
- struct ir3_register *src2;
- instr_cat5_t *cat5 = ptr;
-
- iassert((instr->regs_count == 1) ||
- (instr->regs_count == 2) ||
- (instr->regs_count == 3) ||
- (instr->regs_count == 4));
-
- if (instr->flags & IR3_INSTR_S2EN) {
- src1 = instr->regs[2];
- src2 = instr->regs_count > 3 ? instr->regs[3] : NULL;
- } else {
- src1 = instr->regs_count > 1 ? instr->regs[1] : NULL;
- src2 = instr->regs_count > 2 ? instr->regs[2] : NULL;
- }
-
- assume(src1 || !src2);
-
- if (src1) {
- cat5->full = ! (src1->flags & IR3_REG_HALF);
- cat5->src1 = reg(src1, IR3_REG_HALF);
- }
-
- if (src2) {
- iassert(!((src1->flags ^ src2->flags) & IR3_REG_HALF));
- cat5->src2 = reg(src2, IR3_REG_HALF);
- }
-
- if (instr->flags & IR3_INSTR_B) {
- cat5->s2en_bindless.base_hi = instr->cat5.tex_base >> 1;
- cat5->base_lo = instr->cat5.tex_base & 1;
- }
-
- if (instr->flags & IR3_INSTR_S2EN) {
- struct ir3_register *samp_tex = instr->regs[1];
- cat5->s2en_bindless.src3 = reg(samp_tex,
- (instr->flags & IR3_INSTR_B) ? 0 : IR3_REG_HALF);
- if (instr->flags & IR3_INSTR_B) {
- if (instr->flags & IR3_INSTR_A1EN) {
- cat5->s2en_bindless.desc_mode = CAT5_BINDLESS_A1_UNIFORM;
- } else {
- cat5->s2en_bindless.desc_mode = CAT5_BINDLESS_UNIFORM;
- }
- } else {
- /* TODO: This should probably be CAT5_UNIFORM, at least on a6xx,
- * as this is what the blob does and it is presumably faster, but
- * first we should confirm it is actually nonuniform and figure
- * out when the whole descriptor mode mechanism was introduced.
- */
- cat5->s2en_bindless.desc_mode = CAT5_NONUNIFORM;
- }
- iassert(!(instr->cat5.samp | instr->cat5.tex));
- } else if (instr->flags & IR3_INSTR_B) {
- cat5->s2en_bindless.src3 = instr->cat5.samp;
- if (instr->flags & IR3_INSTR_A1EN) {
- cat5->s2en_bindless.desc_mode = CAT5_BINDLESS_A1_IMM;
- } else {
- cat5->s2en_bindless.desc_mode = CAT5_BINDLESS_IMM;
- }
- } else {
- cat5->norm.samp = instr->cat5.samp;
- cat5->norm.tex = instr->cat5.tex;
- }
-
- cat5->dst = reg(dst, IR3_REG_R | IR3_REG_HALF);
- cat5->wrmask = dst->wrmask;
- cat5->type = instr->cat5.type;
- cat5->is_3d = !!(instr->flags & IR3_INSTR_3D);
- cat5->is_a = !!(instr->flags & IR3_INSTR_A);
- cat5->is_s = !!(instr->flags & IR3_INSTR_S);
- cat5->is_s2en_bindless = !!(instr->flags & (IR3_INSTR_S2EN | IR3_INSTR_B));
- cat5->is_o = !!(instr->flags & IR3_INSTR_O);
- cat5->is_p = !!(instr->flags & IR3_INSTR_P);
- cat5->opc = instr->opc;
- cat5->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
- cat5->sync = !!(instr->flags & IR3_INSTR_SY);
- cat5->opc_cat = 5;
-
- return 0;
-}
-
-static int emit_cat6_a6xx(struct ir3_instruction *instr, void *ptr)
-{
- instr_cat6_a6xx_t *cat6 = ptr;
-
- cat6->type = instr->cat6.type;
- cat6->opc = instr->opc;
- cat6->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
- cat6->sync = !!(instr->flags & IR3_INSTR_SY);
- cat6->opc_cat = 6;
-
- if (instr->opc == OPC_GETWID || instr->opc == OPC_GETSPID) {
- cat6->src2 = reg(instr->regs[0], 0);
- cat6->src1 = cat6->ssbo = 0;
- cat6->d = cat6->typed = cat6->type_size = 0;
- } else {
- struct ir3_register *ssbo = instr->regs[1];
- cat6->d = instr->cat6.d - (instr->opc == OPC_LDC ? 0 : 1);
- cat6->typed = instr->cat6.typed;
- cat6->type_size = instr->cat6.iim_val - 1;
- cat6->ssbo = reg(ssbo, IR3_REG_IMMED);
-
- /* For unused sources in an opcode, initialize contents with the ir3
- * dest reg
- */
- switch (instr->opc) {
- case OPC_RESINFO:
- cat6->src1 = reg(instr->regs[0], 0);
- cat6->src2 = reg(instr->regs[0], 0);
- break;
- case OPC_LDC:
- case OPC_LDIB:
- cat6->src1 = reg(instr->regs[2], 0);
- cat6->src2 = reg(instr->regs[0], 0);
- break;
- default:
- cat6->src1 = reg(instr->regs[2], 0);
- cat6->src2 = reg(instr->regs[3], 0);
- break;
- }
-
- if (instr->flags & IR3_INSTR_B) {
- if (ssbo->flags & IR3_REG_IMMED) {
- cat6->desc_mode = CAT6_BINDLESS_IMM;
- } else if (instr->flags & IR3_INSTR_NONUNIF) {
- cat6->desc_mode = CAT6_BINDLESS_NONUNIFORM;
- } else {
- cat6->desc_mode = CAT6_BINDLESS_UNIFORM;
- }
- cat6->base = instr->cat6.base;
- } else {
- if (ssbo->flags & IR3_REG_IMMED) {
- cat6->desc_mode = CAT6_IMM;
- } else if (instr->flags & IR3_INSTR_NONUNIF) {
- cat6->desc_mode = CAT6_NONUNIFORM;
- } else {
- cat6->desc_mode = CAT6_UNIFORM;
- }
- }
- }
-
- switch (instr->opc) {
- 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:
- cat6->pad1 = 0x1;
- cat6->pad3 = 0x6;
- cat6->pad5 = 0x3;
- break;
- case OPC_STIB:
- case OPC_LDIB:
- case OPC_RESINFO:
- cat6->pad1 = 0x0;
- cat6->pad3 = 0x6;
- cat6->pad5 = 0x2;
- break;
- case OPC_LDC:
- case OPC_GETWID:
- case OPC_GETSPID:
- cat6->pad1 = 0x0;
- cat6->pad3 = 0x4;
- cat6->pad5 = 0x2;
- break;
- default:
- iassert(0);
- }
- cat6->pad2 = 0x0;
- cat6->pad4 = 0x0;
-
- return 0;
-}
-
-static int emit_cat6(struct ir3_instruction *instr, void *ptr)
-{
- struct ir3_register *dst, *src1, *src2;
- instr_cat6_t *cat6 = ptr;
-
- /* In a6xx we start using a new instruction encoding for some of
- * these instructions:
- */
- if (instr->block->shader->compiler->gpu_id >= 600) {
- switch (instr->opc) {
- 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:
- /* The shared variants of these still use the old encoding: */
- if (!(instr->flags & IR3_INSTR_G))
- break;
- /* fallthrough */
- case OPC_STIB:
- case OPC_LDIB:
- case OPC_LDC:
- case OPC_RESINFO:
- case OPC_GETSPID:
- case OPC_GETWID:
- return emit_cat6_a6xx(instr, ptr);
- default:
- break;
- }
- }
-
- bool type_full = type_size(instr->cat6.type) == 32;
-
- cat6->type = instr->cat6.type;
- cat6->opc = instr->opc;
- cat6->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
- cat6->sync = !!(instr->flags & IR3_INSTR_SY);
- cat6->g = !!(instr->flags & IR3_INSTR_G);
- cat6->opc_cat = 6;
-
- switch (instr->opc) {
- case OPC_RESINFO:
- case OPC_RESFMT:
- iassert_type(instr->regs[0], type_full); /* dst */
- iassert_type(instr->regs[1], type_full); /* src1 */
- break;
- case OPC_L2G:
- case OPC_G2L:
- iassert_type(instr->regs[0], true); /* dst */
- iassert_type(instr->regs[1], true); /* src1 */
- break;
- case OPC_STG:
- case OPC_STL:
- case OPC_STP:
- case OPC_STLW:
- case OPC_STIB:
- /* no dst, so regs[0] is dummy */
- iassert_type(instr->regs[1], true); /* dst */
- iassert_type(instr->regs[2], type_full); /* src1 */
- iassert_type(instr->regs[3], true); /* src2 */
- break;
- default:
- iassert_type(instr->regs[0], type_full); /* dst */
- iassert_type(instr->regs[1], true); /* src1 */
- if (instr->regs_count > 2)
- iassert_type(instr->regs[2], true); /* src1 */
- break;
- }
-
- /* the "dst" for a store instruction is (from the perspective
- * of data flow in the shader, ie. register use/def, etc) in
- * fact a register that is read by the instruction, rather
- * than written:
- */
- if (is_store(instr)) {
- iassert(instr->regs_count >= 3);
-
- dst = instr->regs[1];
- src1 = instr->regs[2];
- src2 = (instr->regs_count >= 4) ? instr->regs[3] : NULL;
- } else {
- iassert(instr->regs_count >= 2);
-
- dst = instr->regs[0];
- src1 = instr->regs[1];
- src2 = (instr->regs_count >= 3) ? instr->regs[2] : NULL;
- }
-
- /* TODO we need a more comprehensive list about which instructions
- * can be encoded which way. Or possibly use IR3_INSTR_0 flag to
- * indicate to use the src_off encoding even if offset is zero
- * (but then what to do about dst_off?)
- */
- if (is_atomic(instr->opc)) {
- instr_cat6ldgb_t *ldgb = ptr;
-
- /* maybe these two bits both determine the instruction encoding? */
- cat6->src_off = false;
-
- ldgb->d = instr->cat6.d - 1;
- ldgb->typed = instr->cat6.typed;
- ldgb->type_size = instr->cat6.iim_val - 1;
-
- ldgb->dst = reg(dst, IR3_REG_R | IR3_REG_HALF);
-
- if (ldgb->g) {
- struct ir3_register *src3 = instr->regs[3];
- struct ir3_register *src4 = instr->regs[4];
-
- /* first src is src_ssbo: */
- iassert(src1->flags & IR3_REG_IMMED);
- ldgb->src_ssbo = src1->uim_val;
- ldgb->src_ssbo_im = 0x1;
-
- ldgb->src1 = reg(src2, IR3_REG_IMMED);
- ldgb->src1_im = !!(src2->flags & IR3_REG_IMMED);
- ldgb->src2 = reg(src3, IR3_REG_IMMED);
- ldgb->src2_im = !!(src3->flags & IR3_REG_IMMED);
-
- ldgb->src3 = reg(src4, 0);
- ldgb->pad0 = 0x1;
- } else {
- ldgb->src1 = reg(src1, IR3_REG_IMMED);
- ldgb->src1_im = !!(src1->flags & IR3_REG_IMMED);
- ldgb->src2 = reg(src2, IR3_REG_IMMED);
- ldgb->src2_im = !!(src2->flags & IR3_REG_IMMED);
- ldgb->pad0 = 0x1;
- ldgb->src_ssbo_im = 0x0;
- }
-
- return 0;
- } else if (instr->opc == OPC_LDGB) {
- struct ir3_register *src3 = instr->regs[3];
- instr_cat6ldgb_t *ldgb = ptr;
-
- /* maybe these two bits both determine the instruction encoding? */
- cat6->src_off = false;
-
- ldgb->d = instr->cat6.d - 1;
- ldgb->typed = instr->cat6.typed;
- ldgb->type_size = instr->cat6.iim_val - 1;
-
- ldgb->dst = reg(dst, IR3_REG_R | IR3_REG_HALF);
-
- /* first src is src_ssbo: */
- iassert(src1->flags & IR3_REG_IMMED);
- ldgb->src_ssbo = src1->uim_val;
-
- /* then next two are src1/src2: */
- ldgb->src1 = reg(src2, IR3_REG_IMMED);
- ldgb->src1_im = !!(src2->flags & IR3_REG_IMMED);
- ldgb->src2 = reg(src3, IR3_REG_IMMED);
- ldgb->src2_im = !!(src3->flags & IR3_REG_IMMED);
-
- ldgb->pad0 = 0x0;
- ldgb->src_ssbo_im = true;
-
- return 0;
- } else if (instr->opc == OPC_RESINFO) {
- instr_cat6ldgb_t *ldgb = ptr;
-
- ldgb->d = instr->cat6.d - 1;
-
- ldgb->dst = reg(dst, IR3_REG_R | IR3_REG_HALF);
-
- /* first src is src_ssbo: */
- ldgb->src_ssbo = reg(src1, IR3_REG_IMMED);
- ldgb->src_ssbo_im = !!(src1->flags & IR3_REG_IMMED);
-
- return 0;
- } else if ((instr->opc == OPC_STGB) || (instr->opc == OPC_STIB)) {
- struct ir3_register *src3 = instr->regs[4];
- instr_cat6stgb_t *stgb = ptr;
-
- /* maybe these two bits both determine the instruction encoding? */
- cat6->src_off = true;
- stgb->pad3 = 0x2;
-
- stgb->d = instr->cat6.d - 1;
- stgb->typed = instr->cat6.typed;
- stgb->type_size = instr->cat6.iim_val - 1;
-
- /* first src is dst_ssbo: */
- iassert(dst->flags & IR3_REG_IMMED);
- stgb->dst_ssbo = dst->uim_val;
-
- /* then src1/src2/src3: */
- stgb->src1 = reg(src1, 0);
- stgb->src2 = reg(src2, IR3_REG_IMMED);
- stgb->src2_im = !!(src2->flags & IR3_REG_IMMED);
- stgb->src3 = reg(src3, IR3_REG_IMMED);
- stgb->src3_im = !!(src3->flags & IR3_REG_IMMED);
-
- return 0;
- } else if ((instr->opc == OPC_LDG) || (instr->opc == OPC_LDL) ||
- (instr->opc == OPC_LDLW) || (instr->opc == OPC_LDP)) {
- struct ir3_register *src3 = instr->regs[3];
- instr_cat6a_t *cat6a = ptr;
-
- cat6->src_off = true;
-
- if (instr->opc == OPC_LDG) {
- /* For LDG src1 can not be immediate, so src1_imm is redundant and
- * instead used to signal whether (when true) 'off' is a 32 bit
- * register or an immediate offset.
- */
- cat6a->src1 = reg(src1, 0);
- cat6a->src1_im = !(src2->flags & IR3_REG_IMMED);
- cat6a->off = reg(src2, IR3_REG_IMMED);
- } else {
- cat6a->src1 = reg(src1, IR3_REG_IMMED);
- cat6a->src1_im = !!(src1->flags & IR3_REG_IMMED);
- cat6a->off = reg(src2, IR3_REG_IMMED);
- iassert(src2->flags & IR3_REG_IMMED);
- }
-
- /* Num components */
- cat6a->src3 = reg(src3, IR3_REG_IMMED);
- cat6a->src3_im = true;
- } else {
- instr_cat6b_t *cat6b = ptr;
-
- cat6->src_off = false;
-
- cat6b->src1 = reg(src1, IR3_REG_IMMED | IR3_REG_HALF);
- cat6b->src1_im = !!(src1->flags & IR3_REG_IMMED);
- if (src2) {
- cat6b->src2 = reg(src2, IR3_REG_IMMED);
- cat6b->src2_im = !!(src2->flags & IR3_REG_IMMED);
- }
- }
-
- if (instr->cat6.dst_offset || (instr->opc == OPC_STG) ||
- (instr->opc == OPC_STL) || (instr->opc == OPC_STLW) ||
- (instr->opc == OPC_STP)) {
- instr_cat6c_t *cat6c = ptr;
- cat6->dst_off = true;
- cat6c->dst = reg(dst, IR3_REG_R | IR3_REG_HALF);
-
- if (instr->flags & IR3_INSTR_G) {
- struct ir3_register *src3 = instr->regs[4];
- cat6c->off = reg(src3, IR3_REG_R | IR3_REG_HALF);
- if (src3->flags & IR3_REG_IMMED) {
- /* Immediate offsets are in bytes... */
- cat6->g = false;
- cat6c->off *= 4;
- }
- } else {
- cat6c->off = instr->cat6.dst_offset;
- cat6c->off_high = instr->cat6.dst_offset >> 8;
- }
- } else {
- instr_cat6d_t *cat6d = ptr;
- cat6->dst_off = false;
- cat6d->dst = reg(dst, IR3_REG_R | IR3_REG_HALF);
- }
-
- return 0;
-}
-
-static int emit_cat7(struct ir3_instruction *instr, void *ptr)
-{
- instr_cat7_t *cat7 = ptr;
-
- cat7->ss = !!(instr->flags & IR3_INSTR_SS);
- cat7->w = instr->cat7.w;
- cat7->r = instr->cat7.r;
- cat7->l = instr->cat7.l;
- cat7->g = instr->cat7.g;
- cat7->opc = instr->opc;
- cat7->jmp_tgt = !!(instr->flags & IR3_INSTR_JP);
- cat7->sync = !!(instr->flags & IR3_INSTR_SY);
- cat7->opc_cat = 7;
-
- return 0;
-}
-
-static int (*emit[])(struct ir3_instruction *instr, void *ptr) = {
- emit_cat0, emit_cat1, emit_cat2, emit_cat3, emit_cat4, emit_cat5, emit_cat6,
- emit_cat7,
-};
-
static void
collect_reg_info(struct ir3_instruction *instr, struct ir3_register *reg,
struct ir3_info *info)
@@ -997,8 +134,7 @@ ir3_collect_info(struct ir3_shader_variant *v)
* doesn't try to decode the following data as instructions (such as the
* next stage's shader in turnip)
*/
- info->size = MAX2(v->instrlen * compiler->instr_align, instr_count + 4) *
- sizeof(instr_t);
+ info->size = MAX2(v->instrlen * compiler->instr_align, instr_count + 4) * 8;
info->sizedwords = info->size / 4;
foreach_block (block, &shader->block_list) {
@@ -1066,30 +202,6 @@ ir3_collect_info(struct ir3_shader_variant *v)
}
}
-void * ir3_assemble(struct ir3_shader_variant *v)
-{
- uint32_t *ptr, *dwords;
- const struct ir3_info *info = &v->info;
- struct ir3 *shader = v->ir;
-
- ptr = dwords = rzalloc_size(v, info->size);
-
- foreach_block (block, &shader->block_list) {
- foreach_instr (instr, &block->instr_list) {
- int ret = emit[opc_cat(instr->opc)](instr, dwords);
- if (ret)
- goto fail;
- dwords += 2;
- }
- }
-
- return ptr;
-
-fail:
- ralloc_free(ptr);
- return NULL;
-}
-
static struct ir3_register * reg_create(struct ir3 *shader,
int num, int flags)
{
diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h
index aedbd403a5f..0b9c389a83b 100644
--- a/src/freedreno/ir3/ir3.h
+++ b/src/freedreno/ir3/ir3.h
@@ -581,7 +581,6 @@ struct ir3 * ir3_create(struct ir3_compiler *compiler, struct ir3_shader_variant
void ir3_destroy(struct ir3 *shader);
void ir3_collect_info(struct ir3_shader_variant *v);
-void * ir3_assemble(struct ir3_shader_variant *v);
void * ir3_alloc(struct ir3 *shader, int sz);
struct ir3_block * ir3_block_create(struct ir3 *shader);
More information about the mesa-commit
mailing list