From f8c7348468e0f1226cb346d299a4d83cda0388f6 Mon Sep 17 00:00:00 2001 From: Caio Oliveira Date: Tue, 19 Nov 2024 13:13:26 -0800 Subject: [PATCH] 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 Reviewed-by: Ian Romanick Part-of: --- src/intel/compiler/brw_disasm.c | 15 ++++++- src/intel/compiler/brw_eu_defines.h | 1 + src/intel/compiler/brw_eu_emit.c | 10 ++++- src/intel/compiler/brw_gram.y | 61 ++++++++++++++++++++++++++++- src/intel/compiler/brw_inst.h | 5 +++ src/intel/compiler/brw_lex.l | 4 ++ 6 files changed, 90 insertions(+), 6 deletions(-) diff --git a/src/intel/compiler/brw_disasm.c b/src/intel/compiler/brw_disasm.c index e6db7877338..ba79ef9dbcc 100644 --- a/src/intel/compiler/brw_disasm.c +++ b/src/intel/compiler/brw_disasm.c @@ -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 { diff --git a/src/intel/compiler/brw_eu_defines.h b/src/intel/compiler/brw_eu_defines.h index ed757e0824b..27e2ea33790 100644 --- a/src/intel/compiler/brw_eu_defines.h +++ b/src/intel/compiler/brw_eu_defines.h @@ -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 diff --git a/src/intel/compiler/brw_eu_emit.c b/src/intel/compiler/brw_eu_emit.c index 598addad58f..9c155fdc759 100644 --- a/src/intel/compiler/brw_eu_emit.c +++ b/src/intel/compiler/brw_eu_emit.c @@ -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); diff --git a/src/intel/compiler/brw_gram.y b/src/intel/compiler/brw_gram.y index 81305de5e7d..2802d42166b 100644 --- a/src/intel/compiler/brw_gram.y +++ b/src/intel/compiler/brw_gram.y @@ -477,7 +477,7 @@ add_label(struct brw_codegen *p, const char* label_name, enum instr_label_type t /* register type */ %token GENREG ADDRREG ACCREG FLAGREG NOTIFYREG STATEREG %token CONTROLREG IPREG PERFORMANCEREG THREADREG CHANNELENABLEREG -%token MASKREG +%token MASKREG SCALARREG %token INTEGER %token LONG @@ -525,7 +525,7 @@ add_label(struct brw_codegen *p, const char* label_name, enum instr_label_type t %type swizzle /* registers */ -%type accreg addrreg channelenablereg controlreg flagreg ipreg +%type accreg addrreg channelenablereg controlreg flagreg ipreg scalarreg %type notifyreg nullreg performancereg threadcontrolreg statereg maskreg %type subregnum @@ -552,6 +552,7 @@ add_label(struct brw_codegen *p, const char* label_name, enum instr_label_type t %token REG_DIST_LONG %token REG_DIST_ALL %token REG_DIST_MATH +%token REG_DIST_SCALAR %token SBID_ALLOC %token SBID_WAIT_SRC %token 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($$)); diff --git a/src/intel/compiler/brw_inst.h b/src/intel/compiler/brw_inst.h index e7294b62b21..1bb89590405 100644 --- a/src/intel/compiler/brw_inst.h +++ b/src/intel/compiler/brw_inst.h @@ -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 */ diff --git a/src/intel/compiler/brw_lex.l b/src/intel/compiler/brw_lex.l index 3af403b5156..b98dac67189 100644 --- a/src/intel/compiler/brw_lex.l +++ b/src/intel/compiler/brw_lex.l @@ -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; }