Simplify code with eval_condition(). Implement conditional BRK.

This commit is contained in:
Brian
2007-02-08 13:22:31 -07:00
parent 2c75ef62ea
commit 97125fb370

View File

@@ -417,6 +417,29 @@ test_cc(GLuint condCode, GLuint ccMaskRule)
} }
/**
* 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 * Store 4 floats into a register. Observe the instructions saturate and
* set-condition-code flags. * set-condition-code flags.
@@ -687,41 +710,29 @@ execute_program( GLcontext *ctx,
case OPCODE_ENDSUB: /* end subroutine */ case OPCODE_ENDSUB: /* end subroutine */
break; break;
case OPCODE_BRA: /* conditional branch */ case OPCODE_BRA: /* conditional branch */
{ if (eval_condition(machine, inst)) {
/* 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 */ /* take branch */
pc = inst->BranchTarget - 1; pc = inst->BranchTarget - 1;
} }
break;
case OPCODE_BRK: /* break out of loop (conditional) */
/* fall-through */
case OPCODE_CONT: /* continue loop (conditional) */
/* Subtract 1 here since we'll do pc++ at end of for-loop */
if (eval_condition(machine, inst)) {
/* take branch */
pc = inst->BranchTarget - 1;
} }
break; break;
case OPCODE_BRK: /* break out of loop */ case OPCODE_CAL: /* Call subroutine (conditional) */
/* fall-through */ if (eval_condition(machine, inst)) {
case OPCODE_CONT: /* continue loop */ /* call the subroutine */
/* Subtract 1 here since we'll do pc++ at end of for-loop */
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) { if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
} }
machine->CallStack[machine->StackDepth++] = pc + 1; machine->CallStack[machine->StackDepth++] = pc + 1;
pc = inst->BranchTarget; /* XXX - 1 ??? */ pc = inst->BranchTarget; /* XXX - 1 ??? */
} }
}
break; break;
case OPCODE_CMP: case OPCODE_CMP:
{ {
@@ -871,13 +882,7 @@ execute_program( GLcontext *ctx,
} }
break; break;
case OPCODE_IF: case OPCODE_IF:
{ if (eval_condition(machine, 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)) {
/* do if-clause (just continue execution) */ /* do if-clause (just continue execution) */
} }
else { else {
@@ -885,14 +890,11 @@ execute_program( GLcontext *ctx,
assert(inst->BranchTarget >= 0); assert(inst->BranchTarget >= 0);
pc = inst->BranchTarget - 1; pc = inst->BranchTarget - 1;
} }
}
break; break;
case OPCODE_ELSE: case OPCODE_ELSE:
{
/* goto ENDIF */ /* goto ENDIF */
assert(inst->BranchTarget >= 0); assert(inst->BranchTarget >= 0);
pc = inst->BranchTarget - 1; pc = inst->BranchTarget - 1;
}
break; break;
case OPCODE_ENDIF: case OPCODE_ENDIF:
/* nothing */ /* nothing */
@@ -908,17 +910,10 @@ execute_program( GLcontext *ctx,
store_vector4( inst, machine, result ); store_vector4( inst, machine, result );
} }
break; break;
case OPCODE_KIL_NV: /* NV_f_p only */ case OPCODE_KIL_NV: /* NV_f_p only (conditional) */
{ if (eval_condition(machine, 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_FALSE; return GL_FALSE;
} }
}
break; break;
case OPCODE_KIL: /* ARB_f_p only */ case OPCODE_KIL: /* ARB_f_p only */
{ {
@@ -1203,21 +1198,13 @@ execute_program( GLcontext *ctx,
store_vector4( inst, machine, result ); store_vector4( inst, machine, result );
} }
break; break;
case OPCODE_RET: /* return from subroutine */ case OPCODE_RET: /* return from subroutine (conditional) */
{ if (eval_condition(machine, inst)) {
/* 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) { if (machine->StackDepth == 0) {
return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
} }
pc = machine->CallStack[--machine->StackDepth]; pc = machine->CallStack[--machine->StackDepth];
} }
}
break; break;
case OPCODE_RFL: /* reflection vector */ case OPCODE_RFL: /* reflection vector */
{ {