ir3: Add support for ldc.u

This will be important for using shared registers as much as possible.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22075>
This commit is contained in:
Connor Abbott 2023-03-01 18:15:04 +01:00 committed by Marge Bot
parent 94c1ff415b
commit 736570b74d
7 changed files with 22 additions and 3 deletions

View File

@ -334,10 +334,14 @@ typedef enum ir3_instruction_flags {
IR3_INSTR_NONUNIF = BIT(13),
/* (cat5-only) Get some parts of the encoding from a1.x */
IR3_INSTR_A1EN = BIT(14),
/* uniform destination for ldc, which must be set if and only if it has a
* shared reg destination
*/
IR3_INSTR_U = BIT(15),
/* meta-flags, for intermediate stages of IR, ie.
* before register assignment is done:
*/
IR3_INSTR_MARK = BIT(15),
IR3_INSTR_MARK = BIT(16),
/* Used by shared register allocation when creating spill/reload instructions
* to inform validation that this is created by RA. This also may be set on

View File

@ -435,6 +435,7 @@ static int parse_reg(const char *str)
"s2en" return TOKEN(T_S2EN);
"s" return 's';
"k" return 'k';
"u" return 'u';
"base"[0-9]+ ir3_yylval.num = strtol(yytext+4, NULL, 10); return T_BASE;
"offset"[0-9]+ ir3_yylval.num = strtol(yytext+6, NULL, 10); return T_OFFSET;
"uniform" return T_UNIFORM;

View File

@ -1308,6 +1308,7 @@ cat6_bindless_ldc_opc: T_OP_LDC { new_instr(OPC_LDC); }
/* This is separated from the opcode to avoid lookahead/shift-reduce conflicts */
cat6_bindless_ldc_middle:
T_OFFSET '.' cat6_immed '.' cat6_bindless_mode dst_reg { instr->cat6.d = $1; }
| 'u' '.' T_OFFSET '.' cat6_immed '.' cat6_bindless_mode dst_reg { instr->flags |= IR3_INSTR_U; instr->cat6.d = $3; }
| cat6_immed '.' 'k' '.' cat6_bindless_mode 'c' '[' T_A1 ']' { instr->opc = OPC_LDC_K; }
cat6_bindless_ldc: cat6_bindless_ldc_opc '.' cat6_bindless_ldc_middle ',' cat6_reg_or_immed ',' cat6_reg_or_immed {

View File

@ -202,6 +202,8 @@ print_instr_name(struct log_stream *stream, struct ir3_instruction *instr,
mesa_log_stream_printf(stream, ".s");
if (instr->flags & IR3_INSTR_A1EN)
mesa_log_stream_printf(stream, ".a1en");
if (instr->flags & IR3_INSTR_U)
mesa_log_stream_printf(stream, ".u");
if (instr->opc == OPC_LDC)
mesa_log_stream_printf(stream, ".offset%d", instr->cat6.d);
if (instr->opc == OPC_LDC_K)

View File

@ -400,6 +400,12 @@ validate_instr(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr)
break;
case OPC_PUSH_CONSTS_LOAD_MACRO:
break;
case OPC_LDC:
validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
validate_assert(ctx, !!(instr->dsts[0]->flags & IR3_REG_SHARED) ==
!!(instr->flags & IR3_INSTR_U));
break;
case OPC_LDC_K:
validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));

View File

@ -380,6 +380,9 @@ static const struct test {
INSTR_6XX(c0260000_00478400, "ldc.offset2.1.imm r0.x, r0.x, 0"), /* ldc.1.mode0.base0 r0.x, r0.x, 0 */
INSTR_6XX(c0260000_00478600, "ldc.offset3.1.imm r0.x, r0.x, 0"), /* ldc.1.mode0.base0 r0.x, r0.x, 0 */
/* dEQP-VK.glsl.arrays.length.float_fragment */
INSTR_6XX(c02600c1_00c7a900, "ldc.u.offset0.3.imm.base0 r48.y, 0, 0"), /* ldc.u.3.mode4.base0 sr48.y, 0, 0 */
/* dEQP-VK.glsl.conditionals.if.if_else_vertex */
INSTR_6XX(c0360000_00c78100, "ldc.1.k.imm.base0 c[a1.x], 0, 0"), /* ldc.1.k.mode4.base0 c[a1.x], 0, 0 */
/* custom */

View File

@ -1020,7 +1020,6 @@ SOFTWARE.
<bitset name="#cat6-ldc-common" extends="#instruction-cat6-a6xx">
<pattern pos="0" >x</pattern>
<pattern pos="11" >x</pattern> <!-- TYPED -->
<pattern low="14" high="19">011110</pattern> <!-- OPC -->
<pattern low="20" high="22">1xx</pattern>
<field pos="23" name="SRC1_IM" type="bool"/>
@ -1057,6 +1056,7 @@ SOFTWARE.
{SY}{JP}ldc.{LOAD_SIZE}.k.{MODE}{BASE} c[a1.x], {SRC1}, {SRC2}
</display>
<pattern pos="11">x</pattern>
<derived name="LOAD_SIZE" expr="#cat6-load-size" type="uint"/>
<field low="32" high="39" name="LOAD_SIZE_MINUS_ONE" type="uint"/>
@ -1077,13 +1077,15 @@ SOFTWARE.
meaning? Maybe I don't have enough ldc examples from deqp-glesN
-->
<display>
{SY}{JP}{NAME}.offset{OFFSET}.{TYPE_SIZE}.{MODE}{BASE} {DST}, {SRC1}, {SRC2}
{SY}{JP}{NAME}{U}.offset{OFFSET}.{TYPE_SIZE}.{MODE}{BASE} {DST}, {SRC1}, {SRC2}
</display>
<field pos="11" name="U" type="bool" display=".u"/>
<field low="9" high="10" name="OFFSET" type="uint"/> <!-- D_MINUS_ONE -->
<field low="32" high="39" name="DST" type="#reg-gpr"/>
<pattern low="52" high="53">10</pattern>
<encode>
<map name="OFFSET">src->cat6.d</map>
<map name="U">!!(src->flags &amp; IR3_INSTR_U)</map>
</encode>
</bitset>