summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-10-09 14:40:11 -0600
committerBrian <brian.paul@tungstengraphics.com>2007-10-09 14:40:11 -0600
commitaec1f8e4f8315df23dc51a0b5a5fad90a03be851 (patch)
tree9fa31fd55332ca0b7dbeab56b0c0299cfc6e6829
parent31bd01f93b0f5795e290897e79c3f16d90e1f202 (diff)
More work on flow control for CAL/RET.
-rw-r--r--src/mesa/pipe/tgsi/exec/tgsi_exec.c37
-rw-r--r--src/mesa/pipe/tgsi/exec/tgsi_exec.h6
2 files changed, 31 insertions, 12 deletions
diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.c b/src/mesa/pipe/tgsi/exec/tgsi_exec.c
index 52848a2a73..6bbff76a87 100644
--- a/src/mesa/pipe/tgsi/exec/tgsi_exec.c
+++ b/src/mesa/pipe/tgsi/exec/tgsi_exec.c
@@ -109,7 +109,7 @@
/** The execution mask depends on the conditional mask and the loop mask */
#define UPDATE_EXEC_MASK(MACH) \
- MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask
+ MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask
#define CHAN_X 0
@@ -2044,6 +2044,9 @@ exec_instruction(
assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
+ assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING);
+ mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask;
+
/* note that PC was already incremented above */
mach->CallStack[mach->CallStackTop++] = *pc;
*pc = inst->InstructionExtLabel.Label;
@@ -2053,19 +2056,28 @@ exec_instruction(
case TGSI_OPCODE_RET:
/* XXX examine ExecMask to determine if we should _really_ return */
/* pop Cond, Loop, Cont stacks */
- assert(mach->CondStackTop > 0);
- mach->CondMask = mach->CondStack[--mach->CondStackTop];
- assert(mach->LoopStackTop > 0);
- mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
- assert(mach->ContStackTop > 0);
- mach->ContMask = mach->ContStack[--mach->ContStackTop];
+ mach->FuncMask &= ~mach->ExecMask;
+ UPDATE_EXEC_MASK(mach);
- assert(mach->CallStackTop >= 0);
- if (mach->CallStackTop == 0) {
- /* XXX error? */
- return;
+ if (mach->ExecMask == 0x0) {
+ /* really return now (otherwise, keep executing */
+ assert(mach->CondStackTop > 0);
+ mach->CondMask = mach->CondStack[--mach->CondStackTop];
+ assert(mach->LoopStackTop > 0);
+ mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
+ assert(mach->ContStackTop > 0);
+ mach->ContMask = mach->ContStack[--mach->ContStackTop];
+
+ assert(mach->FuncStackTop > 0);
+ mach->FuncMask = mach->FuncStack[--mach->FuncStackTop];
+
+ assert(mach->CallStackTop >= 0);
+ if (mach->CallStackTop == 0) {
+ /* XXX error? */
+ return;
+ }
+ *pc = mach->CallStack[--mach->CallStackTop];
}
- *pc = mach->CallStack[--mach->CallStackTop];
break;
case TGSI_OPCODE_SSG:
@@ -2387,6 +2399,7 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
mach->CondMask = 0xf;
mach->LoopMask = 0xf;
mach->ContMask = 0xf;
+ mach->FuncMask = 0xf;
mach->ExecMask = 0xf;
assert(mach->CondStackTop == 0);
diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.h b/src/mesa/pipe/tgsi/exec/tgsi_exec.h
index 354d5df6c2..20647e72e2 100644
--- a/src/mesa/pipe/tgsi/exec/tgsi_exec.h
+++ b/src/mesa/pipe/tgsi/exec/tgsi_exec.h
@@ -141,6 +141,7 @@ struct tgsi_exec_machine
uint CondMask; /**< For IF/ELSE/ENDIF */
uint LoopMask; /**< For BGNLOOP/ENDLOOP */
uint ContMask; /**< For loop CONT statements */
+ uint FuncMask; /**< For function calls */
uint ExecMask; /**< = CondMask & LoopMask */
/** Condition mask stack (for nested conditionals) */
@@ -155,6 +156,11 @@ struct tgsi_exec_machine
uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING];
int ContStackTop;
+ /** Function execution mask stack (for executing subroutine code) */
+ uint FuncStack[TGSI_EXEC_MAX_CALL_NESTING];
+ int FuncStackTop;
+
+ /** Function call stack for saving/restoring the program counter */
uint CallStack[TGSI_EXEC_MAX_CALL_NESTING];
int CallStackTop;