From patchwork Mon Feb 4 15:27:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lespiau, Damien" X-Patchwork-Id: 2093161 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 7A3C0DFE82 for ; Mon, 4 Feb 2013 15:54:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 69AEBE6176 for ; Mon, 4 Feb 2013 07:54:08 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id EA9C6E5FFE for ; Mon, 4 Feb 2013 07:29:45 -0800 (PST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 04 Feb 2013 07:29:45 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.84,600,1355126400"; d="scan'208";a="257442045" Received: from unknown (HELO dyon.amr.corp.intel.com) ([10.255.12.132]) by orsmga001.jf.intel.com with ESMTP; 04 Feb 2013 07:29:44 -0800 From: Damien Lespiau To: intel-gfx@lists.freedesktop.org Date: Mon, 4 Feb 2013 15:27:46 +0000 Message-Id: <1359991705-5254-52-git-send-email-damien.lespiau@intel.com> X-Mailer: git-send-email 1.7.7.5 In-Reply-To: <1359991705-5254-1-git-send-email-damien.lespiau@intel.com> References: <1359991705-5254-1-git-send-email-damien.lespiau@intel.com> Subject: [Intel-gfx] [PATCH 51/90] assembler: Use brw_set_dest() to encode the destination X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org A few notes: I needed to introduce a brw context and compile structs. These are only used to get which generation we are compiling code for, but eventually we can use more of the infrastructure. brw_set_dest() uses the destination register width to program the instruction execution size. The assembler can either take subnr in bytes or in number of elements, so we need a resolve step when setting a brw_reg. Signed-off-by: Damien Lespiau --- assembler/gen4asm.h | 3 + assembler/gram.y | 171 +++++++++++++++++++++++---------------------------- assembler/main.c | 11 +++ 3 files changed, 91 insertions(+), 94 deletions(-) diff --git a/assembler/gen4asm.h b/assembler/gen4asm.h index 49c6ea0..0e3b965 100644 --- a/assembler/gen4asm.h +++ b/assembler/gen4asm.h @@ -43,6 +43,9 @@ typedef float GLfloat; extern long int gen_level; +extern struct brw_context genasm_context; +extern struct brw_compile genasm_compile; + /* Predicate for Gen X and above */ #define IS_GENp(x) (gen_level >= (x)*10) diff --git a/assembler/gram.y b/assembler/gram.y index 9c5f864..bf8d688 100644 --- a/assembler/gram.y +++ b/assembler/gram.y @@ -32,8 +32,7 @@ #include #include #include "gen4asm.h" -#include "brw_defines.h" -#include "brw_reg.h" +#include "brw_eu.h" #define DEFAULT_EXECSIZE (ffs(program_defaults.execute_size) - 1) #define DEFAULT_DSTREGION -1 @@ -175,6 +174,52 @@ static bool validate_dst_reg(struct brw_instruction *insn, struct brw_reg *reg) return true; } +static int get_subreg_address(GLuint regfile, GLuint type, GLuint subreg, GLuint address_mode) +{ + int unit_size = 1; + + assert(address_mode == BRW_ADDRESS_DIRECT); + assert(regfile != BRW_IMMEDIATE_VALUE); + + if (advanced_flag) + unit_size = get_type_size(type); + + return subreg * unit_size; +} + +/* only used in indirect address mode. + * input: sub-register number of an address register + * output: the value of AddrSubRegNum in the instruction binary code + * + * input output(advanced_flag==0) output(advanced_flag==1) + * a0.0 0 0 + * a0.1 invalid input 1 + * a0.2 1 2 + * a0.3 invalid input 3 + * a0.4 2 4 + * a0.5 invalid input 5 + * a0.6 3 6 + * a0.7 invalid input 7 + * a0.8 4 invalid input + * a0.10 5 invalid input + * a0.12 6 invalid input + * a0.14 7 invalid input + */ +static int get_indirect_subreg_address(GLuint subreg) +{ + return advanced_flag == 0 ? subreg / 2 : subreg; +} + +static void resolve_subnr(struct brw_reg *reg) +{ + if (reg->address_mode == BRW_ADDRESS_DIRECT) + reg->subnr = get_subreg_address(reg->file, reg->type, reg->subnr, + reg->address_mode); + else + reg->subnr = get_indirect_subreg_address(reg->subnr); +} + + %} %start ROOT @@ -522,8 +567,8 @@ ifelseinstruction: ENDIF memset(&$$, 0, sizeof($$)); $$.gen.header.opcode = $1; - $$.gen.header.execution_size = $2; $$.gen.header.thread_control |= BRW_THREAD_SWITCH; + ip_dst.width = $2; set_instruction_dest(&$$.gen, &ip_dst); set_instruction_src0(&$$.gen, &ip_src); set_instruction_src1(&$$.gen, &$3); @@ -557,9 +602,9 @@ ifelseinstruction: ENDIF memset(&$$, 0, sizeof($$)); set_instruction_predicate(&$$.gen, &$1); $$.gen.header.opcode = $2; - $$.gen.header.execution_size = $3; if(!IS_GENp(6)) { $$.gen.header.thread_control |= BRW_THREAD_SWITCH; + ip_dst.width = $3; set_instruction_dest(&$$.gen, &ip_dst); set_instruction_src0(&$$.gen, &ip_src); set_instruction_src1(&$$.gen, &$4); @@ -593,11 +638,11 @@ loopinstruction: predicate WHILE execsize relativelocation instoptions * offset is the second source operand. The offset is added * to the pre-incremented IP. */ + ip_dst.width = $3; set_instruction_dest(&$$.gen, &ip_dst); memset(&$$, 0, sizeof($$)); set_instruction_predicate(&$$.gen, &$1); $$.gen.header.opcode = $2; - $$.gen.header.execution_size = $3; $$.gen.header.thread_control |= BRW_THREAD_SWITCH; set_instruction_src0(&$$.gen, &ip_src); set_instruction_src1(&$$.gen, &$4); @@ -632,11 +677,11 @@ haltinstruction: predicate HALT execsize relativelocation relativelocation insto memset(&$$, 0, sizeof($$)); set_instruction_predicate(&$$.gen, &$1); $$.gen.header.opcode = $2; - $$.gen.header.execution_size = $3; $$.first_reloc_target = $4.reloc_target; $$.first_reloc_offset = $4.imm32; $$.second_reloc_target = $5.reloc_target; $$.second_reloc_offset = $5.imm32; + dst_null_reg.width = $3; set_instruction_dest(&$$.gen, &dst_null_reg); set_instruction_src0(&$$.gen, &src_null_reg); }; @@ -648,10 +693,10 @@ multibranchinstruction: memset(&$$, 0, sizeof($$)); set_instruction_predicate(&$$.gen, &$1); $$.gen.header.opcode = $2; - $$.gen.header.execution_size = $3; $$.gen.header.thread_control |= BRW_THREAD_SWITCH; $$.first_reloc_target = $4.reloc_target; $$.first_reloc_offset = $4.imm32; + dst_null_reg.width = $3; set_instruction_dest(&$$.gen, &dst_null_reg); } | predicate BRC execsize relativelocation relativelocation instoptions @@ -660,12 +705,12 @@ multibranchinstruction: memset(&$$, 0, sizeof($$)); set_instruction_predicate(&$$.gen, &$1); $$.gen.header.opcode = $2; - $$.gen.header.execution_size = $3; $$.gen.header.thread_control |= BRW_THREAD_SWITCH; $$.first_reloc_target = $4.reloc_target; $$.first_reloc_offset = $4.imm32; $$.second_reloc_target = $5.reloc_target; $$.second_reloc_offset = $5.imm32; + dst_null_reg.width = $3; set_instruction_dest(&$$.gen, &dst_null_reg); set_instruction_src0(&$$.gen, &src_null_reg); } @@ -691,9 +736,9 @@ subroutineinstruction: memset(&$$, 0, sizeof($$)); set_instruction_predicate(&$$.gen, &$1); $$.gen.header.opcode = $2; - $$.gen.header.execution_size = 1; /* execution size must be 2. Here 1 is encoded 2. */ $4.type = BRW_REGISTER_TYPE_D; /* dest type should be DWORD */ + $4.width = 1; /* execution size must be 2. Here 1 is encoded 2. */ set_instruction_dest(&$$.gen, &$4); struct src_operand src0; @@ -719,7 +764,7 @@ subroutineinstruction: memset(&$$, 0, sizeof($$)); set_instruction_predicate(&$$.gen, &$1); $$.gen.header.opcode = $2; - $$.gen.header.execution_size = 1; /* execution size of RET should be 2 */ + dst_null_reg.width = 1; /* execution size of RET should be 2 */ set_instruction_dest(&$$.gen, &dst_null_reg); $5.reg.type = BRW_REGISTER_TYPE_D; $5.reg.hstride = 1; /*encoded 1*/ @@ -737,7 +782,7 @@ unaryinstruction: $$.header.opcode = $2; $$.header.destreg__conditionalmod = $3.cond; $$.header.saturate = $4; - $$.header.execution_size = $5; + $6.width = $5; set_instruction_options(&$$, &$8); set_instruction_predicate(&$$, &$1); if (set_instruction_dest(&$$, &$6) != 0) @@ -756,7 +801,7 @@ unaryinstruction: } if (!IS_GENp(6) && - get_type_size($$.bits1.da1.dest_reg_type) * (1 << $$.header.execution_size) == 64) + get_type_size($$.bits1.da1.dest_reg_type) * (1 << $6.width) == 64) $$.header.compression_control = BRW_COMPRESSION_COMPRESSED; } ; @@ -774,9 +819,9 @@ binaryinstruction: $$.header.opcode = $2; $$.header.destreg__conditionalmod = $3.cond; $$.header.saturate = $4; - $$.header.execution_size = $5; set_instruction_options(&$$, &$9); set_instruction_predicate(&$$, &$1); + $6.width = $5; if (set_instruction_dest(&$$, &$6) != 0) YYERROR; if (set_instruction_src0(&$$, &$7) != 0) @@ -795,7 +840,7 @@ binaryinstruction: } if (!IS_GENp(6) && - get_type_size($$.bits1.da1.dest_reg_type) * (1 << $$.header.execution_size) == 64) + get_type_size($$.bits1.da1.dest_reg_type) * (1 << $6.width) == 64) $$.header.compression_control = BRW_COMPRESSION_COMPRESSED; } ; @@ -813,7 +858,7 @@ binaryaccinstruction: $$.header.opcode = $2; $$.header.destreg__conditionalmod = $3.cond; $$.header.saturate = $4; - $$.header.execution_size = $5; + $6.width = $5; set_instruction_options(&$$, &$9); set_instruction_predicate(&$$, &$1); if (set_instruction_dest(&$$, &$6) != 0) @@ -834,7 +879,7 @@ binaryaccinstruction: } if (!IS_GENp(6) && - get_type_size($$.bits1.da1.dest_reg_type) * (1 << $$.header.execution_size) == 64) + get_type_size($$.bits1.da1.dest_reg_type) * (1 << $6.width) == 64) $$.header.compression_control = BRW_COMPRESSION_COMPRESSED; } ; @@ -895,7 +940,7 @@ sendinstruction: predicate SEND execsize exp post_dst payload msgtarget */ memset(&$$, 0, sizeof($$)); $$.header.opcode = $2; - $$.header.execution_size = $3; + $5.width = $3; $$.header.destreg__conditionalmod = $4; /* msg reg index */ set_instruction_predicate(&$$, &$1); if (set_instruction_dest(&$$, &$5) != 0) @@ -951,11 +996,11 @@ sendinstruction: predicate SEND execsize exp post_dst payload msgtarget { memset(&$$, 0, sizeof($$)); $$.header.opcode = $2; - $$.header.execution_size = $3; $$.header.destreg__conditionalmod = $5.nr; /* msg reg index */ set_instruction_predicate(&$$, &$1); + $4.width = $3; if (set_instruction_dest(&$$, &$4) != 0) YYERROR; if (set_instruction_src0(&$$, &$6) != 0) @@ -963,6 +1008,7 @@ sendinstruction: predicate SEND execsize exp post_dst payload msgtarget /* XXX is this correct? */ if (set_instruction_src1(&$$, &$7) != 0) YYERROR; + } | predicate SEND execsize dst sendleadreg payload imm32reg instoptions { @@ -974,10 +1020,10 @@ sendinstruction: predicate SEND execsize exp post_dst payload msgtarget } memset(&$$, 0, sizeof($$)); $$.header.opcode = $2; - $$.header.execution_size = $3; $$.header.destreg__conditionalmod = $5.nr; /* msg reg index */ set_instruction_predicate(&$$, &$1); + $4.width = $3; if (set_instruction_dest(&$$, &$4) != 0) YYERROR; if (set_instruction_src0(&$$, &$6) != 0) @@ -1004,10 +1050,10 @@ sendinstruction: predicate SEND execsize exp post_dst payload msgtarget memset(&$$, 0, sizeof($$)); $$.header.opcode = $2; - $$.header.execution_size = $3; $$.header.destreg__conditionalmod = ($6 & EX_DESC_SFID_MASK); /* SFID */ set_instruction_predicate(&$$, &$1); + $4.width = $3; if (set_instruction_dest(&$$, &$4) != 0) YYERROR; @@ -1050,10 +1096,10 @@ sendinstruction: predicate SEND execsize exp post_dst payload msgtarget memset(&$$, 0, sizeof($$)); $$.header.opcode = $2; - $$.header.execution_size = $3; $$.header.destreg__conditionalmod = ($6 & EX_DESC_SFID_MASK); /* SFID */ set_instruction_predicate(&$$, &$1); + $4.width = $3; if (set_instruction_dest(&$$, &$4) != 0) YYERROR; @@ -1085,10 +1131,10 @@ sendinstruction: predicate SEND execsize exp post_dst payload msgtarget } memset(&$$, 0, sizeof($$)); $$.header.opcode = $2; - $$.header.execution_size = $3; $$.header.destreg__conditionalmod = $5.nr; /* msg reg index */ set_instruction_predicate(&$$, &$1); + $4.width = $3; if (set_instruction_dest(&$$, &$4) != 0) YYERROR; if (set_instruction_src0(&$$, &$6) != 0) @@ -1107,11 +1153,11 @@ sendinstruction: predicate SEND execsize exp post_dst payload msgtarget { memset(&$$, 0, sizeof($$)); $$.header.opcode = $2; - $$.header.execution_size = $3; $$.header.destreg__conditionalmod = $5.nr; /* msg reg index */ set_instruction_predicate(&$$, &$1); + $4.width = $3; if (set_instruction_dest(&$$, &$4) != 0) YYERROR; if (set_instruction_src0(&$$, &$6) != 0) @@ -1141,10 +1187,10 @@ jumpinstruction: predicate JMPI execsize relativelocation2 */ memset(&$$, 0, sizeof($$)); $$.gen.header.opcode = $2; - $$.gen.header.execution_size = ffs(1) - 1; if(advanced_flag) $$.gen.header.mask_control = BRW_MASK_DISABLE; set_instruction_predicate(&$$.gen, &$1); + ip_dst.width = ffs(1) - 1; set_instruction_dest(&$$.gen, &ip_dst); set_instruction_src0(&$$.gen, &ip_src); set_instruction_src1(&$$.gen, &$4); @@ -1158,9 +1204,9 @@ mathinstruction: predicate MATH_INST execsize dst src srcimm math_function insto memset(&$$, 0, sizeof($$)); $$.header.opcode = $2; $$.header.destreg__conditionalmod = $7; - $$.header.execution_size = $3; set_instruction_options(&$$, &$8); set_instruction_predicate(&$$, &$1); + $4.width = $3; if (set_instruction_dest(&$$, &$4) != 0) YYERROR; if (set_instruction_src0(&$$, &$5) != 0) @@ -1199,8 +1245,8 @@ syncinstruction: predicate WAIT notifyreg memset(&$$, 0, sizeof($$)); $$.header.opcode = $2; - $$.header.execution_size = ffs(1) - 1; set_direct_dst_operand(¬ify_dst, &$3, BRW_REGISTER_TYPE_D); + notify_dst.width = ffs(1) - 1; set_instruction_dest(&$$, ¬ify_dst); set_direct_src_operand(¬ify_src, &$3, BRW_REGISTER_TYPE_D); set_instruction_src0(&$$, ¬ify_src); @@ -2708,42 +2754,6 @@ static int get_type_size(GLuint type) return size; } -static int get_subreg_address(GLuint regfile, GLuint type, GLuint subreg, GLuint address_mode) -{ - int unit_size = 1; - - assert(address_mode == BRW_ADDRESS_DIRECT); - assert(regfile != BRW_IMMEDIATE_VALUE); - - if (advanced_flag) - unit_size = get_type_size(type); - - return subreg * unit_size; -} - -/* only used in indirect address mode. - * input: sub-register number of an address register - * output: the value of AddrSubRegNum in the instruction binary code - * - * input output(advanced_flag==0) output(advanced_flag==1) - * a0.0 0 0 - * a0.1 invalid input 1 - * a0.2 1 2 - * a0.3 invalid input 3 - * a0.4 2 4 - * a0.5 invalid input 5 - * a0.6 3 6 - * a0.7 invalid input 7 - * a0.8 4 invalid input - * a0.10 5 invalid input - * a0.12 6 invalid input - * a0.14 7 invalid input - */ -static int get_indirect_subreg_address(GLuint subreg) -{ - return advanced_flag == 0 ? subreg / 2 : subreg; -} - static void reset_instruction_src_region(struct brw_instruction *instr, struct src_operand *src) { @@ -2822,38 +2832,11 @@ int set_instruction_dest(struct brw_instruction *instr, if (!validate_dst_reg(instr, dest)) return 1; - if (dest->address_mode == BRW_ADDRESS_DIRECT && - instr->header.access_mode == BRW_ALIGN_1) { - instr->bits1.da1.dest_reg_file = dest->file; - instr->bits1.da1.dest_reg_type = dest->type; - instr->bits1.da1.dest_subreg_nr = get_subreg_address(dest->file, dest->type, dest->subnr, dest->address_mode); - instr->bits1.da1.dest_reg_nr = dest->nr; - instr->bits1.da1.dest_horiz_stride = dest->hstride; - instr->bits1.da1.dest_address_mode = dest->address_mode; - } else if (dest->address_mode == BRW_ADDRESS_DIRECT) { - instr->bits1.da16.dest_reg_file = dest->file; - instr->bits1.da16.dest_reg_type = dest->type; - instr->bits1.da16.dest_subreg_nr = get_subreg_address(dest->file, dest->type, dest->subnr, dest->address_mode); - instr->bits1.da16.dest_reg_nr = dest->nr; - instr->bits1.da16.dest_address_mode = dest->address_mode; - instr->bits1.da16.dest_horiz_stride = ffs(1); - instr->bits1.da16.dest_writemask = dest->dw1.bits.writemask; - } else if (instr->header.access_mode == BRW_ALIGN_1) { - instr->bits1.ia1.dest_reg_file = dest->file; - instr->bits1.ia1.dest_reg_type = dest->type; - instr->bits1.ia1.dest_subreg_nr = dest->subnr; - instr->bits1.ia1.dest_horiz_stride = dest->hstride; - instr->bits1.ia1.dest_indirect_offset = dest->dw1.bits.indirect_offset; - instr->bits1.ia1.dest_address_mode = dest->address_mode; - } else { - instr->bits1.ia16.dest_reg_file = dest->file; - instr->bits1.ia16.dest_reg_type = dest->type; - instr->bits1.ia16.dest_subreg_nr = get_indirect_subreg_address(dest->subnr); - instr->bits1.ia16.dest_writemask = dest->dw1.bits.writemask; - instr->bits1.ia16.dest_horiz_stride = ffs(1); - instr->bits1.ia16.dest_indirect_offset = (dest->dw1.bits.indirect_offset >> 4); /* half register aligned */ - instr->bits1.ia16.dest_address_mode = dest->address_mode; - } + /* the assembler support expressing subnr in bytes or in number of + * elements. */ + resolve_subnr(dest); + + brw_set_dest(&genasm_compile, instr, *dest); return 0; } diff --git a/assembler/main.c b/assembler/main.c index 176835b..cfee749 100644 --- a/assembler/main.c +++ b/assembler/main.c @@ -33,7 +33,9 @@ #include #include +#include "ralloc.h" #include "gen4asm.h" +#include "brw_eu.h" extern FILE *yyin; @@ -48,6 +50,9 @@ char *export_filename = NULL; const char const *binary_prepend = "static const char gen_eu_bytes[] = {\n"; +struct brw_context genasm_brw_context; +struct brw_compile genasm_compile; + struct brw_program compiled_program; struct program_defaults program_defaults = {.register_type = BRW_REGISTER_TYPE_F}; @@ -286,6 +291,8 @@ int main(int argc, char **argv) struct brw_program_instruction *entry, *entry1, *tmp_entry; int err, inst_offset; char o; + void *mem_ctx; + while ((o = getopt_long(argc, argv, "e:l:o:g:ab", longopts, NULL)) != -1) { switch (o) { case 'o': @@ -358,6 +365,10 @@ int main(int argc, char **argv) } } + brw_init_context(&genasm_brw_context, gen_level); + mem_ctx = ralloc_context(NULL); + brw_init_compile(&genasm_brw_context, &genasm_compile, mem_ctx); + err = yyparse(); if (strcmp(argv[0], "-"))