ir3: rework TYPE_S8 as TYPE_U8_32

ir3's TYPE_S8 isn't actually a signed 8-bit type in a half-register, it's
in fact an unsigned 8-bit type in a full register. Only actual uses of
TYPE_S8 are in conversion operations, but those can be trivially replaced
with TYPE_U8, either truncating down to 8 bits or zero-extending or
sign-extending from 8 bits upward.

Signed-off-by: Zan Dobersek <zdobersek@igalia.com>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28254>
This commit is contained in:
Zan Dobersek 2024-04-03 18:53:27 +02:00 committed by Marge Bot
parent bc542b5827
commit c93a629f2c
8 changed files with 33 additions and 34 deletions

View file

@ -428,7 +428,7 @@ typedef enum {
TYPE_S16 = 4,
TYPE_S32 = 5,
TYPE_U8 = 6,
TYPE_S8 = 7, // XXX I assume?
TYPE_U8_32 = 7,
} type_t;
static inline uint32_t
@ -437,6 +437,7 @@ type_size(type_t type)
switch (type) {
case TYPE_F32:
case TYPE_U32:
case TYPE_U8_32:
case TYPE_S32:
return 32;
case TYPE_F16:
@ -444,7 +445,6 @@ type_size(type_t type)
case TYPE_S16:
return 16;
case TYPE_U8:
case TYPE_S8:
return 8;
default:
ir3_assert(0); /* invalid type */
@ -487,13 +487,13 @@ type_float(type_t type)
static inline int
type_uint(type_t type)
{
return (type == TYPE_U32) || (type == TYPE_U16) || (type == TYPE_U8);
return (type == TYPE_U32) || (type == TYPE_U16) || (type == TYPE_U8) || (type == TYPE_U8_32);
}
static inline int
type_sint(type_t type)
{
return (type == TYPE_S32) || (type == TYPE_S16) || (type == TYPE_S8);
return (type == TYPE_S32) || (type == TYPE_S16);
}
typedef enum {

View file

@ -1506,6 +1506,7 @@ half_type(type_t type)
case TYPE_F32:
return TYPE_F16;
case TYPE_U32:
case TYPE_U8_32:
return TYPE_U16;
case TYPE_S32:
return TYPE_S16;
@ -1514,7 +1515,6 @@ half_type(type_t type)
case TYPE_S16:
return type;
case TYPE_U8:
case TYPE_S8:
return type;
default:
assert(0);
@ -1529,9 +1529,9 @@ full_type(type_t type)
case TYPE_F16:
return TYPE_F32;
case TYPE_U8:
case TYPE_U8_32:
case TYPE_U16:
return TYPE_U32;
case TYPE_S8:
case TYPE_S16:
return TYPE_S32;
case TYPE_F32:

View file

@ -177,7 +177,7 @@ create_cov(struct ir3_context *ctx, struct ir3_instruction *src,
src_type = TYPE_S16;
break;
case 8:
src_type = TYPE_S8;
src_type = TYPE_U8;
break;
default:
ir3_context_error(ctx, "invalid src bit size: %u", src_bitsize);
@ -248,7 +248,7 @@ create_cov(struct ir3_context *ctx, struct ir3_instruction *src,
case nir_op_f2i8:
case nir_op_i2i8:
case nir_op_b2i8:
dst_type = TYPE_S8;
dst_type = TYPE_U8;
break;
case nir_op_f2u32:

View file

@ -180,7 +180,7 @@ static int parse_reg(const char *str)
"gat" return TOKEN(T_OP_GAT);
"sct" return TOKEN(T_OP_SCT);
("f16"|"f32"|"u16"|"u32"|"s16"|"s32"|"u8"|"s8"){2} ir3_yylval.str = yytext; return T_CAT1_TYPE_TYPE;
("f16"|"f32"|"u16"|"u32"|"s16"|"s32"|"u8"|"u8_32"){2} ir3_yylval.str = yytext; return T_CAT1_TYPE_TYPE;
/* category 2: */
"add.f" return TOKEN(T_OP_ADD_F);
@ -407,7 +407,7 @@ static int parse_reg(const char *str)
"s16" return TOKEN(T_TYPE_S16);
"s32" return TOKEN(T_TYPE_S32);
"u8" return TOKEN(T_TYPE_U8);
"s8" return TOKEN(T_TYPE_S8);
"u8_32" return TOKEN(T_TYPE_U8_32);
"untyped" return TOKEN(T_UNTYPED);
"typed" return TOKEN(T_TYPED);

View file

@ -145,9 +145,9 @@ static type_t parse_type(const char **type)
} else if (!strncmp("u8", *type, 2)) {
*type += 2;
return TYPE_U8;
} else if (!strncmp("s8", *type, 2)) {
*type += 2;
return TYPE_S8;
} else if (!strncmp("u8_32", *type, 5)) {
*type += 5;
return TYPE_U8_32;
} else {
assert(0); /* shouldn't get here */
return ~0;
@ -671,7 +671,7 @@ static void print_token(FILE *file, int type, YYSTYPE value)
%token <tok> T_TYPE_S16
%token <tok> T_TYPE_S32
%token <tok> T_TYPE_U8
%token <tok> T_TYPE_S8
%token <tok> T_TYPE_U8_32
%token <tok> T_UNTYPED
%token <tok> T_TYPED
@ -1577,11 +1577,11 @@ integer: T_INT { $$ = $1; }
float: T_FLOAT { $$ = $1; }
| '-' T_FLOAT { $$ = -$2; }
type: T_TYPE_F16 { $$ = TYPE_F16; }
| T_TYPE_F32 { $$ = TYPE_F32; }
| T_TYPE_U16 { $$ = TYPE_U16; }
| T_TYPE_U32 { $$ = TYPE_U32; }
| T_TYPE_S16 { $$ = TYPE_S16; }
| T_TYPE_S32 { $$ = TYPE_S32; }
| T_TYPE_U8 { $$ = TYPE_U8; }
| T_TYPE_S8 { $$ = TYPE_S8; }
type: T_TYPE_F16 { $$ = TYPE_F16; }
| T_TYPE_F32 { $$ = TYPE_F32; }
| T_TYPE_U16 { $$ = TYPE_U16; }
| T_TYPE_U32 { $$ = TYPE_U32; }
| T_TYPE_S16 { $$ = TYPE_S16; }
| T_TYPE_S32 { $$ = TYPE_S32; }
| T_TYPE_U8 { $$ = TYPE_U8; }
| T_TYPE_U8_32 { $$ = TYPE_U8_32; }

View file

@ -53,14 +53,14 @@ type_name(type_t type)
{
static const char *type_names[] = {
/* clang-format off */
[TYPE_F16] = "f16",
[TYPE_F32] = "f32",
[TYPE_U16] = "u16",
[TYPE_U32] = "u32",
[TYPE_S16] = "s16",
[TYPE_S32] = "s32",
[TYPE_U8] = "u8",
[TYPE_S8] = "s8",
[TYPE_F16] = "f16",
[TYPE_F32] = "f32",
[TYPE_U16] = "u16",
[TYPE_U32] = "u32",
[TYPE_S16] = "s16",
[TYPE_S32] = "s32",
[TYPE_U8] = "u8",
[TYPE_U8_32] = "u8_32",
/* clang-format on */
};
return type_names[type];

View file

@ -222,7 +222,7 @@ static const struct test {
INSTR_6XX(c0ca0505_03800042, "stg.s32 g[r0.z+5], r8.y, 3"),
INSTR_6XX(c0ca0500_03800042, "stg.s32 g[r0.z], r8.y, 3"),
INSTR_6XX(c0ca0531_03800242, "stg.s32 g[r0.z+305], r8.y, 3"),
INSTR_5XX(c0ce0100_02800000, "stg.s8 g[r0.x], hr0.x, 2"),
INSTR_5XX(c0ce0100_02800000, "stg.u8_32 g[r0.x], r0.x, 2"),
INSTR_5XX(c0c00100_02800000, "stg.f16 g[r0.x], hr0.x, 2"),
/* Customely crafted */

View file

@ -310,15 +310,14 @@ SOFTWARE.
<value val="4" display="s16"/>
<value val="5" display="s32"/>
<value val="6" display="u8"/>
<value val="7" display="s8"/>
<value val="7" display="u8_32"/>
</enum>
<expr name="#type-half">
({TYPE} == 0) /* f16 */ ||
({TYPE} == 2) /* u16 */ ||
({TYPE} == 4) /* s16 */ ||
({TYPE} == 6) /* u8 */ ||
({TYPE} == 7) /* s8 */
({TYPE} == 6) /* u8 */
</expr>
<enum name="#absneg">