mesa: adjust BRK/CONT BranchTarget to always point to ENDLOOP instruction
authorBrian Paul <brianp@vmware.com>
Tue, 22 Dec 2009 21:15:30 +0000 (14:15 -0700)
committerBrian Paul <brianp@vmware.com>
Tue, 22 Dec 2009 21:26:06 +0000 (14:26 -0700)
To be more consistant.

src/mesa/shader/prog_execute.c
src/mesa/shader/slang/slang_emit.c

index 025665a06e59871bb710df4b53e4f136eba82ecd..56d174c6ce593fd6371980a9cad86f1a5bb9b2d1 100644 (file)
@@ -698,12 +698,26 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_ENDSUB:      /* end subroutine */
          break;
       case OPCODE_BRA:         /* branch (conditional) */
-         /* fall-through */
+         if (eval_condition(machine, inst)) {
+            /* take branch */
+            /* Subtract 1 here since we'll do pc++ below */
+            pc = inst->BranchTarget - 1;
+         }
+         break;
       case OPCODE_BRK:         /* break out of loop (conditional) */
-         /* fall-through */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_ENDLOOP);
+         if (eval_condition(machine, inst)) {
+            /* break out of loop */
+            /* pc++ at end of for-loop will put us after the ENDLOOP inst */
+            pc = inst->BranchTarget;
+         }
+         break;
       case OPCODE_CONT:        /* continue loop (conditional) */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_ENDLOOP);
          if (eval_condition(machine, inst)) {
-            /* take branch */
+            /* continue at ENDLOOP */
             /* Subtract 1 here since we'll do pc++ at end of for-loop */
             pc = inst->BranchTarget - 1;
          }
index 99eb254cee0392257a464eaf96bc899ae95ed442..e769d0d3ad4cef4056283f7a6f69d811fbd104da 100644 (file)
@@ -1814,7 +1814,7 @@ emit_loop(slang_emit_info *emitInfo, slang_ir_node *n)
 
    /* Done emitting loop code.  Now walk over the loop's linked list of
     * BREAK and CONT nodes, filling in their BranchTarget fields (which
-    * will point to the ENDLOOP+1 or BGNLOOP instructions, respectively).
+    * will point to the corresponding ENDLOOP instruction.
     */
    for (ir = n->List; ir; ir = ir->List) {
       struct prog_instruction *inst = prog->Instructions + ir->InstLocation;
@@ -1823,8 +1823,8 @@ emit_loop(slang_emit_info *emitInfo, slang_ir_node *n)
           ir->Opcode == IR_BREAK_IF_TRUE) {
          assert(inst->Opcode == OPCODE_BRK ||
                 inst->Opcode == OPCODE_BRA);
-         /* go to instruction after end of loop */
-         inst->BranchTarget = endInstLoc + 1;
+         /* go to instruction at end of loop */
+         inst->BranchTarget = endInstLoc;
       }
       else {
          assert(ir->Opcode == IR_CONT ||