diff options
-rw-r--r-- | ast.h | 3 | ||||
-rw-r--r-- | ast_to_hir.cpp | 49 | ||||
-rw-r--r-- | ir.h | 22 | ||||
-rw-r--r-- | ir_print_visitor.cpp | 24 | ||||
-rw-r--r-- | ir_print_visitor.h | 1 | ||||
-rw-r--r-- | ir_visitor.h | 1 |
6 files changed, 100 insertions, 0 deletions
@@ -492,6 +492,9 @@ public: ast_node *else_statement); virtual void print(void) const; + virtual ir_rvalue *hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state); + ast_expression *condition; ast_node *then_statement; ast_node *else_statement; diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index 7b1db0c481..0a505bf414 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -1318,3 +1318,52 @@ ast_jump_statement::hir(exec_list *instructions, */ return NULL; } + + +ir_rvalue * +ast_selection_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + ir_rvalue *const condition = this->condition->hir(instructions, state); + struct simple_node *ptr; + + /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec: + * + * "Any expression whose type evaluates to a Boolean can be used as the + * conditional expression bool-expression. Vector types are not accepted + * as the expression to if." + * + * The checks are separated so that higher quality diagnostics can be + * generated for cases where both rules are violated. + */ + if (!condition->type->is_boolean() || !condition->type->is_scalar()) { + YYLTYPE loc = this->condition->get_location(); + + _mesa_glsl_error(& loc, state, "if-statement condition must be scalar " + "boolean"); + } + + ir_if *const stmt = new ir_if(condition); + + if (then_statement != NULL) { + ast_node *node = (ast_node *) then_statement; + do { + node->hir(& stmt->then_instructions, state); + node = (ast_node *) node->next; + } while (node != then_statement); + } + + if (else_statement != NULL) { + ast_node *node = (ast_node *) else_statement; + do { + node->hir(& stmt->else_instructions, state); + node = (ast_node *) node->next; + } while (node != else_statement); + } + + instructions->push_tail(stmt); + + /* if-statements do not have r-values. + */ + return NULL; +} @@ -192,6 +192,28 @@ public: /*@}*/ +/** + * IR instruction representing high-level if-statements + */ +class ir_if : public ir_instruction { +public: + ir_if(ir_rvalue *condition) + : condition(condition) + { + /* empty */ + } + + virtual void accept(ir_visitor *v) + { + v->visit(this); + } + + ir_rvalue *condition; + exec_list then_instructions; + exec_list else_instructions; +}; + + class ir_assignment : public ir_rvalue { public: ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition); diff --git a/ir_print_visitor.cpp b/ir_print_visitor.cpp index aeff280cdd..e6b24d2d5b 100644 --- a/ir_print_visitor.cpp +++ b/ir_print_visitor.cpp @@ -265,3 +265,27 @@ ir_print_visitor::visit(ir_return *ir) printf(")"); } + + +void +ir_print_visitor::visit(ir_if *ir) +{ + printf("(if "); + ir->condition->accept(this); + + printf("(\n"); + foreach_iter(exec_list_iterator, iter, ir->then_instructions) { + ir_instruction *const inst = (ir_instruction *) iter.get(); + + inst->accept(this); + } + printf(")\n"); + + printf("(\n"); + foreach_iter(exec_list_iterator, iter, ir->else_instructions) { + ir_instruction *const inst = (ir_instruction *) iter.get(); + + inst->accept(this); + } + printf("))\n"); +} diff --git a/ir_print_visitor.h b/ir_print_visitor.h index 8fd684eb92..76d812e19c 100644 --- a/ir_print_visitor.h +++ b/ir_print_visitor.h @@ -64,6 +64,7 @@ public: virtual void visit(ir_constant *); virtual void visit(ir_call *); virtual void visit(ir_return *); + virtual void visit(ir_if *); /*@}*/ private: diff --git a/ir_visitor.h b/ir_visitor.h index 76981f7afc..521b1c3d80 100644 --- a/ir_visitor.h +++ b/ir_visitor.h @@ -55,6 +55,7 @@ public: virtual void visit(class ir_constant *) = 0; virtual void visit(class ir_call *) = 0; virtual void visit(class ir_return *) = 0; + virtual void visit(class ir_if *) = 0; /*@}*/ }; |