intel/brw: Add assembly support for ARF scalar register

And the SEND gather variant that uses a scalar register as its only
source.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32236>
This commit is contained in:
Caio Oliveira 2024-11-19 13:13:26 -08:00 committed by Marge Bot
parent 46e9fe6981
commit f8c7348468
6 changed files with 90 additions and 6 deletions

View file

@ -838,6 +838,9 @@ reg(FILE *file, unsigned _reg_file, unsigned _reg_nr)
case BRW_ARF_STATE:
format(file, "sr%d", _reg_nr & 0x0f);
break;
case BRW_ARF_SCALAR:
format(file, "s%d", _reg_nr & 0x0f);
break;
case BRW_ARF_CONTROL:
format(file, "cr%d", _reg_nr & 0x0f);
break;
@ -1663,7 +1666,13 @@ src0(FILE *file, const struct brw_isa_info *isa, const brw_inst *inst)
const struct intel_device_info *devinfo = isa->devinfo;
if (is_split_send(devinfo, brw_inst_opcode(isa, inst))) {
if (devinfo->ver >= 12) {
if (devinfo->ver >= 30 &&
brw_inst_send_src0_reg_file(devinfo, inst) == ARF) {
format(file, "r[");
reg(file, ARF, brw_inst_src0_da_reg_nr(devinfo, inst));
format(file, ".%u]", (unsigned)brw_inst_send_src0_subreg_nr(devinfo, inst) * 2);
return 0;
} else if (devinfo->ver >= 12) {
return src_sends_da(file,
devinfo,
BRW_TYPE_UD,
@ -2116,6 +2125,8 @@ brw_disassemble_inst(FILE *file, const struct brw_isa_info *isa,
bool has_imm_desc = false, has_imm_ex_desc = false;
uint32_t imm_desc = 0, imm_ex_desc = 0;
if (is_split_send(devinfo, opcode)) {
const bool is_send_gather =
devinfo->ver >= 30 && brw_inst_send_src0_reg_file(devinfo, inst) == ARF;
pad(file, 64);
if (brw_inst_send_sel_reg32_desc(devinfo, inst)) {
/* show the indirect descriptor source */
@ -2133,7 +2144,7 @@ brw_disassemble_inst(FILE *file, const struct brw_isa_info *isa,
brw_inst_send_ex_desc_ia_subreg_nr(devinfo, inst));
} else {
has_imm_ex_desc = true;
imm_ex_desc = brw_inst_sends_ex_desc(devinfo, inst, false);
imm_ex_desc = brw_inst_sends_ex_desc(devinfo, inst, is_send_gather);
fprintf(file, "0x%08"PRIx32, imm_ex_desc);
}
} else {

View file

@ -787,6 +787,7 @@ enum ENUM_PACKED gfx10_align1_3src_exec_type {
#define BRW_ARF_ACCUMULATOR 0x20
#define BRW_ARF_FLAG 0x30
#define BRW_ARF_MASK 0x40
#define BRW_ARF_SCALAR 0x60
#define BRW_ARF_STATE 0x70
#define BRW_ARF_CONTROL 0x80
#define BRW_ARF_NOTIFICATION_COUNT 0x90

View file

@ -151,16 +151,22 @@ brw_set_src0(struct brw_codegen *p, brw_inst *inst, struct brw_reg reg)
if (devinfo->ver >= 12 &&
(brw_inst_opcode(p->isa, inst) == BRW_OPCODE_SEND ||
brw_inst_opcode(p->isa, inst) == BRW_OPCODE_SENDC)) {
assert(reg.file != IMM);
assert(reg.file == ARF || reg.file == FIXED_GRF);
assert(reg.address_mode == BRW_ADDRESS_DIRECT);
assert(reg.subnr == 0);
assert(has_scalar_region(reg) ||
(reg.hstride == BRW_HORIZONTAL_STRIDE_1 &&
reg.vstride == reg.width + 1));
assert(!reg.negate && !reg.abs);
brw_inst_set_send_src0_reg_file(devinfo, inst, reg.file);
brw_inst_set_src0_da_reg_nr(devinfo, inst, phys_nr(devinfo, reg));
if (reg.file == ARF && reg.nr == BRW_ARF_SCALAR) {
assert(reg.subnr % 2 == 0);
brw_inst_set_send_src0_subreg_nr(devinfo, inst, reg.subnr / 2);
} else {
assert(reg.subnr == 0);
}
} else if (brw_inst_opcode(p->isa, inst) == BRW_OPCODE_SENDS ||
brw_inst_opcode(p->isa, inst) == BRW_OPCODE_SENDSC) {
assert(reg.file == FIXED_GRF);

View file

@ -477,7 +477,7 @@ add_label(struct brw_codegen *p, const char* label_name, enum instr_label_type t
/* register type */
%token <integer> GENREG ADDRREG ACCREG FLAGREG NOTIFYREG STATEREG
%token <integer> CONTROLREG IPREG PERFORMANCEREG THREADREG CHANNELENABLEREG
%token <integer> MASKREG
%token <integer> MASKREG SCALARREG
%token <integer> INTEGER
%token <llint> LONG
@ -525,7 +525,7 @@ add_label(struct brw_codegen *p, const char* label_name, enum instr_label_type t
%type <integer> swizzle
/* registers */
%type <reg> accreg addrreg channelenablereg controlreg flagreg ipreg
%type <reg> accreg addrreg channelenablereg controlreg flagreg ipreg scalarreg
%type <reg> notifyreg nullreg performancereg threadcontrolreg statereg maskreg
%type <integer> subregnum
@ -552,6 +552,7 @@ add_label(struct brw_codegen *p, const char* label_name, enum instr_label_type t
%token <integer> REG_DIST_LONG
%token <integer> REG_DIST_ALL
%token <integer> REG_DIST_MATH
%token <integer> REG_DIST_SCALAR
%token <integer> SBID_ALLOC
%token <integer> SBID_WAIT_SRC
%token <integer> SBID_WAIT_DST
@ -954,6 +955,42 @@ sendinstruction:
brw_pop_insn_state(p);
}
| predicate sendsopcode execsize dst GENREGFILE LSQUARE scalarreg RSQUARE desc ex_desc sharedfunction msgdesc instoptions
{
assert(p->devinfo->ver >= 30);
i965_asm_set_instruction_options(p, $13);
brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3);
brw_set_dest(p, brw_last_inst, $4);
brw_set_src0(p, brw_last_inst, $7);
brw_set_src1(p, brw_last_inst, brw_null_reg());
if ($9.file == IMM) {
brw_inst_set_send_sel_reg32_desc(p->devinfo, brw_last_inst, 0);
brw_inst_set_send_desc(p->devinfo, brw_last_inst, $9.ud);
} else {
brw_inst_set_send_sel_reg32_desc(p->devinfo, brw_last_inst, 1);
}
if ($10.file == IMM) {
brw_inst_set_send_sel_reg32_ex_desc(p->devinfo, brw_last_inst, 0);
brw_inst_set_sends_ex_desc(p->devinfo, brw_last_inst, $10.ud, true);
} else {
brw_inst_set_send_sel_reg32_ex_desc(p->devinfo, brw_last_inst, 1);
brw_inst_set_send_ex_desc_ia_subreg_nr(p->devinfo, brw_last_inst, $10.subnr >> 2);
}
brw_inst_set_sfid(p->devinfo, brw_last_inst, $11);
brw_inst_set_eot(p->devinfo, brw_last_inst, $13.end_of_thread);
brw_inst_set_group(p->devinfo, brw_last_inst, $13.chan_offset);
if ($12.ex_bso) {
brw_inst_set_send_ex_bso(p->devinfo, brw_last_inst, 1);
/* Not settings src1 length, as its implied zero. */
}
brw_pop_insn_state(p);
}
;
sendop:
@ -1296,6 +1333,7 @@ dstoperandex_typed:
| notifyreg
| performancereg
| statereg
| scalarreg
;
dstreg:
@ -1444,6 +1482,7 @@ srcarcoperandex_typed:
| ipreg
| maskreg
| statereg
| scalarreg
;
indirectsrcoperand:
@ -1612,6 +1651,18 @@ notifyreg:
}
;
scalarreg:
SCALARREG subregnum
{
if ($2 > 31)
error(&@2, "Scalar sub register number %d"
" out of range\n", $2);
$$.file = ARF;
$$.nr = BRW_ARF_SCALAR;
$$.subnr = $2;
}
statereg:
STATEREG subregnum
{
@ -2069,6 +2120,12 @@ depinfo:
$$.regdist = $1;
$$.pipe = TGL_PIPE_MATH;
}
| REG_DIST_SCALAR
{
memset(&$$, 0, sizeof($$));
$$.regdist = $1;
$$.pipe = TGL_PIPE_SCALAR;
}
| SBID_ALLOC
{
memset(&$$, 0, sizeof($$));

View file

@ -718,6 +718,11 @@ FC(send_src1_len, /* 9+ */ -1, -1, /* 12+ */ 103, 99, devinfo->verx
FF(send_src1_reg_file, /* 9+ */ 36, 36, /* 12+ */ 98, 98)
FF(send_dst_reg_file, /* 9+ */ 35, 35, /* 12+ */ 50, 50)
FC(send_ex_bso, /* 9+ */ -1, -1, /* 12+ */ 39, 39, devinfo->verx10 >= 125)
/* When using scalar register for src0, this replaces src1_len, which is
* always zero.
*/
FC(send_src0_subreg_nr, /* 9+ */ -1, -1, /* 12+ */ 103, 99, devinfo->verx10 >= 300)
/** @} */
/* Message descriptor bits */

View file

@ -329,6 +329,9 @@ BranchCtrl { return BRANCH_CTRL; }
/* flag registers */
"f"[0|1] { BEGIN(CHANNEL); yylval.integer = atoi(yytext + 1); return FLAGREG; }
/* scalar register */
"s0" { return SCALARREG; }
/* state register */
sr[0-9]+ { yylval.integer = atoi(yytext + 2); return STATEREG; }
@ -416,6 +419,7 @@ sr[0-9]+ { yylval.integer = atoi(yytext + 2); return STATEREG; }
"L@"[1-7] { yylval.integer = atoi(yytext + 2); return REG_DIST_LONG; }
"A@"[1-7] { yylval.integer = atoi(yytext + 2); return REG_DIST_ALL; }
"M@"[1-7] { yylval.integer = atoi(yytext + 2); return REG_DIST_MATH; }
"S@"[1-7] { yylval.integer = atoi(yytext + 2); return REG_DIST_SCALAR; }
"$"[0-9]* { yylval.integer = atoi(yytext + 1); return SBID_ALLOC; }
"$"[0-9]*".src" { yylval.integer = atoi(yytext + 1); return SBID_WAIT_SRC; }