summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHomer Hsing <homer.xing@intel.com>2012-09-27 16:20:39 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2012-09-28 04:06:00 -0400
commit7c4379ae57efbe1c9fe308bf4aa24d8ddd7cbbc0 (patch)
tree4198e298d6a16a7f8214173f25f1319dd60c302b
parentd64d27a1ec91a7937c23887b8d16c73eb962da52 (diff)
Fix Gen6 ELSE instructions code logic according to bspec.
-rw-r--r--src/brw_structs.h13
-rw-r--r--src/gram.y6
-rw-r--r--src/main.c13
3 files changed, 22 insertions, 10 deletions
diff --git a/src/brw_structs.h b/src/brw_structs.h
index 3c0c578..cd81e78 100644
--- a/src/brw_structs.h
+++ b/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/src/gram.y b/src/gram.y
index c72cc9c..826a3fc 100644
--- a/src/gram.y
+++ b/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/src/main.c b/src/main.c
index 3236e75..7284d45 100644
--- a/src/main.c
+++ b/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;
}
}