summaryrefslogtreecommitdiff
path: root/assembler
diff options
context:
space:
mode:
authorDamien Lespiau <damien.lespiau@intel.com>2013-01-24 16:16:35 +0000
committerDamien Lespiau <damien.lespiau@intel.com>2013-03-04 15:54:39 +0000
commit9fcc1bdcad1a993d4681673d96443991d0c3bac4 (patch)
tree72d9409e9961e6dc7ae8793491fdf0df3bb9b01b /assembler
parent5e0da9f854fea552cbc73f07a2e86a370f35aa92 (diff)
assembler: Use brw_set_dest() to encode the destination
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>
Diffstat (limited to 'assembler')
-rw-r--r--assembler/gen4asm.h3
-rw-r--r--assembler/gram.y171
-rw-r--r--assembler/main.c11
3 files changed, 91 insertions, 94 deletions
diff --git a/assembler/gen4asm.h b/assembler/gen4asm.h
index 49c6ea01..0e3b965a 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 9c5f8640..bf8d688a 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 176835b7..cfee749a 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], "-"))