diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index a2a9f774d3e..a82e0eabea7 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -1738,6 +1738,41 @@ unsigned ir3_cat2_absneg(opc_t opc); unsigned ir3_cat3_absneg(struct ir3_compiler *compiler, opc_t opc, unsigned src_n); +static inline bool +ir3_cat3_int(opc_t opc) +{ + switch (opc) { + case OPC_MAD_F16: + case OPC_MAD_F32: + case OPC_SEL_F16: + case OPC_SEL_F32: + return false; + case OPC_MAD_U16: + case OPC_MADSH_U16: + case OPC_MAD_S16: + case OPC_MADSH_M16: + case OPC_MAD_U24: + case OPC_MAD_S24: + case OPC_SEL_B16: + case OPC_SEL_B32: + case OPC_SEL_S16: + case OPC_SEL_S32: + case OPC_SAD_S16: + case OPC_SAD_S32: + case OPC_SHRM: + case OPC_SHLM: + case OPC_SHRG: + case OPC_SHLG: + case OPC_ANDG: + case OPC_DP2ACC: + case OPC_DP4ACC: + case OPC_WMM: + case OPC_WMM_ACCU: + default: + return true; + } +} + /* Return the type (float, int, or uint) the op uses when converting from the * internal result of the op (which is assumed to be the same size as the * sources) to the destination when they are not the same size. If F32 it does diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index ad9592274b5..ce87dd489dd 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -839,7 +839,11 @@ cat3_wmm: T_OP_WMM { new_instr(OPC_WMM); } cat3_dp: T_OP_DP2ACC { new_instr(OPC_DP2ACC); } | T_OP_DP4ACC { new_instr(OPC_DP4ACC); } -cat3_instr: cat3_opc dst_reg ',' src_reg_or_const_or_rel ',' src_reg_or_const ',' src_reg_or_const_or_rel +src_reg_or_const_or_rel_or_flut: src_reg_or_const_or_rel +| flut_immed { new_src(0, IR3_REG_IMMED)->uim_val = $1; } +| 'h' flut_immed { new_src(0, IR3_REG_IMMED | IR3_REG_HALF)->uim_val = $2; } + +cat3_instr: cat3_opc dst_reg ',' src_reg_or_const_or_rel_or_flut ',' src_reg_or_const ',' src_reg_or_const_or_rel_or_flut | cat3_reg_or_const_or_rel_opc dst_reg ',' src_reg_or_const_or_rel_or_imm ',' src_reg_or_const ',' src_reg_or_const_or_rel_or_imm | cat3_imm_reg_opc dst_reg ',' src_reg_or_rel_or_imm ',' src_reg_or_const ',' src_reg_or_rel_or_imm | cat3_wmm dst_reg ',' src_reg_gpr ',' src_reg ',' immediate diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index d539a66396a..bdd28a2fedb 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -154,6 +154,7 @@ static const struct test { INSTR_7XX(64838806_04088406, "(nop3) sel.b32 r1.z, (last)r1.z, r1.w, (last)r2.x"), INSTR_8XX(6206000a_040a0610, "mad.u24 r2.z, 16, r3.x, (last)r2.z"), INSTR_8XX(62000800_06030402, "(nop1) mad.u24 r0.x, (last)r0.z, r0.x, 3"), + INSTR_8XX(63820009_07024409, "mad.f32 r2.y, (neg)(last)r2.y, r1.x, (1.0)"), /* cat4 */ INSTR_6XX(8010000a_00000003, "rcp r2.z, r0.w"), diff --git a/src/freedreno/isa/encode.c b/src/freedreno/isa/encode.c index 224e912d69f..7f975c84cd9 100644 --- a/src/freedreno/isa/encode.c +++ b/src/freedreno/isa/encode.c @@ -271,6 +271,7 @@ __multisrc_case(struct encode_state *s, const struct ir3_register *reg) typedef enum { REG_CAT3_SRC_GPR, REG_CAT3_SRC_ALT_IMMED, + REG_CAT3_SRC_FLUT, REG_CAT3_SRC_CONST_OR_IMMED, REG_CAT3_SRC_RELATIVE_GPR, REG_CAT3_SRC_RELATIVE_CONST, @@ -286,18 +287,23 @@ __cat3_src_case(struct encode_state *s, const struct ir3_register *reg) return REG_CAT3_SRC_RELATIVE_GPR; } } else if (reg->flags & IR3_REG_IMMED) { - switch (s->instr->opc) { - case OPC_SHRM: - case OPC_SHLM: - case OPC_SHRG: - case OPC_SHLG: - case OPC_ANDG: - case OPC_WMM: - case OPC_WMM_ACCU: - return REG_CAT3_SRC_CONST_OR_IMMED; - default: + if (ir3_cat3_int(s->instr->opc)) { + switch (s->instr->opc) { + case OPC_SHRM: + case OPC_SHLM: + case OPC_SHRG: + case OPC_SHLG: + case OPC_ANDG: + case OPC_WMM: + case OPC_WMM_ACCU: + return REG_CAT3_SRC_CONST_OR_IMMED; + default: + assert(s->gen >= 800); + return REG_CAT3_SRC_ALT_IMMED; + } + } else { assert(s->gen >= 800); - return REG_CAT3_SRC_ALT_IMMED; + return REG_CAT3_SRC_FLUT; } } else if (reg->flags & IR3_REG_CONST) { return REG_CAT3_SRC_CONST_OR_IMMED; diff --git a/src/freedreno/isa/ir3-cat3.xml b/src/freedreno/isa/ir3-cat3.xml index 8b8b75b4332..9834a99c7d7 100644 --- a/src/freedreno/isa/ir3-cat3.xml +++ b/src/freedreno/isa/ir3-cat3.xml @@ -52,6 +52,20 @@ SOFTWARE. + + + + {HALF}{IMMED} + + 00111 + + 000 + + + extract_reg_uim(src) + !!(src->flags & IR3_REG_HALF) + +