diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index a6546a4530a..c64bf5bc349 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -641,6 +641,18 @@ is_madsh(opc_t opc) } } +static inline bool +is_sad(opc_t opc) +{ + switch (opc) { + case OPC_SAD_S16: + case OPC_SAD_S32: + return true; + default: + return false; + } +} + static inline bool is_local_atomic(opc_t opc) { diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index c1f71dc8f10..8af7d85fcb0 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -1301,7 +1301,7 @@ ir3_valid_flags(struct ir3_instruction *instr, unsigned n, unsigned flags) break; case 3: valid_flags = - ir3_cat3_absneg(instr->opc) | IR3_REG_RELATIV | IR3_REG_SHARED; + ir3_cat3_absneg(instr->opc, n) | IR3_REG_RELATIV | IR3_REG_SHARED; switch (instr->opc) { case OPC_SHRM: diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 2ae55458743..accb8cc97a7 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -1699,7 +1699,7 @@ ir3_cat2_absneg(opc_t opc) /* map cat3 instructions to valid abs/neg flags: */ static inline unsigned -ir3_cat3_absneg(opc_t opc) +ir3_cat3_absneg(opc_t opc, unsigned src_n) { switch (opc) { case OPC_MAD_F16: @@ -1708,6 +1708,10 @@ ir3_cat3_absneg(opc_t opc) case OPC_SEL_F32: return IR3_REG_FNEG; + case OPC_SAD_S16: + case OPC_SAD_S32: + return src_n == 1 ? IR3_REG_SNEG : 0; + case OPC_MAD_U16: case OPC_MADSH_U16: case OPC_MAD_S16: @@ -1716,8 +1720,6 @@ ir3_cat3_absneg(opc_t opc) case OPC_MAD_S24: case OPC_SEL_S16: case OPC_SEL_S32: - case OPC_SAD_S16: - case OPC_SAD_S32: /* neg *may* work on 3rd src.. */ case OPC_SEL_B16: