Fix Gen6 ELSE instructions code logic according to bspec.
authorHomer Hsing <homer.xing@intel.com>
Thu, 27 Sep 2012 08:20:39 +0000 (16:20 +0800)
committerDamien Lespiau <damien.lespiau@intel.com>
Mon, 4 Mar 2013 15:54:34 +0000 (15:54 +0000)
assembler/src/brw_structs.h
assembler/src/gram.y
assembler/src/main.c

index 3c0c578..cd81e78 100644 (file)
@@ -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;
index c72cc9c..826a3fc 100644 (file)
@@ -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*/
index 3236e75..7284d45 100644 (file)
@@ -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;
            }
        }