diff --git a/src/freedreno/ir3/ir3_lexer.l b/src/freedreno/ir3/ir3_lexer.l index de4a087628b..aca583cab0b 100644 --- a/src/freedreno/ir3/ir3_lexer.l +++ b/src/freedreno/ir3/ir3_lexer.l @@ -95,6 +95,9 @@ static int parse_reg(const char *str) str++; num++; } + if (str[0] == 'u') { + str++; + } str++; if (str[0] == 't') { str++; @@ -178,6 +181,7 @@ static int parse_reg(const char *str) "a0.x" return T_A0; "a1.x" return T_A1; "p0."[xyzw] ir3_yylval.num = parse_reg(yytext); return T_P0; +"up0."[xyzw] ir3_yylval.num = parse_reg(yytext); return T_UP0; "w"[0-9]+ ir3_yylval.num = strtol(yytext+1, NULL, 10); return T_W; "s#"[0-9]+ ir3_yylval.num = strtol(yytext+2, NULL, 10); return T_SAMP; "t#"[0-9]+ ir3_yylval.num = strtol(yytext+2, NULL, 10); return T_TEX; diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index f17deb3978a..83f1d8bf4b9 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -773,6 +773,7 @@ static void print_token(FILE *file, int type, YYSTYPE value) %token T_A0 %token T_A1 %token T_P0 +%token T_UP0 %token T_W %token T_CAT1_TYPE_TYPE @@ -1613,6 +1614,7 @@ dst: T_REGISTER { $$ = new_dst($1, 0); } | T_A0 { $$ = new_dst((61 << 3), IR3_REG_HALF); } | T_A1 { $$ = new_dst((61 << 3) + 1, IR3_REG_HALF); } | T_P0 { $$ = new_dst((62 << 3) + $1, IR3_REG_PREDICATE); } +| T_UP0 { $$ = new_dst((62 << 3) + $1, IR3_REG_PREDICATE | IR3_REG_UNIFORM); } const: T_CONSTANT { $$ = new_src($1, IR3_REG_CONST); } diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 698e28fc104..b9f0c735dce 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -117,6 +117,8 @@ static const struct test { INSTR_7XX(42380800_04010400, "(nop3) add.s r0.x, (last)r0.x, (last)r0.y"), INSTR_7XX(42930000_04000406, "cmps.u.ge r0.x, (last)r1.z, (last)r0.x"), + INSTR_7XX(429000f5_100600c1, "cmps.u.lt up0.y, r48.y, c1.z"), + /* cat3 */ INSTR_6XX(66000000_10421041, "sel.f16 hr0.x, hc16.y, hr0.x, hc16.z"), INSTR_6XX(64848109_109a9099, "(rpt1)sel.b32 r2.y, c38.y, (r)r2.y, c38.z"), diff --git a/src/freedreno/isa/encode.c b/src/freedreno/isa/encode.c index 1b1876b6e2f..114b73f49d8 100644 --- a/src/freedreno/isa/encode.c +++ b/src/freedreno/isa/encode.c @@ -130,6 +130,18 @@ extract_reg_uim(const struct ir3_register *reg) return reg->uim_val; } +static inline uint32_t +extract_dst_num(const struct ir3_register *reg) +{ + if (reg->flags & IR3_REG_UNIFORM) { + assert(reg->flags & IR3_REG_PREDICATE); + assert(reg_num(reg) == REG_P0); + return REG_A0; + } + + return reg_num(reg); +} + /** * This is a bit messy, to deal with the fact that the optional "s2en" * src is the first src, shifting everything else up by one. diff --git a/src/freedreno/isa/ir3-cat2.xml b/src/freedreno/isa/ir3-cat2.xml index e1901cc8e53..9c516fdabde 100644 --- a/src/freedreno/isa/ir3-cat2.xml +++ b/src/freedreno/isa/ir3-cat2.xml @@ -28,8 +28,38 @@ SOFTWARE. Cat2 Instructions: one and two src ALU instructions --> + + + + Predicate registers can be written from the scalar + ALU by using a special cat2 encoding: if the dst is + encoded as a0.c, the instruction will execute on the + scalar ALU and write to p0.c. + + + up0.{SWIZ} + + 111101 + + + + p0.{SWIZ} + + 111110 + + + r{GPR}.{SWIZ} + + + + + extract_dst_num(src) + src->num & 0x3 + + + - +