}
+/**
+ * Evaluate the 4 condition codes against a predicate and return GL_TRUE
+ * or GL_FALSE to indicate result.
+ */
+static INLINE GLboolean
+eval_condition(const struct fp_machine *machine,
+ const struct prog_instruction *inst)
+{
+ const GLuint swizzle = inst->DstReg.CondSwizzle;
+ const GLuint condMask = inst->DstReg.CondMask;
+ if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
+ test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
+ test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
+ test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+
+
/**
* Store 4 floats into a register. Observe the instructions saturate and
* set-condition-code flags.
case OPCODE_ENDSUB: /* end subroutine */
break;
case OPCODE_BRA: /* conditional branch */
- {
- /* NOTE: The branch is conditional! */
- const GLuint swizzle = inst->DstReg.CondSwizzle;
- const GLuint condMask = inst->DstReg.CondMask;
- if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
- /* take branch */
- pc = inst->BranchTarget - 1;
- }
+ if (eval_condition(machine, inst)) {
+ /* take branch */
+ pc = inst->BranchTarget - 1;
}
break;
- case OPCODE_BRK: /* break out of loop */
+ case OPCODE_BRK: /* break out of loop (conditional) */
/* fall-through */
- case OPCODE_CONT: /* continue loop */
+ case OPCODE_CONT: /* continue loop (conditional) */
/* Subtract 1 here since we'll do pc++ at end of for-loop */
- pc = inst->BranchTarget - 1;
+ if (eval_condition(machine, inst)) {
+ /* take branch */
+ pc = inst->BranchTarget - 1;
+ }
break;
- case OPCODE_CAL: /* Call subroutine */
- {
- /* NOTE: The call is conditional! */
- const GLuint swizzle = inst->DstReg.CondSwizzle;
- const GLuint condMask = inst->DstReg.CondMask;
- if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
- if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
- return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
- }
- machine->CallStack[machine->StackDepth++] = pc + 1;
- pc = inst->BranchTarget; /* XXX - 1 ??? */
+ case OPCODE_CAL: /* Call subroutine (conditional) */
+ if (eval_condition(machine, inst)) {
+ /* call the subroutine */
+ if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
+ return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
}
+ machine->CallStack[machine->StackDepth++] = pc + 1;
+ pc = inst->BranchTarget; /* XXX - 1 ??? */
}
break;
case OPCODE_CMP:
}
break;
case OPCODE_IF:
- {
- const GLuint swizzle = inst->DstReg.CondSwizzle;
- const GLuint condMask = inst->DstReg.CondMask;
- if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
- /* do if-clause (just continue execution) */
- }
- else {
- /* go to the instruction after ELSE or ENDIF */
- assert(inst->BranchTarget >= 0);
- pc = inst->BranchTarget - 1;
- }
+ if (eval_condition(machine, inst)) {
+ /* do if-clause (just continue execution) */
}
- break;
- case OPCODE_ELSE:
- {
- /* goto ENDIF */
+ else {
+ /* go to the instruction after ELSE or ENDIF */
assert(inst->BranchTarget >= 0);
pc = inst->BranchTarget - 1;
}
break;
+ case OPCODE_ELSE:
+ /* goto ENDIF */
+ assert(inst->BranchTarget >= 0);
+ pc = inst->BranchTarget - 1;
+ break;
case OPCODE_ENDIF:
/* nothing */
break;
store_vector4( inst, machine, result );
}
break;
- case OPCODE_KIL_NV: /* NV_f_p only */
- {
- const GLuint swizzle = inst->DstReg.CondSwizzle;
- const GLuint condMask = inst->DstReg.CondMask;
- if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
- return GL_FALSE;
- }
+ case OPCODE_KIL_NV: /* NV_f_p only (conditional) */
+ if (eval_condition(machine, inst)) {
+ return GL_FALSE;
}
break;
case OPCODE_KIL: /* ARB_f_p only */
store_vector4( inst, machine, result );
}
break;
- case OPCODE_RET: /* return from subroutine */
- {
- /* NOTE: The return is conditional! */
- const GLuint swizzle = inst->DstReg.CondSwizzle;
- const GLuint condMask = inst->DstReg.CondMask;
- if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
- test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
- if (machine->StackDepth == 0) {
- return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
- }
- pc = machine->CallStack[--machine->StackDepth];
+ case OPCODE_RET: /* return from subroutine (conditional) */
+ if (eval_condition(machine, inst)) {
+ if (machine->StackDepth == 0) {
+ return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
}
+ pc = machine->CallStack[--machine->StackDepth];
}
break;
case OPCODE_RFL: /* reflection vector */