diff mbox

[51/90] assembler: Use brw_set_dest() to encode the destination

Message ID 1359991705-5254-52-git-send-email-damien.lespiau@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lespiau, Damien Feb. 4, 2013, 3:27 p.m. UTC
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 <damien.lespiau@intel.com>
---
 assembler/gen4asm.h |    3 +
 assembler/gram.y    |  171 +++++++++++++++++++++++----------------------------
 assembler/main.c    |   11 +++
 3 files changed, 91 insertions(+), 94 deletions(-)
diff mbox

Patch

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 <stdbool.h>
 #include <assert.h>
 #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(&notify_dst, &$3, BRW_REGISTER_TYPE_D);
+		  notify_dst.width = ffs(1) - 1;
 		  set_instruction_dest(&$$, &notify_dst);
 		  set_direct_src_operand(&notify_src, &$3, BRW_REGISTER_TYPE_D);
 		  set_instruction_src0(&$$, &notify_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 <unistd.h>
 #include <assert.h>
 
+#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], "-"))