diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index d3ea24e3cb9..ad9592274b5 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -808,22 +808,10 @@ cat3_dp_signedness:'.' T_MIXED { instr->cat3.signedness = IR3_SRC_MIXED; } cat3_dp_pack: '.' T_LOW { instr->cat3.packed = IR3_SRC_PACKED_LOW; } | '.' T_HIGH { instr->cat3.packed = IR3_SRC_PACKED_HIGH; } -cat3_opc: T_OP_MAD_U16 { new_instr(OPC_MAD_U16); } -| T_OP_MADSH_U16 { new_instr(OPC_MADSH_U16); } -| T_OP_MAD_S16 { new_instr(OPC_MAD_S16); } -| T_OP_MADSH_M16 { new_instr(OPC_MADSH_M16); } -| T_OP_MAD_U24 { new_instr(OPC_MAD_U24); } -| T_OP_MAD_S24 { new_instr(OPC_MAD_S24); } -| T_OP_MAD_F16 { new_instr(OPC_MAD_F16); } +cat3_opc: T_OP_MAD_F16 { new_instr(OPC_MAD_F16); } | T_OP_MAD_F32 { new_instr(OPC_MAD_F32); } -| T_OP_SEL_B16 { new_instr(OPC_SEL_B16); } -| T_OP_SEL_B32 { new_instr(OPC_SEL_B32); } -| T_OP_SEL_S16 { new_instr(OPC_SEL_S16); } -| T_OP_SEL_S32 { new_instr(OPC_SEL_S32); } | T_OP_SEL_F16 { new_instr(OPC_SEL_F16); } | T_OP_SEL_F32 { new_instr(OPC_SEL_F32); } -| T_OP_SAD_S16 { new_instr(OPC_SAD_S16); } -| T_OP_SAD_S32 { new_instr(OPC_SAD_S32); } cat3_imm_reg_opc: T_OP_SHRM { new_instr(OPC_SHRM); } | T_OP_SHLM { new_instr(OPC_SHLM); } @@ -831,6 +819,20 @@ cat3_imm_reg_opc: T_OP_SHRM { new_instr(OPC_SHRM); } | T_OP_SHLG { new_instr(OPC_SHLG); } | T_OP_ANDG { new_instr(OPC_ANDG); } +cat3_reg_or_const_or_rel_opc: +| T_OP_MAD_U16 { new_instr(OPC_MAD_U16); } +| T_OP_MADSH_U16 { new_instr(OPC_MADSH_U16); } +| T_OP_MAD_S16 { new_instr(OPC_MAD_S16); } +| T_OP_MADSH_M16 { new_instr(OPC_MADSH_M16); } +| T_OP_MAD_U24 { new_instr(OPC_MAD_U24); } +| T_OP_MAD_S24 { new_instr(OPC_MAD_S24); } +| T_OP_SEL_B16 { new_instr(OPC_SEL_B16); } +| T_OP_SEL_B32 { new_instr(OPC_SEL_B32); } +| T_OP_SEL_S16 { new_instr(OPC_SEL_S16); } +| T_OP_SEL_S32 { new_instr(OPC_SEL_S32); } +| T_OP_SAD_S16 { new_instr(OPC_SAD_S16); } +| T_OP_SAD_S32 { new_instr(OPC_SAD_S32); } + cat3_wmm: T_OP_WMM { new_instr(OPC_WMM); } | T_OP_WMM_ACCU { new_instr(OPC_WMM_ACCU); } @@ -838,6 +840,7 @@ 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 +| 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 | cat3_dp cat3_dp_signedness cat3_dp_pack dst_reg ',' src_reg_or_rel_or_imm ',' src_reg_or_const ',' src_reg_or_rel_or_imm diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 396a9476c53..d539a66396a 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -152,6 +152,8 @@ static const struct test { INSTR_7XX(61808000_04020400, "madsh.m16 r0.x, (last)r0.x, r0.y, (last)r0.z"), 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"), /* 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 114b73f49d8..224e912d69f 100644 --- a/src/freedreno/isa/encode.c +++ b/src/freedreno/isa/encode.c @@ -270,6 +270,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_CONST_OR_IMMED, REG_CAT3_SRC_RELATIVE_GPR, REG_CAT3_SRC_RELATIVE_CONST, @@ -284,7 +285,21 @@ __cat3_src_case(struct encode_state *s, const struct ir3_register *reg) } else { return REG_CAT3_SRC_RELATIVE_GPR; } - } else if (reg->flags & (IR3_REG_CONST | IR3_REG_IMMED)) { + } 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: + assert(s->gen >= 800); + return REG_CAT3_SRC_ALT_IMMED; + } + } else if (reg->flags & IR3_REG_CONST) { return REG_CAT3_SRC_CONST_OR_IMMED; } else { return REG_CAT3_SRC_GPR; diff --git a/src/freedreno/isa/ir3-cat3.xml b/src/freedreno/isa/ir3-cat3.xml index 9d6b7b760dc..8b8b75b4332 100644 --- a/src/freedreno/isa/ir3-cat3.xml +++ b/src/freedreno/isa/ir3-cat3.xml @@ -53,6 +53,19 @@ SOFTWARE. + + + + + {IMMED} + + 00110 + + + extract_reg_uim(src) + + + {IMMED_ENCODING}