summaryrefslogtreecommitdiff
path: root/ast_to_hir.cpp
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-04-05 18:07:27 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-04-07 11:42:36 -0700
commit8c46ed24906ee10dd2f2cfaf4cf9803eca1ba523 (patch)
tree71eac354c7f81b6811f2dbbbc471e9b7353881f2 /ast_to_hir.cpp
parent4cf20cd37c12c6243a09d52739d3d47f030a1799 (diff)
Generate correct IR for do-while loops
Previously the same code was generated for a while loop and a do-while loop. This pulls the code that generates the conditional break into a separate method. This method is called either at the beginning or the end depending on the loop type. Reported-by: Kenneth Graunke <kenneth@whitecape.org>
Diffstat (limited to 'ast_to_hir.cpp')
-rw-r--r--ast_to_hir.cpp51
1 files changed, 31 insertions, 20 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp
index ae5a8d51f7..6afd7eafec 100644
--- a/ast_to_hir.cpp
+++ b/ast_to_hir.cpp
@@ -2104,27 +2104,10 @@ ast_selection_statement::hir(exec_list *instructions,
}
-ir_rvalue *
-ast_iteration_statement::hir(exec_list *instructions,
- struct _mesa_glsl_parse_state *state)
+void
+ast_iteration_statement::condition_to_hir(ir_loop *stmt,
+ struct _mesa_glsl_parse_state *state)
{
- /* For loops start a new scope, but while and do-while loops do not.
- */
- if (mode == ast_for)
- state->symbols->push_scope();
-
- if (init_statement != NULL)
- init_statement->hir(instructions, state);
-
- ir_loop *const stmt = new ir_loop();
- instructions->push_tail(stmt);
-
- /* Track the current loop and / or switch-statement nesting.
- */
- ir_instruction *const nesting = state->loop_or_switch_nesting;
- state->loop_or_switch_nesting = stmt;
-
-
if (condition != NULL) {
ir_rvalue *const cond =
condition->hir(& stmt->body_instructions, state);
@@ -2152,6 +2135,31 @@ ast_iteration_statement::hir(exec_list *instructions,
stmt->body_instructions.push_tail(if_stmt);
}
}
+}
+
+
+ir_rvalue *
+ast_iteration_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ /* For loops start a new scope, but while and do-while loops do not.
+ */
+ if (mode == ast_for)
+ state->symbols->push_scope();
+
+ if (init_statement != NULL)
+ init_statement->hir(instructions, state);
+
+ ir_loop *const stmt = new ir_loop();
+ instructions->push_tail(stmt);
+
+ /* Track the current loop and / or switch-statement nesting.
+ */
+ ir_instruction *const nesting = state->loop_or_switch_nesting;
+ state->loop_or_switch_nesting = stmt;
+
+ if (mode != ast_do_while)
+ condition_to_hir(stmt, state);
if (body != NULL) {
ast_node *node = (ast_node *) body;
@@ -2164,6 +2172,9 @@ ast_iteration_statement::hir(exec_list *instructions,
if (rest_expression != NULL)
rest_expression->hir(& stmt->body_instructions, state);
+ if (mode == ast_do_while)
+ condition_to_hir(stmt, state);
+
if (mode == ast_for)
state->symbols->pop_scope();