diff --git a/assembler/src/brw_defines.h b/assembler/src/brw_defines.h index f60ed5a1..173b70ce 100644 --- a/assembler/src/brw_defines.h +++ b/assembler/src/brw_defines.h @@ -606,6 +606,7 @@ #define BRW_OPCODE_DPA2 88 #define BRW_OPCODE_LINE 89 #define BRW_OPCODE_PLN 90 +#define BRW_OPCODE_MAD 91 #define BRW_OPCODE_NOP 126 #define BRW_PREDICATE_NONE 0 diff --git a/assembler/src/gram.y b/assembler/src/gram.y index 04a29fce..2c454390 100644 --- a/assembler/src/gram.y +++ b/assembler/src/gram.y @@ -48,6 +48,14 @@ int set_instruction_src0(struct brw_instruction *instr, struct src_operand *src); int set_instruction_src1(struct brw_instruction *instr, struct src_operand *src); +int set_instruction_dest_three_src(struct brw_instruction *instr, + struct dst_operand *dest); +int set_instruction_src0_three_src(struct brw_instruction *instr, + struct src_operand *src); +int set_instruction_src1_three_src(struct brw_instruction *instr, + struct src_operand *src); +int set_instruction_src2_three_src(struct brw_instruction *instr, + struct src_operand *src); void set_instruction_options(struct brw_instruction *instr, struct brw_instruction *options); void set_instruction_predicate(struct brw_instruction *instr, @@ -110,6 +118,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg, %token SEND NOP JMPI IF IFF WHILE ELSE BREAK CONT HALT MSAVE %token PUSH MREST POP WAIT DO ENDIF ILLEGAL %token MATH_INST +%token MAD %token NULL_TOKEN MATH SAMPLER GATEWAY READ WRITE URB THREAD_SPAWNER VME DATA_PORT @@ -144,7 +153,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg, %type exp sndopr %type instruction unaryinstruction binaryinstruction -%type binaryaccinstruction triinstruction sendinstruction +%type binaryaccinstruction trinaryinstruction sendinstruction %type jumpinstruction branchloopinstruction elseinstruction %type breakinstruction syncinstruction specialinstruction %type msgtarget @@ -154,6 +163,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg, %type instrseq %type instoption %type unaryop binaryop binaryaccop branchloopop breakop +%type trinaryop %type conditionalmodifier %type condition saturate negate abs chansel %type writemask_x writemask_y writemask_z writemask_w @@ -363,7 +373,8 @@ instrseq: instrseq pragma instruction: unaryinstruction | binaryinstruction | binaryaccinstruction - | triinstruction + | trinaryinstruction + | sendinstruction | jumpinstruction | branchloopinstruction | elseinstruction @@ -482,7 +493,42 @@ binaryaccinstruction: binaryaccop: AVG | ADD | SEL | AND | OR | XOR | SHR | SHL | ASR | CMP | CMPN | PLN ; -triinstruction: sendinstruction +trinaryop: MAD +; + +trinaryinstruction: + predicate trinaryop conditionalmodifier saturate execsize + dst src src src instoptions +{ + memset(&$$, 0, sizeof($$)); + + $$.header.predicate_control = $1.header.predicate_control; + $$.header.predicate_inverse = $1.header.predicate_inverse; + $$.bits1.three_src_gen7.flag_reg_nr = $1.bits2.da1.flag_reg_nr; + $$.bits1.three_src_gen7.flag_subreg_nr = $1.bits2.da1.flag_subreg_nr; + + $$.header.opcode = $2; + $$.header.sfid_destreg__conditionalmod = $3.cond; + $$.header.saturate = $4; + $$.header.execution_size = $5; + + if (set_instruction_dest_three_src(&$$, &$6)) + YYERROR; + if (set_instruction_src0_three_src(&$$, &$7)) + YYERROR; + if (set_instruction_src1_three_src(&$$, &$8)) + YYERROR; + if (set_instruction_src2_three_src(&$$, &$9)) + YYERROR; + set_instruction_options(&$$, &$10); + + if ($3.flag_subreg_nr != -1) { + if ($$.header.predicate_control != BRW_PREDICATE_NONE && + ($1.bits2.da1.flag_reg_nr != $3.flag_reg_nr || + $1.bits2.da1.flag_subreg_nr != $3.flag_subreg_nr)) + fprintf(stderr, "WARNING: must use the same flag register if both prediction and conditional modifier are enabled\n"); + } +} ; sendinstruction: predicate SEND execsize exp post_dst payload msgtarget @@ -2858,6 +2904,75 @@ int set_instruction_src1(struct brw_instruction *instr, return 0; } +/* convert 2-src reg type to 3-src reg type + * + * 2-src reg type: + * 000=UD 001=D 010=UW 011=W 100=UB 101=B 110=DF 111=F + * + * 3-src reg type: + * 00=F 01=D 10=UD 11=DF + */ +static int reg_type_2_to_3(int reg_type) +{ + int r = 0; + switch(reg_type) { + case 7: r = 0; break; + case 1: r = 1; break; + case 0: r = 2; break; + // TODO: supporting DF + } + return r; +} + +int set_instruction_dest_three_src(struct brw_instruction *instr, + struct dst_operand *dest) +{ + instr->bits1.three_src_gen7.dest_reg_nr = dest->reg_nr; + instr->bits1.three_src_gen7.dest_subreg_nr = get_subreg_address(dest->reg_file, dest->reg_type, dest->subreg_nr, dest->address_mode) / 4; // in DWORD + instr->bits1.three_src_gen7.dest_writemask = dest->writemask; + instr->bits1.three_src_gen7.dest_reg_type = reg_type_2_to_3(dest->reg_type); + return 0; +} + +int set_instruction_src0_three_src(struct brw_instruction *instr, + struct src_operand *src) +{ + if (advanced_flag) { + reset_instruction_src_region(instr, src); + } + // TODO: supporting src0 swizzle, src0 modifier, src0 rep_ctrl + instr->bits1.three_src_gen7.src_reg_type = reg_type_2_to_3(src->reg_type); + instr->bits2.three_src_gen7.src0_subreg_nr = get_subreg_address(src->reg_file, src->reg_type, src->subreg_nr, src->address_mode) / 4; // in DWORD + instr->bits2.three_src_gen7.src0_reg_nr = src->reg_nr; + return 0; +} + +int set_instruction_src1_three_src(struct brw_instruction *instr, + struct src_operand *src) +{ + if (advanced_flag) { + reset_instruction_src_region(instr, src); + } + // TODO: supporting src1 swizzle, src1 modifier, src1 rep_ctrl + int v = get_subreg_address(src->reg_file, src->reg_type, src->subreg_nr, src->address_mode) / 4; // in DWORD + instr->bits2.three_src_gen7.src1_subreg_nr_low = v % 4; // lower 2 bits + instr->bits3.three_src_gen7.src1_subreg_nr_high = v / 4; // highest bit + instr->bits3.three_src_gen7.src1_reg_nr = src->reg_nr; + return 0; +} + +int set_instruction_src2_three_src(struct brw_instruction *instr, + struct src_operand *src) +{ + if (advanced_flag) { + reset_instruction_src_region(instr, src); + } + // TODO: supporting src2 swizzle, src2 modifier, src2 rep_ctrl + instr->bits3.three_src_gen7.src2_subreg_nr = get_subreg_address(src->reg_file, src->reg_type, src->subreg_nr, src->address_mode) / 4; // in DWORD + instr->bits3.three_src_gen7.src2_reg_nr = src->reg_nr; + return 0; +} + void set_instruction_options(struct brw_instruction *instr, struct brw_instruction *options) { diff --git a/assembler/src/lex.l b/assembler/src/lex.l index 37c23c25..a3949a5b 100644 --- a/assembler/src/lex.l +++ b/assembler/src/lex.l @@ -83,6 +83,7 @@ yylval.integer = BRW_CHANNEL_W; "not" { yylval.integer = BRW_OPCODE_NOT; return NOT; } "lzd" { yylval.integer = BRW_OPCODE_LZD; return LZD; } +"mad" { yylval.integer = BRW_OPCODE_MAD; return MAD; } "mul" { yylval.integer = BRW_OPCODE_MUL; return MUL; } "mac" { yylval.integer = BRW_OPCODE_MAC; return MAC; } "mach" { yylval.integer = BRW_OPCODE_MACH; return MACH; }