From 2f8bdf2e2b8cc516b89cd042962d5dab81a695ec Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 8 Nov 2017 18:08:16 -0500 Subject: [PATCH] freedreno/ir3: split out INSTR4F instructions Atomic instructions take a different # of src args depending on .g or .l variant, split these out into different helpers with INSTR*F() helper macro that lets you specify instruction flag. Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/ir3/ir3.h | 73 ++++++++++++++----- .../drivers/freedreno/ir3/ir3_compiler_nir.c | 20 ++--- 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index 4658674488a..b85e5e38bda 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -1068,11 +1068,30 @@ ir3_##name(struct ir3_block *block, \ return instr; \ } +#define INSTR4F(f, name) \ +static inline struct ir3_instruction * \ +ir3_##name##_##f(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 *d, unsigned dflags) \ +{ \ + struct ir3_instruction *instr = \ + ir3_instr_create2(block, OPC_##name, 5); \ + 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; \ + ir3_reg_create(instr, 0, IR3_REG_SSA | dflags)->instr = d; \ + instr->flags |= IR3_INSTR_##f; \ + return instr; \ +} + /* cat0 instructions: */ -INSTR0(BR); -INSTR0(JUMP); -INSTR1(KILL); -INSTR0(END); +INSTR0(BR) +INSTR0(JUMP) +INSTR1(KILL) +INSTR0(END) /* cat2 instructions, most 2 src but some 1 src: */ INSTR2(ADD_F) @@ -1184,24 +1203,40 @@ ir3_SAM(struct ir3_block *block, opc_t opc, type_t type, /* cat6 instructions: */ INSTR2(LDLV) INSTR2(LDG) +INSTR2(LDL) INSTR3(STG) -INSTR3(LDGB); -INSTR4(STGB); -INSTR4(ATOMIC_ADD); -INSTR4(ATOMIC_SUB); -INSTR4(ATOMIC_XCHG); -INSTR4(ATOMIC_INC); -INSTR4(ATOMIC_DEC); -INSTR4(ATOMIC_CMPXCHG); -INSTR4(ATOMIC_MIN); -INSTR4(ATOMIC_MAX); -INSTR4(ATOMIC_AND); -INSTR4(ATOMIC_OR); -INSTR4(ATOMIC_XOR); +INSTR3(STL) +INSTR3(LDGB) +INSTR4(STGB) +INSTR4(STIB) +INSTR1(RESINFO) +INSTR1(RESFMT) +INSTR2(ATOMIC_ADD) +INSTR2(ATOMIC_SUB) +INSTR2(ATOMIC_XCHG) +INSTR2(ATOMIC_INC) +INSTR2(ATOMIC_DEC) +INSTR2(ATOMIC_CMPXCHG) +INSTR2(ATOMIC_MIN) +INSTR2(ATOMIC_MAX) +INSTR2(ATOMIC_AND) +INSTR2(ATOMIC_OR) +INSTR2(ATOMIC_XOR) +INSTR4F(G, ATOMIC_ADD) +INSTR4F(G, ATOMIC_SUB) +INSTR4F(G, ATOMIC_XCHG) +INSTR4F(G, ATOMIC_INC) +INSTR4F(G, ATOMIC_DEC) +INSTR4F(G, ATOMIC_CMPXCHG) +INSTR4F(G, ATOMIC_MIN) +INSTR4F(G, ATOMIC_MAX) +INSTR4F(G, ATOMIC_AND) +INSTR4F(G, ATOMIC_OR) +INSTR4F(G, ATOMIC_XOR) /* cat7 instructions: */ -INSTR0(BAR); -INSTR0(FENCE); +INSTR0(BAR) +INSTR0(FENCE) /* ************************************************************************* */ /* split this out or find some helper to use.. like main/bitset.h.. */ diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index ba0db12e04c..f464d487ca7 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -1356,33 +1356,33 @@ emit_intrinsic_atomic(struct ir3_context *ctx, nir_intrinsic_instr *intr) switch (intr->intrinsic) { case nir_intrinsic_ssbo_atomic_add: - atomic = ir3_ATOMIC_ADD(b, ssbo, 0, src0, 0, src1, 0, src2, 0); + atomic = ir3_ATOMIC_ADD_G(b, ssbo, 0, src0, 0, src1, 0, src2, 0); break; case nir_intrinsic_ssbo_atomic_imin: - atomic = ir3_ATOMIC_MIN(b, ssbo, 0, src0, 0, src1, 0, src2, 0); + atomic = ir3_ATOMIC_MIN_G(b, ssbo, 0, src0, 0, src1, 0, src2, 0); type = TYPE_S32; break; case nir_intrinsic_ssbo_atomic_umin: - atomic = ir3_ATOMIC_MIN(b, ssbo, 0, src0, 0, src1, 0, src2, 0); + atomic = ir3_ATOMIC_MIN_G(b, ssbo, 0, src0, 0, src1, 0, src2, 0); break; case nir_intrinsic_ssbo_atomic_imax: - atomic = ir3_ATOMIC_MAX(b, ssbo, 0, src0, 0, src1, 0, src2, 0); + atomic = ir3_ATOMIC_MAX_G(b, ssbo, 0, src0, 0, src1, 0, src2, 0); type = TYPE_S32; break; case nir_intrinsic_ssbo_atomic_umax: - atomic = ir3_ATOMIC_MAX(b, ssbo, 0, src0, 0, src1, 0, src2, 0); + atomic = ir3_ATOMIC_MAX_G(b, ssbo, 0, src0, 0, src1, 0, src2, 0); break; case nir_intrinsic_ssbo_atomic_and: - atomic = ir3_ATOMIC_AND(b, ssbo, 0, src0, 0, src1, 0, src2, 0); + atomic = ir3_ATOMIC_AND_G(b, ssbo, 0, src0, 0, src1, 0, src2, 0); break; case nir_intrinsic_ssbo_atomic_or: - atomic = ir3_ATOMIC_OR(b, ssbo, 0, src0, 0, src1, 0, src2, 0); + atomic = ir3_ATOMIC_OR_G(b, ssbo, 0, src0, 0, src1, 0, src2, 0); break; case nir_intrinsic_ssbo_atomic_xor: - atomic = ir3_ATOMIC_XOR(b, ssbo, 0, src0, 0, src1, 0, src2, 0); + atomic = ir3_ATOMIC_XOR_G(b, ssbo, 0, src0, 0, src1, 0, src2, 0); break; case nir_intrinsic_ssbo_atomic_exchange: - atomic = ir3_ATOMIC_XCHG(b, ssbo, 0, src0, 0, src1, 0, src2, 0); + atomic = ir3_ATOMIC_XCHG_G(b, ssbo, 0, src0, 0, src1, 0, src2, 0); break; case nir_intrinsic_ssbo_atomic_comp_swap: /* for cmpxchg, src0 is [ui]vec2(data, compare): */ @@ -1390,7 +1390,7 @@ emit_intrinsic_atomic(struct ir3_context *ctx, nir_intrinsic_instr *intr) src0, get_src(ctx, &intr->src[3])[0], }, 2); - atomic = ir3_ATOMIC_CMPXCHG(b, ssbo, 0, src0, 0, src1, 0, src2, 0); + atomic = ir3_ATOMIC_CMPXCHG_G(b, ssbo, 0, src0, 0, src1, 0, src2, 0); break; default: unreachable("boo"); -- 2.30.2