diff options
author | Homer Hsing <homer.xing@intel.com> | 2012-09-27 16:20:39 +0800 |
---|---|---|
committer | Damien Lespiau <damien.lespiau@intel.com> | 2013-03-04 15:54:34 +0000 |
commit | c91bd8c76ffb3a5098791a7d9c8b45a789f77cc2 (patch) | |
tree | f8d3fd73881ae3f0d0cc2e86616056d3f514197c /assembler | |
parent | ce55552470d8135070d4ceb2c21585f77de68210 (diff) |
Fix Gen6 ELSE instructions code logic according to bspec.
Diffstat (limited to 'assembler')
-rw-r--r-- | assembler/src/brw_structs.h | 13 | ||||
-rw-r--r-- | assembler/src/gram.y | 6 | ||||
-rw-r--r-- | assembler/src/main.c | 13 |
3 files changed, 22 insertions, 10 deletions
diff --git a/assembler/src/brw_structs.h b/assembler/src/brw_structs.h index 3c0c5786..cd81e783 100644 --- a/assembler/src/brw_structs.h +++ b/assembler/src/brw_structs.h @@ -1139,6 +1139,12 @@ struct brw_instruction GLuint dest_subreg_nr:3; GLuint dest_reg_nr:8; } three_src_gen6; /* Three-source-operator instructions for Gen6+ */ + + struct + { + GLuint pad:16; + GLint JIP:16; + } branch; /* conditional branch JIP for Gen6 only */ } bits1; @@ -1309,12 +1315,11 @@ struct brw_instruction struct { - GLint JIP:16; /* bspec: both the JIP and UIP are signed 16-bit numbers */ + GLint JIP:16; /* Gen7 bspec: both the JIP and UIP are signed 16-bit numbers */ GLint UIP:16; - } branch_2_offset; /* for Gen6, Gen7 2-offsets branch instructions */ + } branch_2_offset; /* for Gen6, Gen7 2-offsets branch; for Gen7 1-offset branch */ - GLint JIP; /* for Gen6, Gen7 1-offset branch instructions - Gen6 uses low 25 bits. Gen7 uses low 16 bits. */ + GLint JIP; /* used by Gen6 CALL instructions */ struct { GLuint function:4; diff --git a/assembler/src/gram.y b/assembler/src/gram.y index c72cc9c1..826a3fcf 100644 --- a/assembler/src/gram.y +++ b/assembler/src/gram.y @@ -450,8 +450,8 @@ ifelseinstruction: ENDIF } | ELSE execsize relativelocation instoptions { - // for Gen4, Gen5 if(gen_level <= 5) { + // for Gen4, Gen5 /* Set the istack pop count, which must always be 1. */ $3.imm32 |= (1 << 16); @@ -464,7 +464,7 @@ ifelseinstruction: ENDIF set_instruction_src1(&$$, &$3); $$.first_reloc_target = $3.reloc_target; $$.first_reloc_offset = $3.imm32; - } else if(gen_level == 7) { // TODO: Gen5 Gen6 also OK? + } else if(gen_level <= 7) { memset(&$$, 0, sizeof($$)); $$.header.opcode = $1; $$.header.execution_size = $2; @@ -640,7 +640,7 @@ subroutineinstruction: set_instruction_predicate(&$$, &$1); $$.header.opcode = $2; $$.header.execution_size = 1; /* execution size of RET should be 2 */ - set_instruction_dest(&$$, dst_null_reg); + set_instruction_dest(&$$, &dst_null_reg); $5.reg_type = BRW_REGISTER_TYPE_D; $5.horiz_stride = 1; /*encoded 1*/ $5.width = 1; /*encoded 2*/ diff --git a/assembler/src/main.c b/assembler/src/main.c index 3236e757..7284d45d 100644 --- a/assembler/src/main.c +++ b/assembler/src/main.c @@ -417,9 +417,16 @@ int main(int argc, char **argv) /* bspec: Unlike other flow control instructions, the offset used by JMPI is relative to the incremented instruction pointer rather than the IP value for the instruction itself. */ if(entry->instruction.header.opcode == BRW_OPCODE_JMPI) offset --; - entry->instruction.bits3.JIP = jump_distance(offset); - if(entry->instruction.header.opcode == BRW_OPCODE_ELSE) - entry->instruction.bits3.branch_2_offset.UIP = 1; + offset = jump_distance(offset); + + if(gen_level <= 5 && entry->instruction.header.opcode == BRW_OPCODE_ELSE) + entry->instruction.bits3.branch_2_offset.UIP = 1; /* Set the istack pop count, which must always be 1. */ + else if(gen_level == 6) { + /* TODO: position of JIP for endif is not written down in Gen6 spec, may be bits1 */ + entry->instruction.bits1.branch.JIP = offset; // for CASE,ELSE,FORK,IF,WHILE + entry->instruction.bits3.JIP = offset; // for CALL + } else if(gen_level >= 7) + entry->instruction.bits3.branch_2_offset.JIP = offset; } } |